diff --git a/project/jni/application/gemrb/AndroidAppSettings.cfg b/project/jni/application/gemrb/AndroidAppSettings.cfg index 92b4f2ef8..2bb56fccd 100644 --- a/project/jni/application/gemrb/AndroidAppSettings.cfg +++ b/project/jni/application/gemrb/AndroidAppSettings.cfg @@ -5,12 +5,12 @@ AppName="GemRB" AppFullName=net.sourceforge.gemrb ScreenOrientation=h InhibitSuspend=n -AppDataDownloadUrl="Baldur's gate 2 demo|http://sourceforge.net/projects/libsdl-android/files/gemrb/bg2demo.zip/download^!GemRB data(override)|override4.zip^!GemRB data(scripts)|scripts4.zip" +AppDataDownloadUrl="Baldur's Gate 2 demo (800 Mb)|http://sourceforge.net/projects/libsdl-android/files/gemrb/bg2demo.zip/download^!GemRB data(override)|override10.zip^!GemRB data(scripts)|scripts10.zip" VideoDepthBpp=16 NeedDepthBuffer=n NeedStencilBuffer=n NeedGles2=n -SwVideoMode=n +SwVideoMode=y SdlVideoResize=y SdlVideoResizeKeepAspect=y CompatibilityHacks=n @@ -31,9 +31,9 @@ StartupMenuButtonTimeout=2000 HiddenMenuOptions='' FirstStartMenuOptions='' MultiABI=y -AppVersionCode=0643 -AppVersionName="0.6.4.3" -CompiledLibraries="sdl_mixer ogg vorbis openal png python" +AppVersionCode=0700 +AppVersionName="0.7.0.0" +CompiledLibraries="sdl_mixer sdl_ttf ogg vorbis openal png python" CustomBuildScript=n AppCflags='-fexceptions -finline-functions -O3 -DSTATIC_LINK=Yes -DHAVE_SNPRINTF' AppLdflags='' diff --git a/project/jni/application/gemrb/AndroidData/override10.zip b/project/jni/application/gemrb/AndroidData/override10.zip new file mode 100644 index 000000000..03db8032d Binary files /dev/null and b/project/jni/application/gemrb/AndroidData/override10.zip differ diff --git a/project/jni/application/gemrb/AndroidData/override4.zip b/project/jni/application/gemrb/AndroidData/override4.zip deleted file mode 100644 index 8c8645b43..000000000 Binary files a/project/jni/application/gemrb/AndroidData/override4.zip and /dev/null differ diff --git a/project/jni/application/gemrb/AndroidData/scripts10.zip b/project/jni/application/gemrb/AndroidData/scripts10.zip new file mode 100644 index 000000000..0ba627309 Binary files /dev/null and b/project/jni/application/gemrb/AndroidData/scripts10.zip differ diff --git a/project/jni/application/gemrb/AndroidData/scripts4.zip b/project/jni/application/gemrb/AndroidData/scripts4.zip deleted file mode 100644 index 542fce81c..000000000 Binary files a/project/jni/application/gemrb/AndroidData/scripts4.zip and /dev/null differ diff --git a/project/jni/application/gemrb/gemrb/GemRB.cpp b/project/jni/application/gemrb/gemrb/GemRB.cpp deleted file mode 100644 index ecb6d5f24..000000000 --- a/project/jni/application/gemrb/gemrb/GemRB.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -// GemRB.cpp : Defines the entry point for the application. - -#include "win32def.h" // logging - -#include "Interface.h" - -#ifdef HAVE_MALLOC_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif - -//this supposed to convince SDL to work on OS/X -//WARNING: commenting this out will cause SDL 1.2.x to crash -#ifdef __APPLE_CC__ // we need startup SDL here -#include -#endif - -#ifdef ANDROID -#include -#include "Audio.h" - -// pause audio playing if app goes in background -static void appPutToBackground() -{ - core->GetAudioDrv()->Pause(); -} -// resume audio playing if app return to foreground -static void appPutToForeground() -{ - core->GetAudioDrv()->Resume(); -} - -#endif - -int main(int argc, char* argv[]) -{ -#ifdef M_TRIM_THRESHOLD -// Prevent fragmentation of the heap by malloc (glibc). -// -// The default threshold is 128*1024, which can result in a large memory usage -// due to fragmentation since we use a lot of small objects. On the other hand -// if the threshold is too low, free() starts to permanently ask the kernel -// about shrinking the heap. - #ifdef HAVE_UNISTD_H - int pagesize = sysconf(_SC_PAGESIZE); - #else - int pagesize = 4*1024; - #endif - mallopt(M_TRIM_THRESHOLD, 5*pagesize); -#endif - - Interface::SanityCheck(VERSION_GEMRB); - core = new Interface( argc, argv ); - if (core->Init() == GEM_ERROR) { - delete( core ); - print("Press enter to continue..."); - textcolor(DEFAULT); - getc(stdin); - return -1; - } -#ifdef ANDROID - SDL_ANDROID_SetApplicationPutToBackgroundCallback(&appPutToBackground, &appPutToForeground); -#endif - core->Main(); - delete( core ); - textcolor(DEFAULT); - return 0; -} diff --git a/project/jni/application/gemrb/gemrb/core/ActorMgr.cpp b/project/jni/application/gemrb/gemrb/core/ActorMgr.cpp deleted file mode 100644 index ebcee7124..000000000 --- a/project/jni/application/gemrb/gemrb/core/ActorMgr.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "ActorMgr.h" - -ActorMgr::ActorMgr(void) -{ -} - -ActorMgr::~ActorMgr(void) -{ -} diff --git a/project/jni/application/gemrb/gemrb/core/ActorMgr.h b/project/jni/application/gemrb/gemrb/core/ActorMgr.h deleted file mode 100644 index e072defc5..000000000 --- a/project/jni/application/gemrb/gemrb/core/ActorMgr.h +++ /dev/null @@ -1,42 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#ifndef ACTORMGR_H -#define ACTORMGR_H - -#include "Plugin.h" - -class Actor; -class DataStream; - -class GEM_EXPORT ActorMgr : public Plugin { -public: - ActorMgr(void); - virtual ~ActorMgr(void); - virtual bool Open(DataStream* stream) = 0; - virtual Actor* GetActor(unsigned char is_in_party) = 0; - - //returns saved size, updates internal offsets before save - virtual int GetStoredFileSize(Actor *ac) = 0; - //saves file - virtual int PutActor(DataStream *stream, Actor *actor, bool chr=false) = 0; -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/Ambient.cpp b/project/jni/application/gemrb/gemrb/core/Ambient.cpp deleted file mode 100644 index db543f474..000000000 --- a/project/jni/application/gemrb/gemrb/core/Ambient.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2004 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "Ambient.h" - -Ambient::Ambient() -{ -} - -Ambient::~Ambient() -{ - unsigned int i=sounds.size(); - while(i--) { - free(sounds[i]); - } -} - -void Ambient::setActive() { flags |= IE_AMBI_ENABLED; } -void Ambient::setInactive() { flags &= ~IE_AMBI_ENABLED; } diff --git a/project/jni/application/gemrb/gemrb/core/Ambient.h b/project/jni/application/gemrb/gemrb/core/Ambient.h deleted file mode 100644 index ec4f9be22..000000000 --- a/project/jni/application/gemrb/gemrb/core/Ambient.h +++ /dev/null @@ -1,77 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2004 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#ifndef AMBIENT_H -#define AMBIENT_H - -#include "exports.h" -#include "globals.h" -#include "ie_types.h" - -#include -#include -#include - -#define IE_AMBI_ENABLED 1 -#define IE_AMBI_POINT 2 -#define IE_AMBI_MAIN 4 -#define IE_AMBI_AREA 8 - -class GEM_EXPORT Ambient { -public: - Ambient(); - ~Ambient(); - - /* there is a good reason to have these in the header: - * they are automatically inlined, so we have - * no roundtrips and no overhead for accessors --Divide */ - const char *getName() const { return name; } - const Point &getOrigin() const { return origin; } - ieWord getRadius() const { return radius; } - ieWord getHeight() const { return height; } - ieWord getGain() const { return gain; } - char *getSound(ieDword i) const - { - if(i sounds; - ieDword interval; // no pauses if zero - ieDword perset; - ieDword appearance; - ieDword flags; - -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/AmbientMgr.cpp b/project/jni/application/gemrb/gemrb/core/AmbientMgr.cpp deleted file mode 100644 index a998eb86a..000000000 --- a/project/jni/application/gemrb/gemrb/core/AmbientMgr.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2004 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "AmbientMgr.h" - -#include "Ambient.h" - -AmbientMgr::AmbientMgr() -{ -} - -AmbientMgr::~AmbientMgr() -{ - reset(); -} - -void AmbientMgr::activate(const std::string &name) -{ - for (std::vector::iterator it = ambients.begin(); it != ambients.end(); ++it) { - if ((*it) -> getName() == name) { - (*it) -> setActive(); - break; - } - } -} - -void AmbientMgr::deactivate(const std::string &name) -{ - for (std::vector::iterator it = ambients.begin(); it != ambients.end(); ++it) { - if ((*it) -> getName() == name) { - (*it) -> setInactive(); - break; - } - } -} - -bool AmbientMgr::isActive(const std::string &name) const -{ - for (std::vector::const_iterator it = ambients.begin(); it != ambients.end(); ++it) { - if ((*it) -> getName() == name) { - return (*it) -> getFlags() & IE_AMBI_ENABLED; - } - } - return false; -} diff --git a/project/jni/application/gemrb/gemrb/core/AmbientMgr.h b/project/jni/application/gemrb/gemrb/core/AmbientMgr.h deleted file mode 100644 index 0b6daf122..000000000 --- a/project/jni/application/gemrb/gemrb/core/AmbientMgr.h +++ /dev/null @@ -1,48 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2004 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#ifndef AMBIENTMGR_H -#define AMBIENTMGR_H - -#include "exports.h" -#include "win32def.h" - -#include -#include - -class Ambient; - -class GEM_EXPORT AmbientMgr { -public: - AmbientMgr(); - virtual ~AmbientMgr(); - virtual void reset() { ambients = std::vector (); } - virtual void setAmbients(const std::vector &a) { reset(); ambients = a; activate(); } - virtual void activate(const std::string &name); - virtual void activate() { active = true; } // hard play ;-) - virtual void deactivate(const std::string &name); - virtual void deactivate() { active = false; } // hard stop - virtual bool isActive(const std::string &name) const; -protected: - std::vector ambients; - bool active; -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/AnimStructures.h b/project/jni/application/gemrb/gemrb/core/AnimStructures.h deleted file mode 100644 index 9692cf947..000000000 --- a/project/jni/application/gemrb/gemrb/core/AnimStructures.h +++ /dev/null @@ -1,29 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#ifndef ANIMSTRUCTURES_H -#define ANIMSTRUCTURES_H - -struct CycleEntry { - ieWord FramesCount; - ieWord FirstFrame; -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/Animation.cpp b/project/jni/application/gemrb/gemrb/core/Animation.cpp deleted file mode 100644 index 4d58f1fdc..000000000 --- a/project/jni/application/gemrb/gemrb/core/Animation.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "Animation.h" - -#include "win32def.h" - -#include "Game.h" -#include "Interface.h" -#include "Map.h" -#include "Sprite2D.h" -#include "Video.h" - -Animation::Animation(int count) -{ - frames = (Sprite2D **) calloc(count, sizeof(Sprite2D *)); - indicesCount = count; - if (count) { - pos = rand() % count; - } - else { - pos = 0; - } - starttime = 0; - x = 0; - y = 0; - Flags = A_ANI_ACTIVE; - fps = 15; - endReached = false; - //behaviour flags - playReversed = false; - gameAnimation = false; -} - -Animation::~Animation(void) -{ - Video *video = core->GetVideoDriver(); - - for (unsigned int i = 0; i < indicesCount; i++) { - video->FreeSprite( frames[i] ); - } - free(frames); -} - -void Animation::SetPos(unsigned int index) -{ - if (index=indicesCount) { - error("Animation", "You tried to write past a buffer in animation, BAD!\n"); - } - core->GetVideoDriver()->FreeSprite(frames[index]); - frames[index]=frame; - - int x = -frame->XPos; - int y = -frame->YPos; - int w = frame->Width; - int h = frame->Height; - if (x < animArea.x) { - animArea.w += (animArea.x - x); - animArea.x = x; - } - if (y < animArea.y) { - animArea.h += (animArea.y - y); - animArea.y = y; - } - if (x+w > animArea.x+animArea.w) { - animArea.w = x+w-animArea.x; - } - if (y+h > animArea.y+animArea.h) { - animArea.h = y+h-animArea.y; - } -} - -unsigned int Animation::GetCurrentFrame() const -{ - if (playReversed) - return indicesCount-pos-1; - return pos; -} - -Sprite2D* Animation::LastFrame(void) -{ - if (!Flags&A_ANI_ACTIVE) { - print("Frame fetched while animation is inactive!\n"); - return NULL; - } - if (gameAnimation) { - starttime = core->GetGame()->Ticks; - } else { - starttime = GetTickCount(); - } - Sprite2D* ret; - if (playReversed) - ret = frames[indicesCount-pos-1]; - else - ret = frames[pos]; - return ret; -} - -Sprite2D* Animation::NextFrame(void) -{ - if (!Flags&A_ANI_ACTIVE) { - print("Frame fetched while animation is inactive!\n"); - return NULL; - } - if (starttime == 0) { - if (gameAnimation) { - starttime = core->GetGame()->Ticks; - } else { - starttime = GetTickCount(); - } - } - Sprite2D* ret; - if (playReversed) - ret = frames[indicesCount-pos-1]; - else - ret = frames[pos]; - - if (endReached && (Flags&A_ANI_PLAYONCE) ) - return ret; - - unsigned long time; - if (gameAnimation) { - time = core->GetGame()->Ticks; - } else { - time = GetTickCount(); - } - - //it could be that we skip more than one frame in case of slow rendering - //large, composite animations (dragons, multi-part area anims) require synchronisation - if (( time - starttime ) >= ( unsigned long ) ( 1000 / fps )) { - int inc = (time-starttime)*fps/1000; - pos += inc; - starttime += inc*1000/fps; - } - if (pos >= indicesCount ) { - if (indicesCount) { - if (Flags&A_ANI_PLAYONCE) { - pos = indicesCount-1; - endReached = true; - } else { - pos = pos%indicesCount; - endReached = false; //looping, there is no end - } - } else { - pos = 0; - endReached = true; - } - starttime = 0; - } - return ret; -} - -Sprite2D* Animation::GetSyncedNextFrame(Animation* master) -{ - if (!Flags&A_ANI_ACTIVE) { - print("Frame fetched while animation is inactive!\n"); - return NULL; - } - Sprite2D* ret; - if (playReversed) - ret = frames[indicesCount-pos-1]; - else - ret = frames[pos]; - - starttime = master->starttime; - pos = master->pos; - endReached = master->endReached; - - return ret; -} - - -void Animation::release(void) -{ - delete this; -} -/** Gets the i-th frame */ -Sprite2D* Animation::GetFrame(unsigned int i) -{ - if (i >= indicesCount) { - return NULL; - } - return frames[i]; -} - -void Animation::MirrorAnimation() -{ - Video *video = core->GetVideoDriver(); - - for (size_t i = 0; i < indicesCount; i++) { - Sprite2D * tmp = frames[i]; - frames[i] = video->MirrorSpriteHorizontal( tmp, true ); - video->FreeSprite(tmp); - } - - // flip animArea horizontally as well - animArea.x = -animArea.w - animArea.x; -} - -void Animation::MirrorAnimationVert() -{ - Video *video = core->GetVideoDriver(); - - for (size_t i = 0; i < indicesCount; i++) { - Sprite2D * tmp = frames[i]; - frames[i] = video->MirrorSpriteVertical( tmp, true ); - video->FreeSprite(tmp); - } - - // flip animArea vertically as well -// animArea.y = -animArea.h - animArea.y; -} - -void Animation::AddAnimArea(Animation* slave) -{ - int x = slave->animArea.x; - int y = slave->animArea.y; - int w = slave->animArea.w; - int h = slave->animArea.h; - if (x < animArea.x) { - animArea.w += (animArea.x - x); - animArea.x = x; - } - if (y < animArea.y) { - animArea.h += (animArea.y - y); - animArea.y = y; - } - if (x+w > animArea.x+animArea.w) { - animArea.w = x+w-animArea.x; - } - if (y+h > animArea.y+animArea.h) { - animArea.h = y+h-animArea.y; - } -} diff --git a/project/jni/application/gemrb/gemrb/core/Animation.h b/project/jni/application/gemrb/gemrb/core/Animation.h deleted file mode 100644 index 5c32424cf..000000000 --- a/project/jni/application/gemrb/gemrb/core/Animation.h +++ /dev/null @@ -1,73 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#ifndef ANIMATION_H -#define ANIMATION_H - -#include "RGBAColor.h" -#include "exports.h" -#include "globals.h" - -#include "Region.h" - -#include - -class Sprite2D; - -class GEM_EXPORT Animation { -private: - Sprite2D **frames; - unsigned int indicesCount; - unsigned long starttime; -public: - bool endReached; - unsigned int pos; - int x, y; - unsigned char fps; - bool playReversed; - bool gameAnimation; - Region animArea; - ieDword Flags; - Animation(int count); - ~Animation(void); - void AddFrame(Sprite2D* frame, unsigned int index); - Sprite2D* LastFrame(void); - Sprite2D* NextFrame(void); - Sprite2D* GetSyncedNextFrame(Animation* master); - void release(void); - /** Gets the i-th frame */ - Sprite2D* GetFrame(unsigned int i); - /** Mirrors all the frames vertically */ - void MirrorAnimationVert(); - /** Mirrors all the frames horizontally */ - void MirrorAnimation(); - /** sets frame index */ - void SetPos(unsigned int index); - /** Sets ScriptName for area animation */ - void SetScriptName(const char *name); - /** returns the frame count */ - unsigned int GetFrameCount() const { return indicesCount; } - /** returns the current frame's index */ - unsigned int GetCurrentFrame() const; - /** add other animation's animarea to self */ - void AddAnimArea(Animation* slave); -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/AnimationFactory.cpp b/project/jni/application/gemrb/gemrb/core/AnimationFactory.cpp deleted file mode 100644 index 941e963a1..000000000 --- a/project/jni/application/gemrb/gemrb/core/AnimationFactory.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "AnimationFactory.h" - -#include "win32def.h" - -#include "Interface.h" -#include "Sprite2D.h" -#include "Video.h" - -AnimationFactory::AnimationFactory(const char* ResRef) - : FactoryObject( ResRef, IE_BAM_CLASS_ID ) -{ - FLTable = NULL; - FrameData = NULL; - datarefcount = 0; -} - -AnimationFactory::~AnimationFactory(void) -{ - for (unsigned int i = 0; i < frames.size(); i++) { - core->GetVideoDriver()->FreeSprite( frames[i] ); - } - if (FLTable) - free( FLTable); - - // FIXME: track down where sprites are being leaked - if (datarefcount) { - fprintf(stderr, "AnimationFactory %s has refcount %d\n", ResRef, datarefcount); - //assert(datarefcount == 0); - } - if (FrameData) - free( FrameData); -} - -void AnimationFactory::AddFrame(Sprite2D* frame) -{ - frames.push_back( frame ); -} - -void AnimationFactory::AddCycle(CycleEntry cycle) -{ - cycles.push_back( cycle ); -} - -void AnimationFactory::LoadFLT(unsigned short* buffer, int count) -{ - if (FLTable) { - free( FLTable ); - } - //FLTable = new unsigned short[count]; - FLTable = (unsigned short *) malloc(count * sizeof( unsigned short ) ); - memcpy( FLTable, buffer, count * sizeof( unsigned short ) ); -} - -void AnimationFactory::SetFrameData(unsigned char* FrameData) -{ - this->FrameData = FrameData; -} - - -Animation* AnimationFactory::GetCycle(unsigned char cycle) -{ - if (cycle >= cycles.size()) { - return NULL; - } - int ff = cycles[cycle].FirstFrame; - int lf = ff + cycles[cycle].FramesCount; - Animation* anim = new Animation( cycles[cycle].FramesCount ); - int c = 0; - for (int i = ff; i < lf; i++) { - frames[FLTable[i]]->acquire(); - anim->AddFrame( frames[FLTable[i]], c++ ); - } - return anim; -} - -/* returns the required frame of the named cycle, cycle defaults to 0 */ -Sprite2D* AnimationFactory::GetFrame(unsigned short index, unsigned char cycle) const -{ - if (cycle >= cycles.size()) { - return NULL; - } - int ff = cycles[cycle]. FirstFrame, fc = cycles[cycle].FramesCount; - if(index >= fc) { - return NULL; - } - Sprite2D* spr = frames[FLTable[ff+index]]; - spr->acquire(); - return spr; -} - -Sprite2D* AnimationFactory::GetFrameWithoutCycle(unsigned short index) const -{ - if(index >= frames.size()) { - return NULL; - } - Sprite2D* spr = frames[index]; - spr->acquire(); - return spr; -} - -Sprite2D* AnimationFactory::GetPaperdollImage(ieDword *Colors, - Sprite2D *&Picture2, unsigned int type) const -{ - if (frames.size()<2) { - return NULL; - } - - Video* video = core->GetVideoDriver(); - Picture2 = video->DuplicateSprite(frames[1]); - if (!Picture2) { - return NULL; - } - if (Colors) { - Palette* palette = Picture2->GetPalette(); - palette->SetupPaperdollColours(Colors, type); - Picture2->SetPalette(palette); - palette->Release(); - } - - Picture2->XPos = (short)frames[1]->XPos; - Picture2->YPos = (short)frames[1]->YPos - 80; - - - Sprite2D* spr = core->GetVideoDriver()->DuplicateSprite(frames[0]); - if (Colors) { - Palette* palette = spr->GetPalette(); - palette->SetupPaperdollColours(Colors, type); - spr->SetPalette(palette); - palette->Release(); - } - - spr->XPos = (short)frames[0]->XPos; - spr->YPos = (short)frames[0]->YPos; - - //don't free pixels, createsprite stores it in spr - - return spr; -} - -void AnimationFactory::IncDataRefCount() -{ - ++datarefcount; -} - -void AnimationFactory::DecDataRefCount() -{ - assert(datarefcount > 0); - --datarefcount; -} diff --git a/project/jni/application/gemrb/gemrb/core/AnimationFactory.h b/project/jni/application/gemrb/gemrb/core/AnimationFactory.h deleted file mode 100644 index 2da099b39..000000000 --- a/project/jni/application/gemrb/gemrb/core/AnimationFactory.h +++ /dev/null @@ -1,59 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#ifndef ANIMATIONFACTORY_H -#define ANIMATIONFACTORY_H - -#include "exports.h" -#include "globals.h" - -#include "Animation.h" -#include "AnimStructures.h" -#include "FactoryObject.h" - -class GEM_EXPORT AnimationFactory : public FactoryObject { -private: - std::vector< Sprite2D*> frames; - std::vector< CycleEntry> cycles; - unsigned short* FLTable; // Frame Lookup Table - unsigned char* FrameData; - int datarefcount; -public: - AnimationFactory(const char* ResRef); - ~AnimationFactory(void); - void AddFrame(Sprite2D* frame); - void AddCycle(CycleEntry cycle); - void LoadFLT(unsigned short* buffer, int count); - void SetFrameData(unsigned char* FrameData); - Animation* GetCycle(unsigned char cycle); - /** No descriptions */ - Sprite2D* GetFrame(unsigned short index, unsigned char cycle=0) const; - Sprite2D* GetFrameWithoutCycle(unsigned short index) const; - size_t GetCycleCount() const { return cycles.size(); } - size_t GetFrameCount() const { return frames.size(); } - int GetCycleSize(int idx) const { return cycles[idx].FramesCount; } - Sprite2D* GetPaperdollImage(ieDword *Colors, Sprite2D *&Picture2, - unsigned int type) const; - - void IncDataRefCount(); - void DecDataRefCount(); -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/AnimationMgr.cpp b/project/jni/application/gemrb/gemrb/core/AnimationMgr.cpp deleted file mode 100644 index 7ddece946..000000000 --- a/project/jni/application/gemrb/gemrb/core/AnimationMgr.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "AnimationMgr.h" - -AnimationMgr::AnimationMgr(void) -{ -} - -AnimationMgr::~AnimationMgr(void) -{ -} diff --git a/project/jni/application/gemrb/gemrb/core/AnimationMgr.h b/project/jni/application/gemrb/gemrb/core/AnimationMgr.h deleted file mode 100644 index 4bf90c61d..000000000 --- a/project/jni/application/gemrb/gemrb/core/AnimationMgr.h +++ /dev/null @@ -1,48 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#ifndef ANIMATIONMGR_H -#define ANIMATIONMGR_H - -#include "globals.h" - -#include "Animation.h" -#include "AnimationFactory.h" -#include "Plugin.h" - -class Font; - -class GEM_EXPORT AnimationMgr : public Plugin { -public: - AnimationMgr(void); - virtual ~AnimationMgr(void); - virtual bool Open(DataStream* stream) = 0; - virtual int GetCycleSize(unsigned char Cycle) = 0; - virtual AnimationFactory* GetAnimationFactory(const char* ResRef, - unsigned char mode = IE_NORMAL) = 0; - /** This function will load the Animation as a Font */ - virtual Font* GetFont() = 0; - /** Debug Function: Returns the Global Animation Palette as a Sprite2D Object. - If the Global Animation Palette is NULL, returns NULL. */ - virtual Sprite2D* GetPalette() = 0; - virtual int GetCycleCount() = 0; -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/ArchiveImporter.cpp b/project/jni/application/gemrb/gemrb/core/ArchiveImporter.cpp deleted file mode 100644 index 2c8524ff0..000000000 --- a/project/jni/application/gemrb/gemrb/core/ArchiveImporter.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "ArchiveImporter.h" - -ArchiveImporter::ArchiveImporter(void) -{ -} - -ArchiveImporter::~ArchiveImporter(void) -{ -} diff --git a/project/jni/application/gemrb/gemrb/core/ArchiveImporter.h b/project/jni/application/gemrb/gemrb/core/ArchiveImporter.h deleted file mode 100644 index fe464cb25..000000000 --- a/project/jni/application/gemrb/gemrb/core/ArchiveImporter.h +++ /dev/null @@ -1,38 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#ifndef ARCHIVEIMPORTER_H -#define ARCHIVEIMPORTER_H - -#include "globals.h" - -#include "Plugin.h" - -class GEM_EXPORT ArchiveImporter : public Plugin { -public: - ArchiveImporter(void); - virtual ~ArchiveImporter(void); - virtual int CreateArchive(DataStream *stream) = 0; - //decompressing a .sav file similar to CBF - virtual int DecompressSaveGame(DataStream *compressed) = 0; - virtual int AddToSaveGame(DataStream *str, DataStream *uncompressed) = 0; -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/Audio.cpp b/project/jni/application/gemrb/gemrb/core/Audio.cpp deleted file mode 100644 index fa114c4bd..000000000 --- a/project/jni/application/gemrb/gemrb/core/Audio.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003-2004 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "Audio.h" - -const TypeID Audio::ID = { "Audio" }; - -Audio::Audio(void) -{ -} - -Audio::~Audio(void) -{ -} - -SoundHandle::~SoundHandle() -{ -} diff --git a/project/jni/application/gemrb/gemrb/core/Audio.h b/project/jni/application/gemrb/gemrb/core/Audio.h deleted file mode 100644 index 4606f38f7..000000000 --- a/project/jni/application/gemrb/gemrb/core/Audio.h +++ /dev/null @@ -1,82 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003-2004 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#ifndef AUDIO_H_INCLUDED -#define AUDIO_H_INCLUDED - -#include "globals.h" -#include "win32def.h" - -#include "Plugin.h" -#include "Holder.h" - -#define GEM_SND_RELATIVE 1 -#define GEM_SND_LOOPING 2 -#define GEM_SND_SPEECH IE_STR_SPEECH // 4 -#define GEM_SND_VOL_MUSIC 1 -#define GEM_SND_VOL_AMBIENTS 2 - -class AmbientMgr; -class SoundMgr; - -class GEM_EXPORT SoundHandle : public Held { -public: - virtual bool Playing() = 0; - virtual void SetPos(int XPos, int YPos) = 0; - virtual void Stop() = 0; - virtual void StopLooping() = 0; - virtual ~SoundHandle(); -}; - -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; - -protected: - AmbientMgr* ambim; - -}; - -#endif // AUDIO_H_INCLUDED diff --git a/project/jni/application/gemrb/gemrb/core/Bitmap.cpp b/project/jni/application/gemrb/gemrb/core/Bitmap.cpp deleted file mode 100644 index 2a55fa4cf..000000000 --- a/project/jni/application/gemrb/gemrb/core/Bitmap.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2007 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "Bitmap.h" - -Bitmap::Bitmap(unsigned int w, unsigned int h) - : height(h), width(w), data(new unsigned char[height*width]) -{ -} - -Bitmap::~Bitmap() -{ - delete[] data; -} diff --git a/project/jni/application/gemrb/gemrb/core/Bitmap.h b/project/jni/application/gemrb/gemrb/core/Bitmap.h deleted file mode 100644 index 2c37bdd87..000000000 --- a/project/jni/application/gemrb/gemrb/core/Bitmap.h +++ /dev/null @@ -1,55 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2007 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef BITMAP_H -#define BITMAP_H - -#include "exports.h" - -class GEM_EXPORT Bitmap { -public: - Bitmap(unsigned int height, unsigned int width); - ~Bitmap(); - unsigned char GetAt(unsigned int x, unsigned int y) const - { - if (x >= width || y >= height) - return 0; - return data[width*y+x]; - - } - void SetAt(unsigned int x, unsigned int y, unsigned char idx) - { - if (x >= width || y >= height) - return; - data[width*y+x] = idx; - - } - unsigned int GetHeight() const - { - return height; - } - unsigned int GetWidth() const - { - return width; - } -private: - unsigned int height, width; - unsigned char *data; -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/CMakeLists.txt b/project/jni/application/gemrb/gemrb/core/CMakeLists.txt deleted file mode 100644 index 2d6c8dec1..000000000 --- a/project/jni/application/gemrb/gemrb/core/CMakeLists.txt +++ /dev/null @@ -1,139 +0,0 @@ -ADD_DEFINITIONS(-DGEM_BUILD_DLL) - -FILE(GLOB gemrb_core_LIB_SRCS - ActorMgr.cpp - Ambient.cpp - AmbientMgr.cpp - Animation.cpp - AnimationFactory.cpp - AnimationMgr.cpp - ArchiveImporter.cpp - Audio.cpp - Bitmap.cpp - Cache.cpp - Calendar.cpp - Callback.cpp - CharAnimations.cpp - Compressor.cpp - ControlAnimation.cpp - Core.cpp - DataFileMgr.cpp - Dialog.cpp - DialogHandler.cpp - DialogMgr.cpp - DisplayMessage.cpp - EffectMgr.cpp - EffectQueue.cpp - Factory.cpp - FactoryObject.cpp - FileCache.cpp - Font.cpp - Game.cpp - GameData.cpp - GlobalTimer.cpp - Image.cpp - ImageFactory.cpp - ImageMgr.cpp - ImageWriter.cpp - IndexedArchive.cpp - IniSpawn.cpp - Interface.cpp - Inventory.cpp - Item.cpp - ItemMgr.cpp - KeyMap.cpp - LRUCache.cpp - Map.cpp - MapMgr.cpp - MoviePlayer.cpp - MusicMgr.cpp - Palette.cpp - PalettedImageMgr.cpp - Particles.cpp - Plugin.cpp - PluginLoader.cpp - PluginMgr.cpp - Polygon.cpp - Projectile.cpp - ProjectileMgr.cpp - ProjectileServer.cpp - Region.cpp - Resource.cpp - ResourceDesc.cpp - ResourceManager.cpp - ResourceSource.cpp - SaveGameIterator.cpp - SaveGameMgr.cpp - ScriptEngine.cpp - ScriptedAnimation.cpp - SoundMgr.cpp - Spell.cpp - SpellMgr.cpp - Spellbook.cpp - Sprite2D.cpp - SpriteCover.cpp - Store.cpp - StoreMgr.cpp - StringMgr.cpp - SymbolMgr.cpp - TableMgr.cpp - Tile.cpp - TileMap.cpp - TileMapMgr.cpp - TileOverlay.cpp - TileSetMgr.cpp - Variables.cpp - Video.cpp - WindowMgr.cpp - WorldMap.cpp - WorldMapMgr.cpp - GameScript/Actions.cpp - GameScript/GSUtils.cpp - GameScript/GameScript.cpp - GameScript/Matching.cpp - GameScript/Objects.cpp - GameScript/Triggers.cpp - GUI/Button.cpp - GUI/Console.cpp - GUI/Control.cpp - GUI/EventMgr.cpp - GUI/GameControl.cpp - GUI/Label.cpp - GUI/MapControl.cpp - GUI/Progressbar.cpp - GUI/ScrollBar.cpp - GUI/Slider.cpp - GUI/TextArea.cpp - GUI/TextEdit.cpp - GUI/Window.cpp - GUI/WorldMapControl.cpp - Scriptable/Actor.cpp - Scriptable/Container.cpp - Scriptable/Door.cpp - Scriptable/InfoPoint.cpp - Scriptable/Scriptable.cpp - Scriptable/PCStatStruct.cpp - System/DataStream.cpp - System/FileStream.cpp - System/MemoryStream.cpp - System/Logging.cpp - System/SlicedStream.cpp - System/String.cpp - System/VFS.cpp - ) - -if (STATIC_LINK) - ADD_LIBRARY(gemrb_core STATIC ${gemrb_core_LIB_SRCS}) -else (STATIC_LINK) - ADD_LIBRARY(gemrb_core SHARED ${gemrb_core_LIB_SRCS}) - IF(WIN32) - INSTALL(TARGETS gemrb_core RUNTIME DESTINATION ${LIB_DIR}) - ELSE(WIN32) - INSTALL(TARGETS gemrb_core LIBRARY DESTINATION ${LIB_DIR}) - ENDIF(WIN32) -endif (STATIC_LINK) - -SET_TARGET_PROPERTIES(gemrb_core PROPERTIES - COMPILE_DEFINITIONS - "PLUGINDIR=\"${PLUGIN_DIR}\";DATADIR=\"${DATA_DIR}\";SYSCONFDIR=\"${SYSCONF_DIR}\"" - ) diff --git a/project/jni/application/gemrb/gemrb/core/Cache.cpp b/project/jni/application/gemrb/gemrb/core/Cache.cpp deleted file mode 100644 index 4c11ebabc..000000000 --- a/project/jni/application/gemrb/gemrb/core/Cache.cpp +++ /dev/null @@ -1,312 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "Cache.h" - -#include -#include - -// private inlines -inline unsigned int Cache::MyHashKey(const char* key) const -{ - int nHash = tolower(key[0]); - for (int i=1;(i 0 ); - assert( nHashTableSize > 16 ); - - m_pHashTable = NULL; - m_nHashTableSize = nHashTableSize; // default size - m_nCount = 0; - m_pFreeList = NULL; - m_pBlocks = NULL; - m_nBlockSize = nBlockSize; -} - -void Cache::InitHashTable(unsigned int nHashSize, bool bAllocNow) - //Used to force allocation of a hash table or to override the default - //hash table size of (which is fairly small) -{ - assert( m_nCount == 0 ); - assert( nHashSize > 16 ); - - if (m_pHashTable != NULL) { - // free hash table - free( m_pHashTable); - m_pHashTable = NULL; - } - - if (bAllocNow) { - m_pHashTable = (Cache::MyAssoc **) malloc( sizeof( Cache::MyAssoc * ) * nHashSize ); - memset( m_pHashTable, 0, sizeof( Cache::MyAssoc * ) * nHashSize ); - } - m_nHashTableSize = nHashSize; -} - -void Cache::RemoveAll(ReleaseFun fun) -{ - if (m_pHashTable) { - for (unsigned int nHash = 0; nHash < m_nHashTableSize; nHash++) - { - MyAssoc* pAssoc; - for (pAssoc = m_pHashTable[nHash]; pAssoc != NULL; - pAssoc = pAssoc->pNext) - { - if (fun) - fun(pAssoc->data); - pAssoc->MyAssoc::~MyAssoc(); - } - } - // free hash table - free( m_pHashTable ); - m_pHashTable = NULL; - } - - m_nCount = 0; - m_pFreeList = NULL; - - // free memory blocks - MemBlock* p = m_pBlocks; - while (p != NULL) { - MemBlock* pNext = p->pNext; - free( p ); - p = pNext; - } - - m_pBlocks = NULL; -} - -Cache::~Cache() -{ - RemoveAll(NULL); -} - -Cache::MyAssoc* Cache::NewAssoc() -{ - if (m_pFreeList == NULL) { - // add another block - Cache::MemBlock* newBlock = ( Cache::MemBlock* ) malloc(m_nBlockSize * sizeof( Cache::MyAssoc ) + sizeof( Cache::MemBlock )); - assert( newBlock != NULL ); // we must have something - - newBlock->pNext = m_pBlocks; - m_pBlocks = newBlock; - - // chain them into free list - Cache::MyAssoc* pAssoc = ( Cache::MyAssoc* ) - ( newBlock + 1 ); - for (int i = 0; i < m_nBlockSize; i++) { - pAssoc->pNext = m_pFreeList; - m_pFreeList = pAssoc++; - } - } - - Cache::MyAssoc* pAssoc = m_pFreeList; - m_pFreeList = m_pFreeList->pNext; - m_nCount++; - assert( m_nCount > 0 ); // make sure we don't overflow -#ifdef _DEBUG - pAssoc->key[0] = 0; - pAssoc->data = 0; -#endif - pAssoc->nRefCount=1; - return pAssoc; -} - -void Cache::FreeAssoc(Cache::MyAssoc* pAssoc) -{ - if(pAssoc->pNext) { - pAssoc->pNext->pPrev=pAssoc->pPrev; - } - *pAssoc->pPrev = pAssoc->pNext; - pAssoc->pNext = m_pFreeList; - m_pFreeList = pAssoc; - m_nCount--; - assert( m_nCount >= 0 ); // make sure we don't underflow - - // if no more elements, cleanup completely - if (m_nCount == 0) { - RemoveAll(NULL); - } -} - -Cache::MyAssoc *Cache::GetNextAssoc(Cache::MyAssoc *Position) const -{ - if (m_pHashTable == NULL || m_nCount==0) { - return NULL; - } - - Cache::MyAssoc* pAssocRet = (Cache::MyAssoc*)Position; - - if (pAssocRet == NULL) - { - // find the first association - for (unsigned int nBucket = 0; nBucket < m_nHashTableSize; nBucket++) - if ((pAssocRet = m_pHashTable[nBucket]) != NULL) - break; - return pAssocRet; - } - Cache::MyAssoc* pAssocNext = pAssocRet->pNext; - if (pAssocNext == NULL) - { - // go to next bucket - for (unsigned int nBucket = MyHashKey(pAssocRet->key) + 1; - nBucket < m_nHashTableSize; nBucket++) - if ((pAssocNext = m_pHashTable[nBucket]) != NULL) - break; - } - - return pAssocNext; -} - -Cache::MyAssoc* Cache::GetAssocAt(const ieResRef key) const - // find association (or return NULL) -{ - if (m_pHashTable == NULL) { - return NULL; - } - - unsigned int nHash = MyHashKey( key ); - - // see if it exists - Cache::MyAssoc* pAssoc; - for (pAssoc = m_pHashTable[nHash]; - pAssoc != NULL; - pAssoc = pAssoc->pNext) { - if (!strnicmp( pAssoc->key, key, KEYSIZE )) { - return pAssoc; - } - } - return NULL; -} - -void *Cache::GetResource(const ieResRef key) const -{ - Cache::MyAssoc* pAssoc = GetAssocAt( key ); - if (pAssoc == NULL) { - return NULL; - } // not in map - - pAssoc->nRefCount++; - return pAssoc->data; -} - -//returns true if it was successful -bool Cache::SetAt(const ieResRef key, void *rValue) -{ - int i; - - if (m_pHashTable == NULL) { - InitHashTable( m_nHashTableSize ); - } - - Cache::MyAssoc* pAssoc=GetAssocAt( key ); - - if (pAssoc) { - //already exists, but we return true if it is the same - return (pAssoc->data==rValue); - } - - // it doesn't exist, add a new Association - pAssoc = NewAssoc(); - for (i=0;ikey[i]=tolower(key[i]); - } - for (;ikey[i]=0; - } - pAssoc->data=rValue; - // put into hash table - unsigned int nHash = MyHashKey(pAssoc->key); - pAssoc->pNext = m_pHashTable[nHash]; - pAssoc->pPrev = &m_pHashTable[nHash]; - if (pAssoc->pNext) { - pAssoc->pNext->pPrev = &pAssoc->pNext; - } - m_pHashTable[nHash] = pAssoc; - return true; -} - -int Cache::RefCount(const ieResRef key) const -{ - Cache::MyAssoc* pAssoc=GetAssocAt( key ); - if (pAssoc) { - return pAssoc->nRefCount; - } - return -1; -} - -int Cache::DecRef(void *data, const ieResRef key, bool remove) -{ - Cache::MyAssoc* pAssoc; - - if (key) { - pAssoc=GetAssocAt( key ); - if (pAssoc && (pAssoc->data==data) ) { - if (!pAssoc->nRefCount) { - return -1; - } - --pAssoc->nRefCount; - if (remove && !pAssoc->nRefCount) { - FreeAssoc(pAssoc); - return 0; - } - return pAssoc->nRefCount; - } - return -1; - } - - pAssoc=(Cache::MyAssoc *) GetNextAssoc(NULL); - - while (pAssoc) { - if (pAssoc->data == data) { - if (!pAssoc->nRefCount) { - return -1; - } - --pAssoc->nRefCount; - if (remove && !pAssoc->nRefCount) { - FreeAssoc(pAssoc); - return 0; - } - return pAssoc->nRefCount; - } - pAssoc=GetNextAssoc(pAssoc); - } - return -1; -} - -void Cache::Cleanup() -{ - Cache::MyAssoc* pAssoc=(Cache::MyAssoc *) GetNextAssoc(NULL); - - while (pAssoc) - { - Cache::MyAssoc* nextAssoc = GetNextAssoc(pAssoc); - if (pAssoc->nRefCount == 0) { - FreeAssoc(pAssoc); - } - pAssoc=nextAssoc; - } -} diff --git a/project/jni/application/gemrb/gemrb/core/Cache.h b/project/jni/application/gemrb/gemrb/core/Cache.h deleted file mode 100644 index b83e57641..000000000 --- a/project/jni/application/gemrb/gemrb/core/Cache.h +++ /dev/null @@ -1,93 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 |Avenger| - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#ifndef CACHE_H -#define CACHE_H - -#include "globals.h" -#include "win32def.h" - -#define KEYSIZE 8 - -#ifndef ReleaseFun -typedef void (*ReleaseFun)(void *); -#endif - -class Cache -{ -protected: - // Association - struct MyAssoc { - MyAssoc* pNext; - MyAssoc** pPrev; - char key[KEYSIZE]; //not ieResRef! - ieDword nRefCount; - void* data; - }; - struct MemBlock { - MemBlock* pNext; - }; - -public: - // Construction - Cache(int nBlockSize = 10, int nHashTableSize = 129); - - // Attributes - // number of elements - inline int GetCount() const - { - return m_nCount; - } - inline bool IsEmpty() const - { - return m_nCount==0; - } - // Lookup - void *GetResource(const ieResRef key) const; - // Operations - bool SetAt(const ieResRef key, void *rValue); - // decreases refcount or drops data - //if name is supplied it is faster, it will use rValue to validate the request - int DecRef(void *rValue, const ieResRef name, bool free); - int RefCount(const ieResRef key) const; - void RemoveAll(ReleaseFun fun);//removes all refcounts - void Cleanup(); //removes only zero refcounts - void InitHashTable(unsigned int hashSize, bool bAllocNow = true); - - // Implementation -protected: - MyAssoc** m_pHashTable; - unsigned int m_nHashTableSize; - int m_nCount; - MyAssoc* m_pFreeList; - MemBlock* m_pBlocks; - int m_nBlockSize; - - Cache::MyAssoc* NewAssoc(); - void FreeAssoc(Cache::MyAssoc*); - Cache::MyAssoc* GetAssocAt(const ieResRef) const; - Cache::MyAssoc *GetNextAssoc(Cache::MyAssoc * rNextPosition) const; - unsigned int MyHashKey(const ieResRef) const; - -public: - ~Cache(); -}; - -#endif //CACHE_H diff --git a/project/jni/application/gemrb/gemrb/core/Calendar.cpp b/project/jni/application/gemrb/gemrb/core/Calendar.cpp deleted file mode 100644 index 673bdb040..000000000 --- a/project/jni/application/gemrb/gemrb/core/Calendar.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2009 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "Calendar.h" - -#include "win32def.h" - -#include "Interface.h" -#include "TableMgr.h" -#include "Variables.h" - -Calendar::Calendar(void) -{ - int i; - AutoTable tab("months"); - if (!tab) { - monthnamecount=-1; - monthnames = NULL; - days = NULL; - return; - } - monthnamecount = tab->GetRowCount(); - monthnames = (int *) malloc(sizeof(int) * monthnamecount); - days = (int *) malloc(sizeof(int) * monthnamecount); - daysinyear=0; - for(i=0;iQueryField(i,0)); - daysinyear+=days[i]; - monthnames[i]=atoi(tab->QueryField(i,1)); - } -} - -Calendar::~Calendar(void) -{ - if (monthnames) free(monthnames); - if (days) free(days); -} - -void Calendar::GetMonthName(int dayandmonth) const -{ - int month=1; - - for(int i=0;iGetTokenDictionary()->SetAtCopy("DAY", dayandmonth+1); - - tmp = core->GetString( monthnames[i] ); - core->GetTokenDictionary()->SetAt("MONTHNAME",tmp); - //must not free tmp, SetAt doesn't copy the pointer! - - core->GetTokenDictionary()->SetAtCopy("MONTH", month); - return; - } - dayandmonth-=days[i]; - //ignoring single days (they are not months) - if (days[i]!=1) month++; - } -} - -int Calendar::GetCalendarDay(int date) const -{ - int dayandmonth; - int month=1; - - if (!daysinyear) return 0; - dayandmonth = date%daysinyear; - for(int i=0;i { -public: - virtual ~Callback(); - virtual bool call (); - virtual bool call (int); -}; - -typedef Holder EventHandler; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/CharAnimations.cpp b/project/jni/application/gemrb/gemrb/core/CharAnimations.cpp deleted file mode 100644 index aa4519042..000000000 --- a/project/jni/application/gemrb/gemrb/core/CharAnimations.cpp +++ /dev/null @@ -1,2391 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "CharAnimations.h" - -#include "win32def.h" - -#include "AnimationFactory.h" -#include "DataFileMgr.h" -#include "Game.h" -#include "GameData.h" -#include "ImageMgr.h" -#include "Interface.h" -#include "Map.h" -#include "Palette.h" -#include "Video.h" - -static int AvatarsCount = 0; -static AvatarStruct *AvatarTable = NULL; -static const ieByte SixteenToNine[16]={0,1,2,3,4,5,6,7,8,7,6,5,4,3,2,1}; -static const ieByte SixteenToFive[16]={0,0,1,1,2,2,3,3,4,4,3,3,2,2,1,1}; - -static const int zOrder_Mirror16[16][4] = { - { 0, 3, 2, 1 }, - { 0, 3, 2, 1 }, - { 0, 3, 1, 2 }, - { 0, 3, 1, 2 }, - { 1, 0, 3, 2 }, - { 1, 0, 3, 2 }, - { 1, 0, 3, 2 }, - { 1, 0, 3, 2 }, - { 1, 0, 3, 2 }, - { 1, 0, 3, 2 }, - { 1, 0, 3, 2 }, - { 1, 0, 3, 2 }, - { 1, 0, 3, 2 }, - { 0, 3, 1, 2 }, - { 0, 3, 1, 2 }, - { 0, 3, 2, 1 } -}; - -static const int zOrder_8[8][4] = { - { 0, 3, 2, 1 }, - { 0, 3, 1, 2 }, - { 1, 0, 3, 2 }, - { 1, 0, 3, 2 }, - { 1, 0, 3, 2 }, - { 2, 0, 3, 1 }, - { 2, 0, 3, 1 }, - { 2, 0, 3, 1 } -}; - -struct EquipResRefData { - char Suffix[9]; - unsigned char Cycle; -}; - - -void CharAnimations::ReleaseMemory() -{ - if (AvatarTable) { - free(AvatarTable); - AvatarTable=NULL; - } -} - -int CharAnimations::GetAvatarsCount() -{ - return AvatarsCount; -} - -AvatarStruct *CharAnimations::GetAvatarStruct(int RowNum) -{ - return AvatarTable+RowNum; -} - -unsigned int CharAnimations::GetAnimationID() const -{ - if (AvatarsRowNum==~0u) return 0; - return AvatarTable[AvatarsRowNum].AnimID; -} - -int CharAnimations::GetCircleSize() const -{ - if (AvatarsRowNum==~0u) return -1; - return AvatarTable[AvatarsRowNum].CircleSize; -} -int CharAnimations::NoPalette() const -{ - if (AvatarsRowNum==~0u) return -1; - return AvatarTable[AvatarsRowNum].PaletteType; -} - -int CharAnimations::GetAnimType() const -{ - if (AvatarsRowNum==~0u) return -1; - return AvatarTable[AvatarsRowNum].AnimationType; -} - -int CharAnimations::GetSize() const -{ - if (AvatarsRowNum==~0u) return 0; - return AvatarTable[AvatarsRowNum].Size; -} - -int CharAnimations::GetBloodColor() const -{ - if(AvatarsRowNum==~0u) return 0; - return AvatarTable[AvatarsRowNum].BloodColor; -} - -static ieResRef EmptySound={0}; - -const ieResRef &CharAnimations::GetWalkSound() const -{ - if(AvatarsRowNum==~0u) return EmptySound; - return AvatarTable[AvatarsRowNum].WalkSound; -} - -int CharAnimations::GetWalkSoundCount() const -{ - if(AvatarsRowNum==~0u) return 0; - return AvatarTable[AvatarsRowNum].WalkSoundCount; -} - -int CharAnimations::GetActorPartCount() const -{ - if (AvatarsRowNum==~0u) return -1; - switch (AvatarTable[AvatarsRowNum].AnimationType) { - case IE_ANI_NINE_FRAMES: //dragon animations - return 9; - case IE_ANI_FOUR_FRAMES: //wyvern animations - return 4; - case IE_ANI_PST_GHOST: //special pst anims - if (AvatarTable[AvatarsRowNum].Prefixes[1][0]=='*') { - return 1; - } - if (AvatarTable[AvatarsRowNum].Prefixes[2][0]=='*') { - return 2; - } - if (AvatarTable[AvatarsRowNum].Prefixes[3][0]=='*') { - return 3; - } - return 4; - default: - return 1; - } -} - -int CharAnimations::GetTotalPartCount() const -{ - if (AvatarsRowNum==~0u) return -1; - switch (AvatarTable[AvatarsRowNum].AnimationType) { - case IE_ANI_FOUR_FILES: - case IE_ANI_FOUR_FILES_2: - return GetActorPartCount() + 1; // only weapon - case IE_ANI_CODE_MIRROR: - return GetActorPartCount() + 3; // equipment - case IE_ANI_TWENTYTWO: - return GetActorPartCount() + 3; // equipment - default: - return GetActorPartCount(); - } -} - -void CharAnimations::SetArmourLevel(int ArmourLevel) -{ - if (AvatarsRowNum==~0u) return; - //ignore ArmourLevel for the static pst anims (all sprites are displayed) - if (AvatarTable[AvatarsRowNum].AnimationType == IE_ANI_PST_GHOST) { - ArmourLevel = 0; - } - strncpy( ResRef, AvatarTable[AvatarsRowNum].Prefixes[ArmourLevel], 8 ); - ResRef[8]=0; - DropAnims(); -} - -//RangedType could be weird, reducing its value to 0,1,2 -void CharAnimations::SetRangedType(int rt) -{ - if ((unsigned int) rt<2) { - RangedType=(ieByte) rt; - } else { - RangedType=2; - } -} - -void CharAnimations::SetWeaponType(int wt) -{ - if (wt != WeaponType) { - WeaponType = wt; - DropAnims(); - } -} - -void CharAnimations::SetHelmetRef(const char* ref) -{ - HelmetRef[0] = ref[0]; - HelmetRef[1] = ref[1]; - - // TODO: Only drop helmet anims? - // Note: this doesn't happen "often", so this isn't a performance - // bottleneck. (wjp) - DropAnims(); - gamedata->FreePalette(palette[PAL_HELMET], 0); - gamedata->FreePalette(modifiedPalette[PAL_HELMET], 0); -} - -void CharAnimations::SetWeaponRef(const char* ref) -{ - WeaponRef[0] = ref[0]; - WeaponRef[1] = ref[1]; - - // TODO: Only drop weapon anims? - DropAnims(); - gamedata->FreePalette(palette[PAL_WEAPON], 0); - gamedata->FreePalette(modifiedPalette[PAL_WEAPON], 0); -} - -void CharAnimations::SetOffhandRef(const char* ref) -{ - OffhandRef[0] = ref[0]; - OffhandRef[1] = ref[1]; - - // TODO: Only drop shield/offhand anims? - DropAnims(); - gamedata->FreePalette(palette[PAL_OFFHAND], 0); - gamedata->FreePalette(modifiedPalette[PAL_OFFHAND], 0); -} - -void CharAnimations::LockPalette(const ieDword *gradients) -{ - if (lockPalette) return; - //cannot lock colors for PST animations - if (GetAnimType() >= IE_ANI_PST_ANIMATION_1) - { - return; - } - //force initialisation of animation - SetColors( gradients ); - GetAnimation(0,0); - if (palette[PAL_MAIN]) { - lockPalette=true; - } -} - -// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 -static const char *StancePrefix[]={"3","2","5","5","4","4","2","2","5","4","1","3","3","3","4","1","4","4","4"}; -static const char *CyclePrefix[]= {"0","0","1","1","1","1","0","0","1","1","0","1","1","1","1","1","1","1","1"}; -static const unsigned int CycleOffset[] = {0, 0, 0, 0, 0, 9, 0, 0, 0, 18, 0, 0, 9, 18, 0, 0, 0, 0, 0}; - -void CharAnimations::SetColors(const ieDword *arg) -{ - Colors = arg; - SetupColors(PAL_MAIN); - SetupColors(PAL_WEAPON); - SetupColors(PAL_OFFHAND); - 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]; - - if (!pal) { - return; - } - - if (!Colors) { - return; - } - - if (GetAnimType() >= IE_ANI_PST_ANIMATION_1) { - // Only do main palette - if (type != PAL_MAIN) { - return; - } - // TODO: handle equipment colour glows - - // Colors[6] is the COLORCOUNT stat in PST. - // It tells how many customisable color slots we have. - // The color slots start from the end of the palette and go - // backwards. There are 6 available slots with a size of 32 each. - // Actually, the slots seem to be written in the cre file - // but we ignore them, i'm not sure this is correct - int colorcount = Colors[6]; - int size = 32; - //the color count shouldn't be more than 6! - if (colorcount>6) colorcount=6; - int dest = 256-colorcount*size; - bool needmod = false; - 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); - PaletteResRef[0]=0; - return; - } - */ - for (int i = 0; i < colorcount; i++) { - core->GetPalette( Colors[i]&255, size, - &palette[PAL_MAIN]->col[dest] ); - dest +=size; - } - - if (needmod) { - if (!modifiedPalette[PAL_MAIN]) - modifiedPalette[PAL_MAIN] = new Palette(); - modifiedPalette[PAL_MAIN]->SetupGlobalRGBModification(palette[PAL_MAIN], GlobalColorMod); - } else { - gamedata->FreePalette(modifiedPalette[PAL_MAIN], 0); - } - return; - } - - int PType = NoPalette(); - if ( PType && (type == PAL_MAIN) ) { - bool needmod = false; - if (GlobalColorMod.type != RGBModifier::NONE) { - needmod = true; - } - if (!needmod && PaletteResRef[0]) { - gamedata->FreePalette(palette[PAL_MAIN], PaletteResRef); - } - PaletteResRef[0]=0; - //handling special palettes like MBER_BL (black bear) - if (PType!=1) { - if (GetAnimType()==IE_ANI_NINE_FRAMES) { - snprintf(PaletteResRef,9,"%.4s_%-.2s%s",ResRef, (char *) &PType, StancePrefix[StanceID]); - } else { - snprintf(PaletteResRef,9,"%.4s_%-.2s",ResRef, (char *) &PType); - } - strlwr(PaletteResRef); - Palette *tmppal = gamedata->GetPalette(PaletteResRef); - if (tmppal) { - palette[PAL_MAIN] = tmppal; - } else { - PaletteResRef[0]=0; - } - } - if (needmod) { - if (!modifiedPalette[PAL_MAIN]) - modifiedPalette[PAL_MAIN] = new Palette(); - modifiedPalette[PAL_MAIN]->SetupGlobalRGBModification(palette[PAL_MAIN], GlobalColorMod); - } else { - gamedata->FreePalette(modifiedPalette[PAL_MAIN], 0); - } - return; - } - - pal->SetupPaperdollColours(Colors, (int)type); - if (lockPalette) { - return; - } - - int i; - bool needmod = false; - if (GlobalColorMod.type != RGBModifier::NONE) { - needmod = true; - } else { - for (i = 0; i < 7; ++i) { - if (ColorMods[i+8*((int)type)].type != RGBModifier::NONE) - needmod = true; - } - } - - - if (needmod) { - if (!modifiedPalette[(int)type]) - modifiedPalette[(int)type] = new Palette(); - - if (GlobalColorMod.type != RGBModifier::NONE) { - modifiedPalette[(int)type]->SetupGlobalRGBModification(palette[(int)type], GlobalColorMod); - } else { - modifiedPalette[(int)type]->SetupRGBModification(palette[(int)type],ColorMods, (int)type); - } - } else { - gamedata->FreePalette(modifiedPalette[(int)type], 0); - } - -} - -Palette* CharAnimations::GetPartPalette(int part) -{ - int actorPartCount = GetActorPartCount(); - PaletteType type = PAL_MAIN; - - if (part == actorPartCount) type = PAL_WEAPON; - if (part == actorPartCount+1) type = PAL_OFFHAND; - if (part == actorPartCount+2) type = PAL_HELMET; - - if (modifiedPalette[(int)type]) - return modifiedPalette[(int)type]; - - return palette[(int)type]; -} - -static int compare_avatars(const void *a, const void *b) -{ - unsigned int aa = ((AvatarStruct *)a)->AnimID; - unsigned int bb = ((AvatarStruct *)b)->AnimID; - return (int) (aa-bb); -} - -void CharAnimations::InitAvatarsTable() -{ - AutoTable Avatars("avatars"); - if (!Avatars) { - error("CharAnimations", "A critical animation file is missing!\n"); - } - AvatarTable = (AvatarStruct *) calloc ( AvatarsCount = Avatars->GetRowCount(), sizeof(AvatarStruct) ); - int i=AvatarsCount; - DataFileMgr *resdata = core->GetResDataINI(); - while(i--) { - AvatarTable[i].AnimID=(unsigned int) strtol(Avatars->GetRowName(i),NULL,0 ); - strnlwrcpy(AvatarTable[i].Prefixes[0],Avatars->QueryField(i,AV_PREFIX1),8); - strnlwrcpy(AvatarTable[i].Prefixes[1],Avatars->QueryField(i,AV_PREFIX2),8); - strnlwrcpy(AvatarTable[i].Prefixes[2],Avatars->QueryField(i,AV_PREFIX3),8); - strnlwrcpy(AvatarTable[i].Prefixes[3],Avatars->QueryField(i,AV_PREFIX4),8); - AvatarTable[i].AnimationType=(ieByte) atoi(Avatars->QueryField(i,AV_ANIMTYPE) ); - AvatarTable[i].CircleSize=(ieByte) atoi(Avatars->QueryField(i,AV_CIRCLESIZE) ); - const char *tmp = Avatars->QueryField(i,AV_USE_PALETTE); - //QueryField will always return a zero terminated string - //so tmp[0] must exist - if ( isalpha (tmp[0]) ) { - //this is a hack, we store 2 letters on an integer - //it was allocated with calloc, so don't bother erasing it - strncpy( (char *) &AvatarTable[i].PaletteType, tmp, 3); - } - else { - AvatarTable[i].PaletteType=atoi(Avatars->QueryField(i,AV_USE_PALETTE) ); - } - char size = Avatars->QueryField(i,AV_SIZE)[0]; - if (size == '*') { - size = 0; - } - AvatarTable[i].Size = size; - - AvatarTable[i].WalkScale = 0; - AvatarTable[i].RunScale = 0; - AvatarTable[i].Bestiary = -1; - - if (resdata) { - char section[12]; - snprintf(section,10,"%d", i); - - if (!resdata->GetKeysCount(section)) continue; - - float walkscale = resdata->GetKeyAsFloat(section, "walkscale", 0.0f); - if (walkscale != 0.0f) AvatarTable[i].WalkScale = (int)(1000.0f / walkscale); - float runscale = resdata->GetKeyAsFloat(section, "runscale", 0.0f); - if (runscale != 0.0f) AvatarTable[i].RunScale = (int)(1000.0f / runscale); - AvatarTable[i].Bestiary = resdata->GetKeyAsInt(section, "bestiary", -1); - } - } - qsort(AvatarTable, AvatarsCount, sizeof(AvatarStruct), compare_avatars); - - - AutoTable blood("bloodclr"); - if (blood) { - int rows = blood->GetRowCount(); - for(int i=0;iQueryField(i,0), (long &)value); - valid_number(blood->QueryField(i,1), (long &)rmin); - valid_number(blood->QueryField(i,2), (long &)rmax); - if (value>255 || rmin>0xffff || rmax>0xffff) { - printMessage("CharAnimations", "bloodclr entry: %02x %04x-%04x ", LIGHT_RED, - (unsigned int) value, (unsigned int) rmin, (unsigned int) rmax); - printStatus("Invalid value!", LIGHT_RED); - continue; - } - for(int j=0;jAvatarTable[j].AnimID) continue; - AvatarTable[j].BloodColor = value; - } - } - } - - AutoTable walk("walksnd"); - if (walk) { - int rows = walk->GetRowCount(); - for(int i=0;iQueryField(i,0), 8); - valid_number(walk->QueryField(i,1), (long &)rmin); - valid_number(walk->QueryField(i,2), (long &)rmax); - valid_number(walk->QueryField(i,3), (long &)range); - if (value[0]=='*') { - value[0]=0; - range = 0; - } - for(int j=0;jAvatarTable[j].AnimID) continue; - memcpy(AvatarTable[j].WalkSound, value, sizeof(ieResRef) ); - AvatarTable[j].WalkSoundCount = range; - } - } - } -} - -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; - } - nextStanceID = 0; - StanceID = 0; - autoSwitchOnEnd = false; - lockPalette = false; - if (!AvatarsCount) { - InitAvatarsTable(); - } - - for (i = 0; i < MAX_ANIMS; i++) { - for (j = 0; j < MAX_ORIENT; j++) { - Anims[i][j] = NULL; - } - } - ArmorType = 0; - RangedType = 0; - WeaponType = 0; - PaletteResRef[0] = 0; - WeaponRef[0] = 0; - HelmetRef[0] = 0; - OffhandRef[0] = 0; - for (i = 0; i < 32; ++i) { - ColorMods[i].type = RGBModifier::NONE; - ColorMods[i].speed = 0; - // make initial phase depend on location to make the pulse appear - // less even - ColorMods[i].phase = 5*i; - ColorMods[i].locked = false; - } - GlobalColorMod.type = RGBModifier::NONE; - GlobalColorMod.speed = 0; - GlobalColorMod.phase = 0; - GlobalColorMod.locked = false; - lastModUpdate = 0; - - AvatarsRowNum=AvatarsCount; - if (core->HasFeature(GF_ONE_BYTE_ANIMID) ) { - ieDword tmp = AnimID&0xf000; - if (tmp==0x6000 || tmp==0xe000) { - AnimID&=0xff; - } - } - - while (AvatarsRowNum--) { - if (AvatarTable[AvatarsRowNum].AnimID<=AnimID) { - SetArmourLevel( ArmourLevel ); - return; - } - } - ResRef[0]=0; - printMessage("CharAnimations", "Invalid or nonexistent avatar entry:%04X\n", LIGHT_RED, AnimID); -} - -//we have to drop them when armourlevel changes -void CharAnimations::DropAnims() -{ - Animation** tmppoi; - int partCount = GetTotalPartCount(); - for (int StanceID = 0; StanceID < MAX_ANIMS; StanceID++) { - for (int i = 0; i < MAX_ORIENT; i++) { - if (Anims[StanceID][i]) { - tmppoi = Anims[StanceID][i]; - for (int j = 0; j < partCount; j++) - delete Anims[StanceID][i][j]; - delete[] tmppoi; - - // anims can only be duplicated at the Animation** level - for (int IDb=StanceID;IDb < MAX_ANIMS; IDb++) { - for (int i2 = 0; i2FreePalette(palette[PAL_MAIN], PaletteResRef); - int i; - for (i = 1; i < 4; ++i) - gamedata->FreePalette(palette[i], 0); - for (i = 0; i < 4; ++i) - gamedata->FreePalette(modifiedPalette[i], 0); -} -/* -This is a simple Idea of how the animation are coded - -There are the following animation types: - -IE_ANI_CODE_MIRROR: The code automatically mirrors the needed frames - (as in the example above) - - These Animations are stores using the following template: - [NAME][ARMORTYPE][ACTIONCODE] - - Each BAM File contains only 9 Orientations, the missing 7 Animations - are created by Horizontally Mirroring the 1-7 Orientations. - -IE_ANI_CODE_MIRROR_2: another mirroring type with more animations - [NAME]g[1,11-15,2,21-26] - -IE_ANI_CODE_MIRROR_3: Almost identical to IE_ANI_CODE_MIRROR_2, but with fewer cycles in g26 - -IE_ANI_ONE_FILE: The whole animation is in one file, no mirroring needed. - Each animation group is 16 Cycles. - -IE_ANI_TWO_FILES: The whole animation is in 2 files. The East and West part are in 2 BAM Files. - Example: - ACHKg1 - ACHKg1E - - Each BAM File contains many animation groups, each animation group - stores 5 Orientations, the missing 3 are stored in East BAM Files. - - -IE_ANI_FOUR_FILES: The Animation is coded in Four Files. Probably it is an old Two File animation with - additional frames added in a second time. - -IE_ANI_FOUR_FILES_2: Like IE_ANI_FOUR_FILES but with only 16 cycles per frame. - -IE_ANI_TWENTYTWO: This Animation Type stores the Animation in the following format - [NAME][ACTIONCODE][/E] - ACTIONCODE=A1-6, CA, SX, SA (sling is A1) - The g1 file contains several animation states. See MHR - Probably it could use A7-9 files too, bringing the file numbers to 28. - This is the original bg1 format. - -IE_ANI_SIX_FILES: The layout for these files is: - [NAME][g1-3][/E] - Each state contains 16 Orientations, but the last 6 are stored in the East file. - g1 contains only the walking animation. - G2 contains stand, ready, get hit, die and twitch. - g3 contains 3 attacks. - -IE_ANI_SIX_FILES_2: Similar to SIX_FILES, but the orientation numbers are reduced like in FOUR_FILES. Only one animation uses it: MOGR - -IE_ANI_TWO_FILES_2: Animations using this type are stored using the following template: - [NAME]g1[/E] - Each state contains 8 Orientations, but the second 4 are stored in the East file. - From the standard animations, only AHRS and ACOW belong to this type. - -IE_ANI_TWO_FILES_3: Animations using this type are stored using the following template: - [NAME][ACTIONTYPE][/E] - - Example: - MBFI* - MBFI*E - - Each BAM File contains one animation group, each animation group - stores 5 Orientations though the files contain all 8 Cycles, the missing 3 are stored in East BAM Files in Cycle: Stance*8+ (5,6,7). - This is the standard IWD animation, but BG2 also has it. - See MMR - -IE_ANI_TWO_FILES_3B: Animations using this type are stored using the following template: - [NAME][ACTIONTYPE][/E] - - Example: - MBFI* - MBFI*E - - This is a cut down version of IE_ANI_TWO_FILES_3. A2, CA and SP suffixes are missing. - This is the standard IWD animation, but BG2 also has it. - See MOR2 - -IE_ANI_FOUR_FRAMES: These animations are large, four bams make a frame. - - -IE_ANI_NINE_FRAMES: These animations are huge, nine bams make a frame. - - -IE_ANI_FRAGMENT: These animations are used for projectile graphics. - A single file contains 5 cycles (code mirror for east animation) - -IE_ANI_PST_ANIMATION_1: -IE_ANI_PST_ANIMATION_2: -IE_ANI_PST_ANIMATION_3: - Planescape: Torment Animations are stored in a different - way than the other games. This format uses the following template: - [C/D][ACTIONTYPE][NAME][B] - - Example: - CAT1MRTB - - Each Animation stores 5 Orientations, which are automatically mirrored - to form an 8 Orientation Animation. PST Animations have a different Palette - format. This Animation Type handles the PST Palette format too. - - NOTE: Walking/Running animations store 9 Orientations. - The second variation is missing the resting stance (STD) and the transitions. - These creatures are always in combat stance (don't rest). - Animation_3 is without STC (combat stance), they are always standing - -IE_ANI_PST_STAND: This is a modified PST animation, it contains only a - Standing image for every orientations, it follows the - [C/D]STD[NAME][B] standard. - -IE_ANI_PST_GHOST: This is a special static animation with no standard - All armourlevels are drawn simultaneously. There is no orientation or stance. - - - WEST PART | EAST PART - | - NW NNW N NNE NE - NW 006 007 008 009 010 NE -WNW 005 | 011 ENE - W 004 xxx 012 E -WSW 003 | 013 ESE - SW 002 001 000 015 014 SE - SW SSW S SSE SE - | - | - -*/ - -Animation** CharAnimations::GetAnimation(unsigned char Stance, unsigned char Orient) -{ - if (StanceID>=MAX_ANIMS) { - error("CharAnimation", "Illegal stance ID\n"); - } - - //for paletted dragon animations, we need the stance id - StanceID = nextStanceID = Stance; - int AnimType = GetAnimType(); - - //alter stance here if it is missing and you know a substitute - //probably we should feed this result back to the actor? - switch (AnimType) { - case -1: //invalid animation - return NULL; - - case IE_ANI_PST_STAND: - StanceID=IE_ANI_AWAKE; - break; - case IE_ANI_PST_GHOST: - StanceID=IE_ANI_AWAKE; - Orient=0; - break; - case IE_ANI_PST_ANIMATION_3: //stc->std - if (StanceID==IE_ANI_READY) { - StanceID=IE_ANI_AWAKE; - } - break; - case IE_ANI_PST_ANIMATION_2: //std->stc - if (StanceID==IE_ANI_AWAKE) { - StanceID=IE_ANI_READY; - } - break; - } - //pst animations don't have separate animation for sleep/die - if (AnimType >= IE_ANI_PST_ANIMATION_1) { - if (StanceID==IE_ANI_DIE) { - StanceID=IE_ANI_TWITCH; - } - } - - //TODO: Implement Auto Resource Loading - //setting up the sequencing of animation cycles - autoSwitchOnEnd = false; - switch (StanceID) { - case IE_ANI_DAMAGE: - nextStanceID = IE_ANI_READY; - autoSwitchOnEnd = true; - break; - case IE_ANI_SLEEP: //going to sleep - nextStanceID = IE_ANI_TWITCH; - autoSwitchOnEnd = true; - break; - case IE_ANI_TWITCH: //dead, sleeping - autoSwitchOnEnd = false; - break; - case IE_ANI_DIE: //going to die - nextStanceID = IE_ANI_TWITCH; - autoSwitchOnEnd = true; - break; - case IE_ANI_WALK: - case IE_ANI_RUN: - case IE_ANI_CAST: // looping - case IE_ANI_READY: - break; - case IE_ANI_AWAKE: - break; - case IE_ANI_EMERGE: - case IE_ANI_GET_UP: - case IE_ANI_HEAD_TURN: - case IE_ANI_PST_START: - nextStanceID = IE_ANI_AWAKE; - autoSwitchOnEnd = true; - break; - case IE_ANI_CONJURE: //ending - case IE_ANI_SHOOT: - case IE_ANI_ATTACK: - case IE_ANI_ATTACK_JAB: - case IE_ANI_ATTACK_SLASH: - case IE_ANI_ATTACK_BACKSLASH: - nextStanceID = IE_ANI_READY; - autoSwitchOnEnd = true; - break; - default: - print ("Invalid Stance: %d\n", StanceID); - break; - } - Animation** anims = Anims[StanceID][Orient]; - - if (anims) { - return anims; - } - - int partCount = GetTotalPartCount(); - int actorPartCount = GetActorPartCount(); - if (partCount < 0) return 0; - anims = new Animation*[partCount]; - - EquipResRefData* equipdat = 0; - for (int part = 0; part < partCount; ++part) - { - anims[part] = 0; - - //newresref is based on the prefix (ResRef) and various - // other things. - //this is longer than expected so it won't overflow - char NewResRef[12]; - unsigned char Cycle = 0; - if (part < actorPartCount) { - // Character animation parts - - if (equipdat) delete equipdat; - - //we need this long for special anims - strncpy( NewResRef, ResRef, 8 ); - GetAnimResRef( StanceID, Orient, NewResRef, Cycle, part, equipdat); - } else { - // Equipment animation parts - - anims[part] = 0; - if (GetSize() == 0) continue; - - if (part == actorPartCount) { - if (WeaponRef[0] == 0) continue; - // weapon - GetEquipmentResRef(WeaponRef,false,NewResRef,Cycle,equipdat); - } else if (part == actorPartCount+1) { - if (OffhandRef[0] == 0) continue; - if (WeaponType == IE_ANI_WEAPON_2H) continue; - // off-hand - if (WeaponType == IE_ANI_WEAPON_1H) { - GetEquipmentResRef(OffhandRef,false,NewResRef,Cycle, - equipdat); - } else { // IE_ANI_WEAPON_2W - GetEquipmentResRef(OffhandRef,true,NewResRef,Cycle, - equipdat); - } - } else if (part == actorPartCount+2) { - if (HelmetRef[0] == 0) continue; - // helmet - GetEquipmentResRef(HelmetRef,false,NewResRef,Cycle,equipdat); - } - } - NewResRef[8]=0; //cutting right to size - - AnimationFactory* af = ( AnimationFactory* ) - gamedata->GetFactoryResource( NewResRef, - IE_BAM_CLASS_ID, IE_NORMAL ); - - if (!af) { - if (part < actorPartCount) { - printMessage("CharAnimations", "Couldn't create animationfactory: %s (%04x)\n", - LIGHT_RED, NewResRef, GetAnimationID());; - for (int i = 0; i < part; ++i) - delete anims[i]; - delete[] anims; - delete equipdat; - return 0; - } else { - // not fatal if animation for equipment is missing - continue; - } - } - - Animation* a = af->GetCycle( Cycle ); - anims[part] = a; - - if (!a) { - if (part < actorPartCount) { - printMessage("CharAnimations", "Couldn't load animation: %s, cycle %d\n", LIGHT_RED, - NewResRef, Cycle); - for (int i = 0; i < part; ++i) - delete anims[i]; - delete[] anims; - delete equipdat; - return 0; - } else { - // not fatal if animation for equipment is missing - continue; - } - } - - if (part < actorPartCount) { - //if you need to revert this change, consider true paletted - //animations which need a GlobalColorMod (mgir for example) - - //if (!palette[PAL_MAIN] && ((GlobalColorMod.type!=RGBModifier::NONE) || (NoPalette()!=1)) ) { - if(!palette[PAL_MAIN]) { - // This is the first time we're loading an Animation. - // We copy the palette of its first frame into our own palette - palette[PAL_MAIN] = a->GetFrame(0)->GetPalette()->Copy(); - // ...and setup the colours properly - SetupColors(PAL_MAIN); - } - } else if (part == actorPartCount) { - if (!palette[PAL_WEAPON]) { - palette[PAL_WEAPON] = a->GetFrame(0)->GetPalette()->Copy(); - SetupColors(PAL_WEAPON); - } - } else if (part == actorPartCount+1) { - if (!palette[PAL_OFFHAND]) { - palette[PAL_OFFHAND] = a->GetFrame(0)->GetPalette()->Copy(); - SetupColors(PAL_OFFHAND); - } - } else if (part == actorPartCount+2) { - if (!palette[PAL_HELMET]) { - palette[PAL_HELMET] = a->GetFrame(0)->GetPalette()->Copy(); - SetupColors(PAL_HELMET); - } - } - - //animation is affected by game flags - a->gameAnimation = true; - a->SetPos( 0 ); - - //setting up the sequencing of animation cycles - switch (StanceID) { - case IE_ANI_DAMAGE: - case IE_ANI_SLEEP: - case IE_ANI_TWITCH: - case IE_ANI_DIE: - case IE_ANI_PST_START: - case IE_ANI_HEAD_TURN: - case IE_ANI_CONJURE: - case IE_ANI_SHOOT: - case IE_ANI_ATTACK: - case IE_ANI_ATTACK_JAB: - case IE_ANI_ATTACK_SLASH: - case IE_ANI_ATTACK_BACKSLASH: - a->Flags |= A_ANI_PLAYONCE; - break; - case IE_ANI_EMERGE: - case IE_ANI_GET_UP: - a->playReversed = true; - a->Flags |= A_ANI_PLAYONCE; - break; - } - switch (GetAnimType()) { - case IE_ANI_NINE_FRAMES: //dragon animations - case IE_ANI_FOUR_FRAMES: //wyvern animations - case IE_ANI_BIRD: - case IE_ANI_CODE_MIRROR: - case IE_ANI_CODE_MIRROR_2: //9 orientations - case IE_ANI_CODE_MIRROR_3: - case IE_ANI_PST_ANIMATION_3: //no stc just std - case IE_ANI_PST_ANIMATION_2: //no std just stc - case IE_ANI_PST_ANIMATION_1: - case IE_ANI_FRAGMENT: - if (Orient > 8) { - a->MirrorAnimation( ); - } - break; - default: - break; - } - - // make animarea of part 0 encompass the animarea of the other parts - if (part > 0) - anims[0]->AddAnimArea(a); - - } - - switch (GetAnimType()) { - case IE_ANI_NINE_FRAMES: //dragon animations - case IE_ANI_FOUR_FRAMES: //wyvern animations - case IE_ANI_BIRD: - case IE_ANI_CODE_MIRROR: - case IE_ANI_SIX_FILES: //16 anims some are stored elsewhere - case IE_ANI_ONE_FILE: //16 orientations - case IE_ANI_CODE_MIRROR_2: //9 orientations - case IE_ANI_CODE_MIRROR_3: - Anims[StanceID][Orient] = anims; - break; - case IE_ANI_TWO_FILES: - case IE_ANI_TWENTYTWO: - case IE_ANI_TWO_FILES_2: - case IE_ANI_TWO_FILES_3: - case IE_ANI_TWO_FILES_3B: - case IE_ANI_FOUR_FILES: - case IE_ANI_FOUR_FILES_2: - case IE_ANI_SIX_FILES_2: - case IE_ANI_FRAGMENT: - Orient&=~1; - Anims[StanceID][Orient] = anims; - Anims[StanceID][Orient + 1] = anims; - break; - - case IE_ANI_PST_ANIMATION_3: //no stc just std - case IE_ANI_PST_ANIMATION_2: //no std just stc - case IE_ANI_PST_ANIMATION_1: - switch (StanceID) { - case IE_ANI_WALK: - case IE_ANI_RUN: - case IE_ANI_PST_START: - Anims[StanceID][Orient] = anims; - break; - default: - Orient &=~1; - Anims[StanceID][Orient] = anims; - Anims[StanceID][Orient + 1] = anims; - break; - } - break; - - case IE_ANI_PST_STAND: - Orient &=~1; - Anims[StanceID][Orient] = anims; - Anims[StanceID][Orient+1] = anims; - break; - case IE_ANI_PST_GHOST: - Orient = 0; - StanceID = IE_ANI_AWAKE; - Anims[StanceID][0] = anims; - break; - default: - error("CharAnimations", "Unknown animation type\n"); - } - delete equipdat; - - return Anims[StanceID][Orient]; -} - -static const int one_file[19]={2, 1, 0, 0, 2, 3, 0, 1, 0, 4, 1, 0, 0, 0, 3, 1, 4, 4, 4}; - -void CharAnimations::GetAnimResRef(unsigned char StanceID, - unsigned char Orient, - char* NewResRef, unsigned char& Cycle, - int Part, EquipResRefData*& EquipData) -{ - EquipData = 0; - Orient &= 15; - switch (GetAnimType()) { - case IE_ANI_FOUR_FRAMES: - AddFFSuffix( NewResRef, StanceID, Cycle, Orient, Part ); - break; - - case IE_ANI_NINE_FRAMES: - AddNFSuffix( NewResRef, StanceID, Cycle, Orient, Part ); - break; - - case IE_ANI_CODE_MIRROR: - AddVHRSuffix( NewResRef, StanceID, Cycle, Orient, EquipData ); - break; - - case IE_ANI_BIRD: - Cycle = (ieByte) ((StanceID&1) * 9 + SixteenToNine[Orient]); - break; - - case IE_ANI_FRAGMENT: - Cycle = SixteenToFive[Orient]; - break; - - case IE_ANI_ONE_FILE: - Cycle = (ieByte) (one_file[StanceID] * 16 + Orient); - break; - - case IE_ANI_SIX_FILES: - AddSixSuffix( NewResRef, StanceID, Cycle, Orient ); - break; - - case IE_ANI_TWENTYTWO: //5+3 animations - AddMHRSuffix( NewResRef, StanceID, Cycle, Orient, EquipData ); - break; - - case IE_ANI_TWO_FILES_2: //4+4 animations - AddLR2Suffix( NewResRef, StanceID, Cycle, Orient ); - break; - - case IE_ANI_TWO_FILES_3: //IWD style anims - AddMMRSuffix( NewResRef, StanceID, Cycle, Orient ); - break; - - case IE_ANI_TWO_FILES_3B: //IWD style anims - AddMMR2Suffix( NewResRef, StanceID, Cycle, Orient ); - break; - - case IE_ANI_TWO_FILES: - AddTwoFileSuffix(NewResRef, StanceID, Cycle, Orient ); - break; - - case IE_ANI_FOUR_FILES: - AddLRSuffix( NewResRef, StanceID, Cycle, Orient, EquipData ); - break; - - case IE_ANI_FOUR_FILES_2: - AddLRSuffix2( NewResRef, StanceID, Cycle, Orient, EquipData ); - break; - - case IE_ANI_SIX_FILES_2: //MOGR (variant of FOUR_FILES) - AddLR3Suffix( NewResRef, StanceID, Cycle, Orient ); - break; - - case IE_ANI_CODE_MIRROR_2: //9 orientations - AddVHR2Suffix( NewResRef, StanceID, Cycle, Orient ); - break; - - case IE_ANI_CODE_MIRROR_3: // like IE_ANI_CODE_MIRROR_2 but with fewer cycles in g26 - AddVHR3Suffix( NewResRef, StanceID, Cycle, Orient ); - break; - - case IE_ANI_PST_ANIMATION_1: - case IE_ANI_PST_ANIMATION_2: - case IE_ANI_PST_ANIMATION_3: - AddPSTSuffix( NewResRef, StanceID, Cycle, Orient ); - break; - - case IE_ANI_PST_STAND: - sprintf(NewResRef,"%cSTD%4s",ResRef[0], ResRef+1); - Cycle = (ieByte) SixteenToFive[Orient]; - break; - case IE_ANI_PST_GHOST: // pst static animations - //still doesn't handle the second cycle of the golem anim - Cycle = 0; - strnlwrcpy(NewResRef, AvatarTable[AvatarsRowNum].Prefixes[Part], 8); - break; - default: - error("CharAnimations", "Unknown animation type in avatars.2da row: %d\n", AvatarsRowNum); - } -} - -void CharAnimations::GetEquipmentResRef(const char* equipRef, bool offhand, - char* ResRef, unsigned char& Cycle, EquipResRefData* equip) -{ - switch (GetAnimType()) { - case IE_ANI_FOUR_FILES: - case IE_ANI_FOUR_FILES_2: - GetLREquipmentRef( ResRef, Cycle, equipRef, offhand, equip ); - break; - case IE_ANI_CODE_MIRROR: - GetVHREquipmentRef( ResRef, Cycle, equipRef, offhand, equip ); - break; - case IE_ANI_TWENTYTWO: - GetMHREquipmentRef( ResRef, Cycle, equipRef, offhand, equip ); - break; - default: - error("CharAnimations", "Unsupported animation type for equipment animation.\n"); - break; - } -} - -const int* CharAnimations::GetZOrder(unsigned char Orient) -{ - switch (GetAnimType()) { - case IE_ANI_CODE_MIRROR: - return zOrder_Mirror16[Orient]; - case IE_ANI_TWENTYTWO: - return zOrder_8[Orient/2]; - case IE_ANI_FOUR_FILES: - return 0; // FIXME - default: - return 0; - } -} - - -void CharAnimations::AddPSTSuffix(char* ResRef, unsigned char StanceID, - unsigned char& Cycle, unsigned char Orient) -{ - const char *Prefix; - - switch (StanceID) { - case IE_ANI_ATTACK: - case IE_ANI_ATTACK_SLASH: - case IE_ANI_ATTACK_JAB: - case IE_ANI_ATTACK_BACKSLASH: - Cycle=SixteenToFive[Orient]; - Prefix="at1"; break; - case IE_ANI_DAMAGE: - Cycle=SixteenToFive[Orient]; - Prefix="hit"; break; - case IE_ANI_GET_UP: - case IE_ANI_EMERGE: - Cycle=SixteenToFive[Orient]; - Prefix="gup"; break; - case IE_ANI_AWAKE: - Cycle=SixteenToFive[Orient]; - Prefix="std"; break; - case IE_ANI_READY: - Cycle=SixteenToFive[Orient]; - Prefix="stc"; break; - case IE_ANI_DIE: - case IE_ANI_SLEEP: - case IE_ANI_TWITCH: - Cycle=SixteenToFive[Orient]; - Prefix="dfb"; break; - case IE_ANI_RUN: - Cycle=SixteenToNine[Orient]; - Prefix="run"; break; - case IE_ANI_WALK: - Cycle=SixteenToNine[Orient]; - Prefix="wlk"; break; - case IE_ANI_HEAD_TURN: - Cycle=SixteenToFive[Orient]; - if (rand()&1) { - Prefix="sf2"; - sprintf(ResRef,"%c%3s%4s",this->ResRef[0], Prefix, this->ResRef+1); - if (gamedata->Exists(ResRef, IE_BAM_CLASS_ID) ) { - return; - } - } - Prefix="sf1"; - sprintf(ResRef,"%c%3s%4s",this->ResRef[0], Prefix, this->ResRef+1); - if (gamedata->Exists(ResRef, IE_BAM_CLASS_ID) ) { - return; - } - Prefix = "stc"; - break; - case IE_ANI_PST_START: - Cycle=0; - Prefix="ms1"; break; - default: //just in case - Cycle=SixteenToFive[Orient]; - Prefix="stc"; break; - } - sprintf(ResRef,"%c%3s%4s",this->ResRef[0], Prefix, this->ResRef+1); -} - -void CharAnimations::AddVHR2Suffix(char* ResRef, unsigned char StanceID, - unsigned char& Cycle, unsigned char Orient) -{ - Cycle=SixteenToNine[Orient]; - - switch (StanceID) { - case IE_ANI_ATTACK: //temporarily - case IE_ANI_ATTACK_BACKSLASH: - strcat( ResRef, "g21" ); - break; - - case IE_ANI_ATTACK_SLASH: - strcat( ResRef, "g2" ); - break; - - case IE_ANI_ATTACK_JAB: - strcat( ResRef, "g26" ); - Cycle+=45; - break; - - case IE_ANI_CAST: //looping - strcat( ResRef, "g25" ); - Cycle+=45; - break; - - case IE_ANI_CONJURE://ending - strcat( ResRef, "g26" ); - Cycle+=54; - break; - - case IE_ANI_SHOOT: - strcat( ResRef, "g24" ); - Cycle+=27; - break; - - case IE_ANI_HEAD_TURN: - case IE_ANI_AWAKE: - strcat( ResRef, "g12" ); - Cycle+=18; - break; - - case IE_ANI_SLEEP: - strcat( ResRef, "g15" ); - Cycle+=45; - break; - - case IE_ANI_TWITCH: - strcat( ResRef, "g14" ); - Cycle+=45; - break; - - case IE_ANI_DIE: - case IE_ANI_EMERGE: - case IE_ANI_GET_UP: - case IE_ANI_PST_START: - strcat( ResRef, "g14" ); - Cycle+=36; - break; - - case IE_ANI_DAMAGE: - strcat( ResRef, "g13" ); - Cycle+=27; - break; - - case IE_ANI_READY: - strcat( ResRef, "g1" ); - Cycle+=9; - break; - - case IE_ANI_WALK: - strcat( ResRef, "g11" ); - break; - - case IE_ANI_HIDE: - strcat( ResRef, "g22" ); - break; - default: - error("CharAnimation", "VHR2 Animation: unhandled stance: %s %d\n", ResRef, StanceID); - break; - } -} - -void CharAnimations::AddVHR3Suffix(char* ResRef, unsigned char StanceID, - unsigned char& Cycle, unsigned char Orient) -{ - Cycle=SixteenToNine[Orient]; - - switch (StanceID) { - case IE_ANI_ATTACK: //temporarily - case IE_ANI_ATTACK_BACKSLASH: - strcat( ResRef, "g21" ); - break; - - case IE_ANI_ATTACK_SLASH: - strcat( ResRef, "g2" ); - break; - - case IE_ANI_ATTACK_JAB: - strcat( ResRef, "g26" ); - Cycle+=18; - break; - - case IE_ANI_CAST: //looping - strcat( ResRef, "g25" ); - Cycle+=45; - break; - - case IE_ANI_CONJURE://ending - strcat( ResRef, "g26" ); - Cycle+=36; - break; - - case IE_ANI_SHOOT: - strcat( ResRef, "g24" ); - Cycle+=27; - break; - - case IE_ANI_HEAD_TURN: - case IE_ANI_AWAKE: - strcat( ResRef, "g12" ); - Cycle+=18; - break; - - case IE_ANI_SLEEP: - strcat( ResRef, "g15" ); - Cycle+=45; - break; - - case IE_ANI_TWITCH: - strcat( ResRef, "g14" ); - Cycle+=45; - break; - - case IE_ANI_DIE: - case IE_ANI_EMERGE: - case IE_ANI_GET_UP: - case IE_ANI_PST_START: - strcat( ResRef, "g14" ); - Cycle+=36; - break; - - case IE_ANI_DAMAGE: - strcat( ResRef, "g13" ); - Cycle+=27; - break; - - case IE_ANI_READY: - strcat( ResRef, "g1" ); - Cycle+=9; - break; - - case IE_ANI_WALK: - strcat( ResRef, "g11" ); - break; - default: - error("CharAnimation", "VHR3 Animation: unhandled stance: %s %d\n", ResRef, StanceID); - break; - } -} - -// Note: almost like SixSuffix -void CharAnimations::AddFFSuffix(char* ResRef, unsigned char StanceID, - unsigned char& Cycle, unsigned char Orient, int Part) -{ - Cycle=SixteenToNine[Orient]; - switch (StanceID) { - case IE_ANI_WALK: - strcat( ResRef, "g1" ); - break; - - case IE_ANI_ATTACK: - case IE_ANI_ATTACK_SLASH: - strcat( ResRef, "g3" ); - break; - - case IE_ANI_ATTACK_BACKSLASH: - strcat( ResRef, "g3" ); - Cycle += 16; - break; - - case IE_ANI_ATTACK_JAB: - case IE_ANI_CAST: - case IE_ANI_CONJURE: - strcat( ResRef, "g3" ); - Cycle += 32; - break; - - case IE_ANI_HEAD_TURN: //could be wrong - case IE_ANI_AWAKE: - strcat( ResRef, "g2" ); - break; - - case IE_ANI_READY: - strcat( ResRef, "g2" ); - Cycle += 16; - break; - - case IE_ANI_DAMAGE: - strcat( ResRef, "g2" ); - Cycle += 32; - break; - - case IE_ANI_DIE: - case IE_ANI_GET_UP: - case IE_ANI_EMERGE: - case IE_ANI_PST_START: - strcat( ResRef, "g2" ); - Cycle += 48; - break; - - case IE_ANI_TWITCH: - strcat( ResRef, "g2" ); - Cycle += 64; - break; - - default: - error("CharAnimation", "Four frames Animation: unhandled stance: %s %d\n", ResRef, StanceID); - break; - - } - ResRef[6]=(char) (Part+'1'); - ResRef[7]=0; -} - -void CharAnimations::AddNFSuffix(char* ResRef, unsigned char StanceID, - unsigned char& Cycle, unsigned char Orient, int Part) -{ - char prefix[10]; - - Cycle = SixteenToNine[Orient]; - snprintf(prefix, 9, "%s%s%d%s%d", ResRef, StancePrefix[StanceID], Part+1, - CyclePrefix[StanceID], Cycle); - strnlwrcpy(ResRef,prefix,8); - Cycle=(ieByte) (Cycle+CycleOffset[StanceID]); -} - -//Attack -//h1, h2, w2 -//static const char *SlashPrefix[]={"a1","a4","a7"}; -//static const char *BackPrefix[]={"a2","a5","a8"}; -//static const char *JabPrefix[]={"a3","a6","a9"}; -static const char *SlashPrefix[]={"a1","a2","a7"}; -static const char *BackPrefix[]={"a3","a4","a8"}; -static const char *JabPrefix[]={"a5","a6","a9"}; -static const char *RangedPrefix[]={"sa","sx","ss"}; -static const char *RangedPrefixOld[]={"sa","sx","a1"}; - -void CharAnimations::AddVHRSuffix(char* ResRef, unsigned char StanceID, - unsigned char& Cycle, unsigned char Orient, EquipResRefData*& EquipData) -{ - Cycle = SixteenToNine[Orient]; - EquipData = new EquipResRefData; - EquipData->Suffix[0] = 0; - switch (StanceID) { - case IE_ANI_ATTACK: - case IE_ANI_ATTACK_SLASH: - strcat( ResRef, SlashPrefix[WeaponType] ); - strcpy( EquipData->Suffix, SlashPrefix[WeaponType] ); - break; - - case IE_ANI_ATTACK_BACKSLASH: - strcat( ResRef, BackPrefix[WeaponType] ); - strcpy( EquipData->Suffix, BackPrefix[WeaponType] ); - break; - - case IE_ANI_ATTACK_JAB: - strcat( ResRef, JabPrefix[WeaponType] ); - strcpy( EquipData->Suffix, JabPrefix[WeaponType] ); - break; - - case IE_ANI_AWAKE: - strcat( ResRef, "g17" ); - strcpy( EquipData->Suffix, "g1" ); - Cycle += 63; - break; - - case IE_ANI_CAST: //looping - strcat( ResRef, "ca" ); - strcpy( EquipData->Suffix, "ca" ); - break; - - case IE_ANI_CONJURE: //ending - strcat( ResRef, "ca" ); - strcpy( EquipData->Suffix, "ca" ); - Cycle += 9; - break; - - case IE_ANI_DAMAGE: - strcat( ResRef, "g14" ); - strcpy( EquipData->Suffix, "g1" ); - Cycle += 36; - break; - - case IE_ANI_DIE: - strcat( ResRef, "g15" ); - strcpy( EquipData->Suffix, "g1" ); - Cycle += 45; - break; - //I cannot find an emerge animation... - //Maybe is Die reversed - case IE_ANI_GET_UP: - case IE_ANI_EMERGE: - case IE_ANI_PST_START: - strcat( ResRef, "g19" ); - strcpy( EquipData->Suffix, "g1" ); - Cycle += 81; - break; - - case IE_ANI_HEAD_TURN: - if (rand()&1) { - strcat( ResRef, "g12" ); - Cycle += 18; - } else { - strcat( ResRef, "g18" ); - Cycle += 72; - } - strcpy( EquipData->Suffix, "g1" ); - break; - - //Unknown... maybe only a transparency effect apply - case IE_ANI_HIDE: - break; - - case IE_ANI_READY: - if ( WeaponType == IE_ANI_WEAPON_2H ) { - strcat( ResRef, "g13" ); - Cycle += 27; - } else { - strcat( ResRef, "g1" ); - Cycle += 9; - } - strcpy( EquipData->Suffix, "g1" ); - break; - //This depends on the ranged weapon equipped - case IE_ANI_SHOOT: - strcat( ResRef, RangedPrefix[RangedType] ); - strcpy( EquipData->Suffix, RangedPrefix[RangedType] ); - break; - - case IE_ANI_SLEEP: - strcat( ResRef, "g16" ); - strcpy( EquipData->Suffix, "g1" ); - Cycle += 54; - break; - - case IE_ANI_TWITCH: - strcat( ResRef, "g16" ); - strcpy( EquipData->Suffix, "g1" ); - Cycle += 54; - break; - - case IE_ANI_WALK: - strcat( ResRef, "g11" ); - strcpy( EquipData->Suffix, "g1" ); - break; - - default: - error("CharAnimation", "VHR Animation: unhandled stance: %s %d\n", ResRef, StanceID); - break; - } - EquipData->Cycle = Cycle; -} - -void CharAnimations::GetVHREquipmentRef(char* ResRef, unsigned char& Cycle, - const char* equipRef, bool offhand, - EquipResRefData* equip) -{ - Cycle = equip->Cycle; - if (offhand) { - sprintf( ResRef, "wq%c%c%co%s", GetSize(), equipRef[0], equipRef[1], equip->Suffix ); - } else { - sprintf( ResRef, "wq%c%c%c%s", GetSize(), equipRef[0], equipRef[1], equip->Suffix ); - } -} - -void CharAnimations::AddSixSuffix(char* ResRef, unsigned char StanceID, - unsigned char& Cycle, unsigned char Orient) -{ - switch (StanceID) { - case IE_ANI_WALK: - strcat( ResRef, "g1" ); - Cycle = Orient; - break; - - case IE_ANI_ATTACK: - case IE_ANI_ATTACK_SLASH: - strcat( ResRef, "g3" ); - Cycle = Orient; - break; - - case IE_ANI_ATTACK_BACKSLASH: - strcat( ResRef, "g3" ); - Cycle = 16 + Orient; - break; - - case IE_ANI_ATTACK_JAB: - strcat( ResRef, "g3" ); - Cycle = 32 + Orient; - break; - - case IE_ANI_HEAD_TURN: //could be wrong - case IE_ANI_AWAKE: - strcat( ResRef, "g2" ); - Cycle = 0 + Orient; - break; - - case IE_ANI_READY: - strcat( ResRef, "g2" ); - Cycle = 16 + Orient; - break; - - case IE_ANI_DAMAGE: - strcat( ResRef, "g2" ); - Cycle = 32 + Orient; - break; - - case IE_ANI_DIE: - case IE_ANI_GET_UP: - case IE_ANI_EMERGE: - case IE_ANI_PST_START: - strcat( ResRef, "g2" ); - Cycle = 48 + Orient; - break; - - case IE_ANI_TWITCH: - case IE_ANI_SLEEP: - strcat( ResRef, "g2" ); - Cycle = 64 + Orient; - break; - - default: - error("CharAnimation", "Six Animation: unhandled stance: %s %d\n", ResRef, StanceID); - break; - - } - if (Orient>9) { - strcat( ResRef, "e" ); - } -} - -void CharAnimations::AddLR2Suffix(char* ResRef, unsigned char StanceID, - unsigned char& Cycle, unsigned char Orient) -{ - Orient /= 2; - - switch (StanceID) { - case IE_ANI_READY: - case IE_ANI_CAST: //looping - case IE_ANI_CONJURE://ending - case IE_ANI_HIDE: - case IE_ANI_WALK: - case IE_ANI_AWAKE: - Cycle = 0 + Orient; - break; - - case IE_ANI_SHOOT: - case IE_ANI_ATTACK: - case IE_ANI_ATTACK_SLASH: - case IE_ANI_ATTACK_BACKSLASH: - case IE_ANI_ATTACK_JAB: - case IE_ANI_HEAD_TURN: - Cycle = 8 + Orient; - break; - - case IE_ANI_DIE: - case IE_ANI_GET_UP: - case IE_ANI_EMERGE: - case IE_ANI_PST_START: - Cycle = 24 + Orient; - break; - - case IE_ANI_DAMAGE: - Cycle = 16 + Orient; - break; - - case IE_ANI_SLEEP: - case IE_ANI_TWITCH: - Cycle = 32 + Orient; - break; - default: - error("CharAnimation", "LR2 Animation: unhandled stance: %s %d\n", ResRef, StanceID); - break; - } - if (Orient>=4) { - strcat( ResRef, "g1e" ); - } else { - strcat( ResRef, "g1" ); - } -} - -void CharAnimations::AddMHRSuffix(char* ResRef, unsigned char StanceID, - unsigned char& Cycle, unsigned char Orient, EquipResRefData*& EquipData) -{ - Orient /= 2; - EquipData = new EquipResRefData; - EquipData->Suffix[0] = 0; - - switch (StanceID) { - case IE_ANI_ATTACK: - case IE_ANI_ATTACK_SLASH: - strcat (ResRef, SlashPrefix[WeaponType]); - strcpy( EquipData->Suffix, SlashPrefix[WeaponType] ); - Cycle = Orient; - break; - - case IE_ANI_ATTACK_BACKSLASH: - strcat (ResRef, BackPrefix[WeaponType]); - strcpy( EquipData->Suffix, BackPrefix[WeaponType] ); - Cycle = Orient; - break; - - case IE_ANI_ATTACK_JAB: - strcat (ResRef, JabPrefix[WeaponType]); - strcpy( EquipData->Suffix, JabPrefix[WeaponType] ); - Cycle = Orient; - break; - - case IE_ANI_READY: - strcat( ResRef, "g1" ); - strcpy( EquipData->Suffix, "g1" ); - if ( WeaponType == IE_ANI_WEAPON_2W ) { - Cycle = 24 + Orient; - } else { - Cycle = 8 + Orient; - } - break; - - case IE_ANI_CAST://looping - strcat( ResRef, "ca" ); - strcpy( EquipData->Suffix, "ca" ); - Cycle = 8 + Orient; - break; - - case IE_ANI_CONJURE://ending - strcat( ResRef, "ca" ); - strcpy( EquipData->Suffix, "ca" ); - Cycle = Orient; - break; - - case IE_ANI_DAMAGE: - strcat( ResRef, "g1" ); - strcpy( EquipData->Suffix, "g1" ); - Cycle = 40 + Orient; - break; - - case IE_ANI_DIE: - case IE_ANI_GET_UP: - case IE_ANI_PST_START: - strcat( ResRef, "g1" ); - strcpy( EquipData->Suffix, "g1" ); - Cycle = 48 + Orient; - break; - - //I cannot find an emerge animation... - //Maybe is Die reversed - case IE_ANI_EMERGE: - strcat( ResRef, "g1" ); - strcpy( EquipData->Suffix, "g1" ); - Cycle = 48 + Orient; - break; - - case IE_ANI_HEAD_TURN: - strcat( ResRef, "g1" ); - strcpy( EquipData->Suffix, "g1" ); - Cycle = 32 + Orient; - break; - - //Unknown... maybe only a transparency effect apply - case IE_ANI_HIDE: - break; - - case IE_ANI_AWAKE: - strcat( ResRef, "g1" ); - strcpy( EquipData->Suffix, "g1" ); - Cycle = 16 + Orient; - break; - - //This depends on the ranged weapon equipped - case IE_ANI_SHOOT: - strcat (ResRef, RangedPrefixOld[RangedType]); - strcpy( EquipData->Suffix, RangedPrefixOld[RangedType] ); - Cycle = Orient; - break; - - case IE_ANI_SLEEP: - strcat( ResRef, "g1" ); - strcpy( EquipData->Suffix, "g1" ); - Cycle = 64 + Orient; - break; - - case IE_ANI_TWITCH: - strcat( ResRef, "g1" ); - strcpy( EquipData->Suffix, "g1" ); - Cycle = 56 + Orient; - break; - - case IE_ANI_WALK: - strcat( ResRef, "g1" ); - strcpy( EquipData->Suffix, "g1" ); - Cycle = Orient; - break; - default: - error("CharAnimation", "MHR Animation: unhandled stance: %s %d\n", ResRef, StanceID); - break; - } - if (Orient>=5) { - strcat( ResRef, "e" ); - strcat( EquipData->Suffix, "e" ); - } - EquipData->Cycle = Cycle; -} - -void CharAnimations::GetMHREquipmentRef(char* ResRef, unsigned char& Cycle, - const char* equipRef, bool offhand, - EquipResRefData* equip) -{ - Cycle = equip->Cycle; - if (offhand) { - //i think there is no offhand stuff for bg1, lets use the bg2 equivalent here? - sprintf( ResRef, "wq%c%c%co%s", GetSize(), equipRef[0], equipRef[1], equip->Suffix ); - } else { - sprintf( ResRef, "wp%c%c%c%s", GetSize(), equipRef[0], equipRef[1], equip->Suffix ); - } -} - -void CharAnimations::AddTwoFileSuffix( char* ResRef, unsigned char StanceID, - unsigned char& Cycle, unsigned char Orient) -{ - switch(StanceID) { - case IE_ANI_HEAD_TURN: - Cycle = 16 + Orient / 2; - break; - case IE_ANI_DAMAGE: - Cycle = 24 + Orient / 2; - break; - case IE_ANI_SLEEP: - case IE_ANI_TWITCH: - Cycle = 40 + Orient / 2; - break; - case IE_ANI_GET_UP: - case IE_ANI_EMERGE: - case IE_ANI_DIE: - case IE_ANI_PST_START: - Cycle = 32 + Orient / 2; - break; - case IE_ANI_WALK: - Cycle = Orient / 2; - break; - default: - Cycle = 8 + Orient / 2; - break; - } - strcat( ResRef, "g1" ); - if (Orient > 9) { - strcat( ResRef, "e" ); - } -} - -void CharAnimations::AddLRSuffix2( char* ResRef, unsigned char StanceID, - unsigned char& Cycle, unsigned char Orient, EquipResRefData *&EquipData) -{ - EquipData = new EquipResRefData; - EquipData->Suffix[0] = 0; - switch (StanceID) { - case IE_ANI_ATTACK: - case IE_ANI_ATTACK_BACKSLASH: - case IE_ANI_ATTACK_SLASH: - case IE_ANI_ATTACK_JAB: - strcat( ResRef, "g2" ); - strcpy( EquipData->Suffix, "g2" ); - Cycle = Orient / 2; - break; - case IE_ANI_CAST: - case IE_ANI_CONJURE: - case IE_ANI_SHOOT: - strcat( ResRef, "g2" ); - strcpy( EquipData->Suffix, "g2" ); - Cycle = 8 + Orient / 2; - break; - case IE_ANI_WALK: - strcat( ResRef, "g1" ); - strcpy( EquipData->Suffix, "g1" ); - Cycle = Orient / 2; - break; - case IE_ANI_READY: - strcat( ResRef, "g1" ); - strcpy( EquipData->Suffix, "g1" ); - Cycle = 8 + Orient / 2; - break; - case IE_ANI_HEAD_TURN: //could be wrong - case IE_ANI_AWAKE: - strcat( ResRef, "g1" ); - strcpy( EquipData->Suffix, "g1" ); - Cycle = 16 + Orient / 2; - break; - case IE_ANI_DAMAGE: - strcat( ResRef, "g1" ); - strcpy( EquipData->Suffix, "g1" ); - Cycle = 24 + Orient / 2; - break; - case IE_ANI_GET_UP: - case IE_ANI_EMERGE: - case IE_ANI_PST_START: - case IE_ANI_DIE: - strcat( ResRef, "g1" ); - strcpy( EquipData->Suffix, "g1" ); - Cycle = 32 + Orient / 2; - break; - case IE_ANI_SLEEP: - case IE_ANI_HIDE: - case IE_ANI_TWITCH: - strcat( ResRef, "g1" ); - strcpy( EquipData->Suffix, "g1" ); - Cycle = 40 + Orient / 2; - break; - default: - error("CharAnimation", "LRSuffix2 Animation: unhandled stance: %s %d\n", ResRef, StanceID); - break; - } - if (Orient > 9) { - strcat( ResRef, "e" ); - strcat( EquipData->Suffix, "e"); - } - EquipData->Cycle = Cycle; -} - -void CharAnimations::AddLRSuffix( char* ResRef, unsigned char StanceID, - unsigned char& Cycle, unsigned char Orient, EquipResRefData *&EquipData) -{ - EquipData = new EquipResRefData; - EquipData->Suffix[0] = 0; - switch (StanceID) { - case IE_ANI_ATTACK: - case IE_ANI_ATTACK_BACKSLASH: - strcat( ResRef, "g2" ); - strcpy( EquipData->Suffix, "g2" ); - Cycle = Orient / 2; - break; - case IE_ANI_ATTACK_SLASH: - strcat( ResRef, "g2" ); - strcpy( EquipData->Suffix, "g2" ); - Cycle = 8 + Orient / 2; - break; - case IE_ANI_ATTACK_JAB: - strcat( ResRef, "g2" ); - strcpy( EquipData->Suffix, "g2" ); - Cycle = 16 + Orient / 2; - break; - case IE_ANI_CAST: - case IE_ANI_CONJURE: - case IE_ANI_SHOOT: - //these animations are missing - strcat( ResRef, "g2" ); - strcpy( EquipData->Suffix, "g2" ); - Cycle = Orient / 2; - break; - case IE_ANI_WALK: - strcat( ResRef, "g1" ); - strcpy( EquipData->Suffix, "g1" ); - Cycle = Orient / 2; - break; - case IE_ANI_READY: - strcat( ResRef, "g1" ); - strcpy( EquipData->Suffix, "g1" ); - Cycle = 8 + Orient / 2; - break; - case IE_ANI_HEAD_TURN: //could be wrong - case IE_ANI_AWAKE: - strcat( ResRef, "g1" ); - strcpy( EquipData->Suffix, "g1" ); - Cycle = 16 + Orient / 2; - break; - case IE_ANI_DAMAGE: - strcat( ResRef, "g1" ); - strcpy( EquipData->Suffix, "g1" ); - Cycle = 24 + Orient / 2; - break; - case IE_ANI_GET_UP: - case IE_ANI_EMERGE: - case IE_ANI_PST_START: - case IE_ANI_DIE: - strcat( ResRef, "g1" ); - strcpy( EquipData->Suffix, "g1" ); - Cycle = 32 + Orient / 2; - break; - case IE_ANI_TWITCH: - case IE_ANI_SLEEP: - strcat( ResRef, "g1" ); - strcpy( EquipData->Suffix, "g1" ); - Cycle = 40 + Orient / 2; - break; - default: - error("CharAnimation", "LR Animation: unhandled stance: %s %d\n", ResRef, StanceID); - break; - } - if (Orient > 9) { - strcat( ResRef, "e" ); - strcat( EquipData->Suffix, "e"); - } - EquipData->Cycle = Cycle; -} - -void CharAnimations::GetLREquipmentRef(char* ResRef, unsigned char& Cycle, - const char* equipRef, bool /*offhand*/, - EquipResRefData* equip) -{ - Cycle = equip->Cycle; - //hackhackhack - sprintf( ResRef, "%4s%c%s", this->ResRef, equipRef[0], equip->Suffix ); -} - -//Only for the ogre animation (MOGR) -void CharAnimations::AddLR3Suffix( char* ResRef, unsigned char StanceID, - unsigned char& Cycle, unsigned char Orient) -{ - switch (StanceID) { - case IE_ANI_ATTACK: - case IE_ANI_ATTACK_BACKSLASH: - strcat( ResRef, "g2" ); - Cycle = Orient / 2; - break; - case IE_ANI_ATTACK_SLASH: - strcat( ResRef, "g2" ); - Cycle = 8 + Orient / 2; - break; - case IE_ANI_ATTACK_JAB: - strcat( ResRef, "g2" ); - Cycle = 8 + Orient / 2; //there is no third attack animation - break; - case IE_ANI_CAST: - case IE_ANI_CONJURE: - case IE_ANI_SHOOT: - strcat( ResRef, "g3" ); - Cycle = Orient / 2; - break; - case IE_ANI_WALK: - strcat( ResRef, "g1" ); - Cycle = 16 + Orient / 2; - break; - case IE_ANI_READY: - strcat( ResRef, "g1" ); - Cycle = 8 + Orient / 2; - break; - case IE_ANI_HEAD_TURN: //could be wrong - case IE_ANI_AWAKE: - strcat( ResRef, "g1" ); - Cycle = Orient / 2; - break; - case IE_ANI_DAMAGE: - strcat( ResRef, "g3" ); - Cycle = 8 + Orient / 2; - break; - case IE_ANI_DIE: - case IE_ANI_GET_UP: - case IE_ANI_EMERGE: - case IE_ANI_PST_START: - case IE_ANI_SLEEP: - strcat( ResRef, "g3" ); - Cycle = 16 + Orient / 2; - break; - case IE_ANI_TWITCH: - strcat( ResRef, "g3" ); - Cycle = 24 + Orient / 2; - break; - default: - error("CharAnimation", "LR3 Animation: unhandled stance: %s %d\n", ResRef, StanceID); - break; - } - if (Orient > 9) { - strcat( ResRef, "e" ); - } -} - -void CharAnimations::AddMMR2Suffix(char* ResRef, unsigned char StanceID, - unsigned char& Cycle, unsigned char Orient) -{ - switch (StanceID) { - case IE_ANI_ATTACK: - case IE_ANI_ATTACK_SLASH: - case IE_ANI_ATTACK_BACKSLASH: - case IE_ANI_ATTACK_JAB: - case IE_ANI_CONJURE: - case IE_ANI_CAST: - strcat( ResRef, "a1" ); - Cycle = ( Orient / 2 ); - break; - - case IE_ANI_SHOOT: - strcat( ResRef, "a4" ); - Cycle = ( Orient / 2 ); - break; - - case IE_ANI_AWAKE: - case IE_ANI_READY: - strcat( ResRef, "sd" ); - Cycle = ( Orient / 2 ); - break; - - case IE_ANI_HEAD_TURN: - strcat( ResRef, "sc" ); - Cycle = ( Orient / 2 ); - break; - - case IE_ANI_DAMAGE: - strcat( ResRef, "gh" ); - Cycle = ( Orient / 2 ); - break; - - case IE_ANI_DIE: - strcat( ResRef, "de" ); - Cycle = ( Orient / 2 ); - break; - - case IE_ANI_GET_UP: - case IE_ANI_EMERGE: - case IE_ANI_PST_START: - strcat( ResRef, "gu" ); - Cycle = ( Orient / 2 ); - break; - - //Unknown... maybe only a transparency effect apply - case IE_ANI_HIDE: - break; - - case IE_ANI_SLEEP: - strcat( ResRef, "sl" ); - Cycle = ( Orient / 2 ); - break; - - case IE_ANI_TWITCH: - strcat( ResRef, "tw" ); - Cycle = ( Orient / 2 ); - break; - - case IE_ANI_WALK: - strcat( ResRef, "wk" ); - Cycle = ( Orient / 2 ); - break; - default: - error("CharAnimation", "MMR Animation: unhandled stance: %s %d\n", ResRef, StanceID); - break; - } - if (Orient > 9) { - strcat( ResRef, "e" ); - } -} - -void CharAnimations::AddMMRSuffix(char* ResRef, unsigned char StanceID, - unsigned char& Cycle, unsigned char Orient) -{ - switch (StanceID) { - case IE_ANI_ATTACK: - case IE_ANI_ATTACK_SLASH: - case IE_ANI_ATTACK_BACKSLASH: - strcat( ResRef, "a1" ); - Cycle = ( Orient / 2 ); - break; - - case IE_ANI_SHOOT: - strcat( ResRef, "a4" ); - Cycle = ( Orient / 2 ); - break; - - case IE_ANI_ATTACK_JAB: - strcat( ResRef, "a2" ); - Cycle = ( Orient / 2 ); - break; - - case IE_ANI_AWAKE: - case IE_ANI_READY: - strcat( ResRef, "sd" ); - Cycle = ( Orient / 2 ); - break; - - case IE_ANI_CONJURE: - strcat( ResRef, "ca" ); - Cycle = ( Orient / 2 ); - break; - - case IE_ANI_CAST: - strcat( ResRef, "sp" ); - Cycle = ( Orient / 2 ); - break; - - case IE_ANI_HEAD_TURN: - strcat( ResRef, "sc" ); - Cycle = ( Orient / 2 ); - break; - - case IE_ANI_DAMAGE: - strcat( ResRef, "gh" ); - Cycle = ( Orient / 2 ); - break; - - case IE_ANI_DIE: - strcat( ResRef, "de" ); - Cycle = ( Orient / 2 ); - break; - - case IE_ANI_GET_UP: - case IE_ANI_EMERGE: - case IE_ANI_PST_START: - strcat( ResRef, "gu" ); - Cycle = ( Orient / 2 ); - break; - - //Unknown... maybe only a transparency effect apply - case IE_ANI_HIDE: - break; - - case IE_ANI_SLEEP: - strcat( ResRef, "sl" ); - Cycle = ( Orient / 2 ); - break; - - case IE_ANI_TWITCH: - strcat( ResRef, "tw" ); - Cycle = ( Orient / 2 ); - break; - - case IE_ANI_WALK: - strcat( ResRef, "wk" ); - Cycle = ( Orient / 2 ); - break; - default: - error("CharAnimation", "MMR Animation: unhandled stance: %s %d\n", ResRef, StanceID); - break; - } - if (Orient > 9) { - strcat( ResRef, "e" ); - } -} - -void CharAnimations::PulseRGBModifiers() -{ - unsigned long time = core->GetGame()->Ticks; - - if (time - lastModUpdate <= 40) - return; - - if (time - lastModUpdate > 400) lastModUpdate = time - 40; - - int inc = (time - lastModUpdate)/40; - - if (GlobalColorMod.type != RGBModifier::NONE && - GlobalColorMod.speed > 0) - { - GlobalColorMod.phase += inc; - change[0] = change[1] = change[2] = change[3] = true; - - // reset if done - if (GlobalColorMod.phase > 2*GlobalColorMod.speed) { - GlobalColorMod.type = RGBModifier::NONE; - GlobalColorMod.phase = 0; - GlobalColorMod.speed = 0; - GlobalColorMod.locked = false; - } - } - - for (int i = 0; i < 32; ++i) { - if (ColorMods[i].type != RGBModifier::NONE && - ColorMods[i].speed > 0) - { - ColorMods[i].phase += inc; - change[i>>3] = true; - if (ColorMods[i].phase > 2*ColorMods[i].speed) { - ColorMods[i].type = RGBModifier::NONE; - ColorMods[i].phase = 0; - ColorMods[i].speed = 0; - ColorMods[i].locked = false; - } - } - } - - 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 deleted file mode 100644 index ea3331073..000000000 --- a/project/jni/application/gemrb/gemrb/core/CharAnimations.h +++ /dev/null @@ -1,233 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#ifndef CHARANIMATIONS_H -#define CHARANIMATIONS_H - -#include "RGBAColor.h" -#include "exports.h" - -#include "Animation.h" -#include "Palette.h" -#include "TableMgr.h" - -#include - -#define AV_PREFIX1 0 -#define AV_PREFIX2 1 -#define AV_PREFIX3 2 -#define AV_PREFIX4 3 -#define AV_ANIMTYPE 4 -#define AV_CIRCLESIZE 5 -#define AV_USE_PALETTE 6 -#define AV_SIZE 7 - -#define MAX_ANIMS 19 - -#define IE_ANI_ATTACK 0 -#define IE_ANI_AWAKE 1 -#define IE_ANI_CAST 2 -#define IE_ANI_CONJURE 3 -#define IE_ANI_DAMAGE 4 -#define IE_ANI_DIE 5 -#define IE_ANI_HEAD_TURN 6 -#define IE_ANI_READY 7 -#define IE_ANI_SHOOT 8 -#define IE_ANI_TWITCH 9 -#define IE_ANI_WALK 10 -#define IE_ANI_ATTACK_SLASH 11 -#define IE_ANI_ATTACK_BACKSLASH 12 -#define IE_ANI_ATTACK_JAB 13 -#define IE_ANI_EMERGE 14 -#define IE_ANI_HIDE 15 -#define IE_ANI_RUN 15 //pst has no hide, i hope -#define IE_ANI_SLEEP 16 -#define IE_ANI_GET_UP 17 -#define IE_ANI_PST_START 18 - -//BG2, IWD animation types -#define IE_ANI_CODE_MIRROR 0 -#define IE_ANI_ONE_FILE 1 -#define IE_ANI_FOUR_FILES 2 -#define IE_ANI_TWO_FILES 3 -#define IE_ANI_CODE_MIRROR_2 4 -#define IE_ANI_SIX_FILES_2 5 //MOGR -#define IE_ANI_TWENTYTWO 6 -#define IE_ANI_BIRD 7 -#define IE_ANI_SIX_FILES 8 //MCAR/MWYV -#define IE_ANI_TWO_FILES_3 9 //iwd animations -#define IE_ANI_TWO_FILES_2 10 //low res bg1 anim -#define IE_ANI_FOUR_FRAMES 11 //wyvern anims -#define IE_ANI_NINE_FRAMES 12 //dragon anims -#define IE_ANI_FRAGMENT 13 //fragment animation -#define IE_ANI_FOUR_FILES_2 14 //METT -#define IE_ANI_CODE_MIRROR_3 15 //MSPS -#define IE_ANI_TWO_FILES_3B 16 //iwd animations (eg. MBBM) - -//PST animation types -#define IE_ANI_PST_ANIMATION_1 56 //full animation -#define IE_ANI_PST_GHOST 57 //no orientations -#define IE_ANI_PST_STAND 58 //has orientations -#define IE_ANI_PST_ANIMATION_2 59 //full animation std-->stc -#define IE_ANI_PST_ANIMATION_3 60 //full animation stc-->std - -//armour levels -#define IE_ANI_NO_ARMOR 0 -#define IE_ANI_LIGHT_ARMOR 1 -#define IE_ANI_MEDIUM_ARMOR 2 -#define IE_ANI_HEAVY_ARMOR 3 - -#define IE_ANI_WEAPON_1H 0 -#define IE_ANI_WEAPON_2H 1 -#define IE_ANI_WEAPON_2W 2 - -#define IE_ANI_RANGED_BOW 0 -#define IE_ANI_RANGED_XBOW 1 -#define IE_ANI_RANGED_THROW 2 - -struct AvatarStruct { - /* entries from avatars.2da */ - unsigned int AnimID; - unsigned int PaletteType; - ieResRef Prefixes[4]; - unsigned char AnimationType; - unsigned char CircleSize; - char Size; - - /* comes from bloodclr.2da */ - char BloodColor; - - /* resdata.ini entries */ - unsigned int WalkScale; /* 1000 / walkscale */ - unsigned int RunScale; /* 1000 / runscale */ - int Bestiary; - - /* comes from walksnd.2da */ - ieResRef WalkSound; - ieByte WalkSoundCount; -}; - -struct EquipResRefData; - -class GEM_EXPORT CharAnimations { -private: - Animation** Anims[MAX_ANIMS][MAX_ORIENT]; - char HelmetRef[2]; - char WeaponRef[2]; - char OffhandRef[2]; -public: - const ieDword *Colors; //these are the custom color indices - RGBModifier ColorMods[32]; // color modification effects - unsigned long lastModUpdate; - RGBModifier GlobalColorMod; // global color modification effect - - bool change[4]; - Palette* palette[4]; - Palette* modifiedPalette[4]; - unsigned int AvatarsRowNum; - unsigned char ArmorType, WeaponType, RangedType; - ieResRef ResRef; - ieResRef PaletteResRef; - unsigned char nextStanceID, StanceID; - bool autoSwitchOnEnd; - bool lockPalette; -public: - CharAnimations(unsigned int AnimID, ieDword ArmourLevel); - ~CharAnimations(void); - static void ReleaseMemory(); - void SetArmourLevel(int ArmourLevel); - void SetRangedType(int Ranged); - void SetWeaponType(int WeaponType); - void SetHelmetRef(const char* ref); - void SetWeaponRef(const char* ref); - void SetOffhandRef(const char* ref); - void SetColors(const ieDword *Colors); - void CheckColorMod(); - void SetupColors(PaletteType type); - void LockPalette(const ieDword *Colors); - - // returns an array of animations of size GetTotalPartCount() - Animation** GetAnimation(unsigned char Stance, unsigned char Orient); - int GetTotalPartCount() const; - const int* GetZOrder(unsigned char Orient); - - // returns Palette for a given part (unlocked) - Palette* GetPartPalette(int part); // TODO: clean this up - -public: //attribute functions - static int GetAvatarsCount(); - static AvatarStruct *GetAvatarStruct(int RowNum); - unsigned int GetAnimationID() const; - int GetCircleSize() const; - int NoPalette() const; - int GetAnimType() const; - int GetSize() const; - int GetBloodColor() const; - const ieResRef &GetWalkSound() const; - int GetWalkSoundCount() const; - void PulseRGBModifiers(); - -private: - void DropAnims(); - void InitAvatarsTable(); - int GetActorPartCount() const; - void AddPSTSuffix(char* ResRef, unsigned char AnimID, - unsigned char& Cycle, unsigned char Orient); - void AddFFSuffix(char* ResRef, unsigned char AnimID, - unsigned char& Cycle, unsigned char Orient, int Part); - void AddNFSuffix(char* ResRef, unsigned char AnimID, - unsigned char& Cycle, unsigned char Orient, int Part); - void AddVHR2Suffix(char* ResRef, unsigned char AnimID, - unsigned char& Cycle, unsigned char Orient); - void AddVHRSuffix(char* ResRef, unsigned char AnimID, - unsigned char& Cycle, unsigned char Orient, EquipResRefData*& equip); - void AddVHR3Suffix(char* ResRef, unsigned char AnimID, - unsigned char& Cycle, unsigned char Orient); - void GetVHREquipmentRef(char* ResRef, unsigned char& Cycle, - const char* equipRef, bool offhand, EquipResRefData* equip); - void AddSixSuffix(char* ResRef, unsigned char AnimID, - unsigned char& Cycle, unsigned char Orient); - void AddMHRSuffix(char* ResRef, unsigned char AnimID, - unsigned char& Cycle, unsigned char Orient, EquipResRefData*& equip); - void GetMHREquipmentRef(char* ResRef, unsigned char& Cycle, - const char* equipRef, bool offhand, EquipResRefData* equip); - void AddMMRSuffix(char* ResRef, unsigned char AnimID, - unsigned char& Cycle, unsigned char Orient); - void AddMMR2Suffix(char* ResRef, unsigned char AnimID, - unsigned char& Cycle, unsigned char Orient); - void AddTwoFileSuffix(char* ResRef, unsigned char AnimID, - unsigned char& Cycle, unsigned char Orient); - void AddLRSuffix(char* ResRef, unsigned char AnimID, - unsigned char& Cycle, unsigned char Orient, EquipResRefData*& equip); - void AddLRSuffix2( char* ResRef, unsigned char StanceID, - unsigned char& Cycle, unsigned char Orient, EquipResRefData *&EquipData); - void GetLREquipmentRef(char* ResRef, unsigned char& Cycle, - const char* equipRef, bool offhand, EquipResRefData* equip); - void AddLR2Suffix(char* ResRef, unsigned char AnimID, - unsigned char& Cycle, unsigned char Orient); - void AddLR3Suffix(char* ResRef, unsigned char AnimID, - unsigned char& Cycle, unsigned char Orient); - void GetAnimResRef(unsigned char AnimID, unsigned char Orient, - char* ResRef, unsigned char& Cycle, int Part, EquipResRefData*& equip); - void GetEquipmentResRef(const char* equipRef, bool offhand, - char* ResRef, unsigned char& Cycle, EquipResRefData* equip); -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/Compressor.cpp b/project/jni/application/gemrb/gemrb/core/Compressor.cpp deleted file mode 100644 index 187c160b0..000000000 --- a/project/jni/application/gemrb/gemrb/core/Compressor.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "Compressor.h" - -#include "globals.h" - -Compressor::Compressor(void) -{ -} - -Compressor::~Compressor(void) -{ -} diff --git a/project/jni/application/gemrb/gemrb/core/Compressor.h b/project/jni/application/gemrb/gemrb/core/Compressor.h deleted file mode 100644 index dcc1ce409..000000000 --- a/project/jni/application/gemrb/gemrb/core/Compressor.h +++ /dev/null @@ -1,37 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#ifndef COMPRESSOR_H -#define COMPRESSOR_H - -#include "Plugin.h" -#include "System/DataStream.h" - -class GEM_EXPORT Compressor : public Plugin { -public: - Compressor(void); - virtual ~Compressor(void); - /** decompresses a datastream (memory or file) to a FILE * stream */ - virtual int Decompress(DataStream* dest, DataStream* source, unsigned int size_guess = 0) const = 0; - /** compresses a datastream (memory or file) to another DataStream */ - virtual int Compress(DataStream *dest, DataStream* source) const = 0; -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/ControlAnimation.cpp b/project/jni/application/gemrb/gemrb/core/ControlAnimation.cpp deleted file mode 100644 index 7e228f6ea..000000000 --- a/project/jni/application/gemrb/gemrb/core/ControlAnimation.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "ControlAnimation.h" - -#include "win32def.h" - -#include "AnimationFactory.h" -#include "GameData.h" -#include "GlobalTimer.h" -#include "Interface.h" -#include "Palette.h" /* needed only for paperdoll palettes */ -#include "Video.h" /* needed only for paperdoll palettes */ -#include "GUI/Button.h" - -ControlAnimation::ControlAnimation(Control* ctl, const ieResRef ResRef, int Cycle) -{ - control = NULL; - bam = NULL; - cycle = Cycle; - frame = 0; - anim_phase = 0; - - bam = ( AnimationFactory* ) gamedata->GetFactoryResource( ResRef, - IE_BAM_CLASS_ID, IE_NORMAL ); - - if (! bam) - return; - - control = ctl; - control->animation = this; - has_palette = false; - is_blended = false; -} - -//freeing the bitmaps only once, but using an intelligent algorithm -ControlAnimation::~ControlAnimation(void) -{ - //removing from timer first - core->timer->RemoveAnimation( this ); - - bam = NULL; -} - -bool ControlAnimation::SameResource(const ieResRef ResRef, int Cycle) -{ - if (!control ) return false; - if (!bam) return false; - if (strnicmp(ResRef, bam->ResRef, sizeof(ieResRef) )) return false; - int c = cycle; - if (control->Flags&IE_GUI_BUTTON_PLAYRANDOM) { - c&=~1; - } - if (Cycle!=c) return false; - return true; -} - -void ControlAnimation::UpdateAnimation(void) -{ - unsigned long time; - int Cycle = cycle; - - if (control->Flags & IE_GUI_BUTTON_PLAYRANDOM) { - // simple Finite-State Machine - if (anim_phase == 0) { - frame = 0; - anim_phase = 1; - time = 500 + 500 * (rand() % 20); - cycle&=~1; - Cycle=cycle; - } else if (anim_phase == 1) { - if (rand() % 30 == 0) { - cycle|=1; - Cycle=cycle; - } - anim_phase = 2; - time = 100; - } else { - frame++; - time = 100; - } - } else { - frame ++; - if (has_palette) { - time = 100; //hack for slower movement - } else { - time = 15; - } - } - - Sprite2D* pic = bam->GetFrame( (unsigned short) frame, (unsigned char) Cycle ); - - if (pic == NULL) { - //stopping at end frame - if (control->Flags & IE_GUI_BUTTON_PLAYONCE) { - core->timer->RemoveAnimation( this ); - control->SetAnimPicture( NULL ); - return; - } - anim_phase = 0; - frame = 0; - pic = bam->GetFrame( 0, (unsigned char) Cycle ); - } - - if (pic == NULL) { - return; - } - - if (has_palette) { - Palette* palette = pic->GetPalette(); - palette->SetupPaperdollColours(colors, 0); - if (is_blended) { - palette->CreateShadedAlphaChannel(); - } - pic->SetPalette(palette); - palette->Release(); - } else { - if (is_blended) { - Palette* palette = pic->GetPalette(); - palette->CreateShadedAlphaChannel(); - pic->SetPalette(palette); - palette->Release(); - } - } - - control->SetAnimPicture( pic ); - core->timer->AddAnimation( this, time ); -} - -void ControlAnimation::SetPaletteGradients(ieDword *col) -{ - memcpy(colors, col, 8*sizeof(ieDword)); - has_palette = true; -} - -void ControlAnimation::SetBlend(bool b) -{ - is_blended = b; -} diff --git a/project/jni/application/gemrb/gemrb/core/ControlAnimation.h b/project/jni/application/gemrb/gemrb/core/ControlAnimation.h deleted file mode 100644 index bb7a86d28..000000000 --- a/project/jni/application/gemrb/gemrb/core/ControlAnimation.h +++ /dev/null @@ -1,53 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#ifndef CONTROLANIMATIONS_H -#define CONTROLANIMATIONS_H - -#include "RGBAColor.h" -#include "exports.h" -#include "globals.h" - -#include - -class AnimationFactory; -class Control; - -class GEM_EXPORT ControlAnimation { -private: - AnimationFactory* bam; - Control* control; - unsigned int cycle; - unsigned int frame; - unsigned int anim_phase; - bool has_palette; - bool is_blended; - ieDword colors[8]; -public: - ControlAnimation(Control* ctl, const ieResRef ResRef, int Cycle = 0); - ~ControlAnimation(void); - void UpdateAnimation(); - //report if the current resource is the same as descripted by the params - bool SameResource(const ieResRef ResRef, int Cycle); - void SetPaletteGradients(ieDword *col); - void SetBlend(bool b); -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/Core.cpp b/project/jni/application/gemrb/gemrb/core/Core.cpp deleted file mode 100644 index 05d0911e4..000000000 --- a/project/jni/application/gemrb/gemrb/core/Core.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -/** - * @file Core.cpp - * Some compatibility and utility functions - * @author The GemRB Project - */ - -#include "globals.h" -#include "exports.h" - -#include "Interface.h" -#include "Scriptable/Actor.h" - -#include -#include -#ifdef WIN32 -#include "win32def.h" -#ifdef _DEBUG -#include -#include -#endif - -BOOL WINAPI DllEntryPoint(HINSTANCE /*hinstDLL*/, DWORD /*fdwReason*/, - LPVOID /*lpvReserved*/) -{ - return true; -} -#endif - -//// Globally used functions - -static const unsigned char orientations[25]={ -6,7,8,9,10, -5,6,8,10,11, -4,4,0,12,12, -3,2,0,14,13, -2,1,0,15,14 -}; - -/** Calculates the orientation of a character (or projectile) facing a point */ -unsigned char GetOrient(const Point &s, const Point &d) -{ - int deltaX = s.x - d.x; - int deltaY = s.y - d.y; - int div = Distance(s,d); - if(!div) return 0; //default - if(div>3) div/=2; - int aX=deltaX/div; - int aY=deltaY/div; - return orientations[(aY+2)*5+aX+2]; -} - -/** Calculates distance between 2 points */ -unsigned int Distance(Point p, Point q) -{ - long x = ( p.x - q.x ); - long y = ( p.y - q.y ); - return (unsigned int) sqrt( ( double ) ( x* x + y* y ) ); -} - -/** Calculates distance squared from a point to a scriptable */ -unsigned int SquaredMapDistance(Point p, Scriptable *b) -{ - long x = ( p.x/16 - b->Pos.x/16 ); - long y = ( p.y/12 - b->Pos.y/12 ); - return (unsigned int)(x*x + y*y); -} - -/** Calculates distance between 2 points */ -unsigned int Distance(Point p, Scriptable *b) -{ - long x = ( p.x - b->Pos.x ); - long y = ( p.y - b->Pos.y ); - return (unsigned int) sqrt( ( double ) ( x* x + y* y ) ); -} - -unsigned int PersonalDistance(Point p, Scriptable *b) -{ - long x = ( p.x - b->Pos.x ); - long y = ( p.y - b->Pos.y ); - int ret = (int) sqrt( ( double ) ( x* x + y* y ) ); - if (b->Type==ST_ACTOR) { - ret-=((Actor *)b)->size*10; - } - if (ret<0) return (unsigned int) 0; - return (unsigned int) ret; -} - -unsigned int SquaredPersonalDistance(Point p, Scriptable *b) -{ - long x = ( p.x - b->Pos.x ); - long y = ( p.y - b->Pos.y ); - int ret = x*x + y*y; - if (b->Type==ST_ACTOR) { - ret-=((Actor *)b)->size*100; - } - if (ret<0) return (unsigned int) 0; - return (unsigned int) ret; -} - -/** Calculates map distance between 2 scriptables */ -unsigned int SquaredMapDistance(Scriptable *a, Scriptable *b) -{ - long x = (a->Pos.x/16 - b->Pos.x/16 ); - long y = (a->Pos.y/12 - b->Pos.y/12 ); - return (unsigned int)(x*x + y*y); -} - -/** Calculates distance between 2 scriptables */ -unsigned int Distance(Scriptable *a, Scriptable *b) -{ - long x = ( a->Pos.x - b->Pos.x ); - long y = ( a->Pos.y - b->Pos.y ); - return (unsigned int) sqrt( ( double ) ( x* x + y* y ) ); -} - -/** Calculates distance squared between 2 scriptables */ -unsigned int SquaredDistance(Scriptable *a, Scriptable *b) -{ - long x = ( a->Pos.x - b->Pos.x ); - long y = ( a->Pos.y - b->Pos.y ); - return (unsigned int) ( x* x + y* y ); -} - -/** Calculates distance between 2 scriptables, including feet circle if applicable */ -unsigned int PersonalDistance(Scriptable *a, Scriptable *b) -{ - long x = ( a->Pos.x - b->Pos.x ); - long y = ( a->Pos.y - b->Pos.y ); - int ret = (int) sqrt( ( double ) ( x* x + y* y ) ); - if (a->Type==ST_ACTOR) { - ret-=((Actor *)a)->size*10; - } - if (b->Type==ST_ACTOR) { - ret-=((Actor *)b)->size*10; - } - if (ret<0) return (unsigned int) 0; - return (unsigned int) ret; -} - -unsigned int SquaredPersonalDistance(Scriptable *a, Scriptable *b) -{ - long x = ( a->Pos.x - b->Pos.x ); - long y = ( a->Pos.y - b->Pos.y ); - int ret = x*x + y*y; - if (a->Type==ST_ACTOR) { - ret-=((Actor *)a)->size*100; - } - if (b->Type==ST_ACTOR) { - ret-=((Actor *)b)->size*100; - } - if (ret<0) return (unsigned int) 0; - return (unsigned int) ret; -} - -// returns EA relation between two scriptables (non actors are always enemies) -// it is used for protectile targeting/iwd ids targeting too! -int EARelation(Scriptable* Owner, Actor* target) -{ - ieDword eao = EA_ENEMY; - - if (Owner && Owner->Type==ST_ACTOR) { - eao = ((Actor *) Owner)->GetStat(IE_EA); - } - - ieDword eat = target->GetStat(IE_EA); - - if (eao<=EA_GOODCUTOFF) { - - if (eat<=EA_GOODCUTOFF) { - return EAR_FRIEND; - } - if (eat>=EA_EVILCUTOFF) { - return EAR_HOSTILE; - } - - return EAR_NEUTRAL; - } - - if (eao>=EA_EVILCUTOFF) { - - if (eat<=EA_GOODCUTOFF) { - return EAR_HOSTILE; - } - if (eat>=EA_EVILCUTOFF) { - return EAR_FRIEND; - } - - return EAR_NEUTRAL; - } - - return EAR_NEUTRAL; -} diff --git a/project/jni/application/gemrb/gemrb/core/DataFileMgr.cpp b/project/jni/application/gemrb/gemrb/core/DataFileMgr.cpp deleted file mode 100644 index 2c95d6787..000000000 --- a/project/jni/application/gemrb/gemrb/core/DataFileMgr.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "DataFileMgr.h" - -DataFileMgr::DataFileMgr(void) -{ -} - -DataFileMgr::~DataFileMgr(void) -{ -} diff --git a/project/jni/application/gemrb/gemrb/core/DataFileMgr.h b/project/jni/application/gemrb/gemrb/core/DataFileMgr.h deleted file mode 100644 index 8df95ae7e..000000000 --- a/project/jni/application/gemrb/gemrb/core/DataFileMgr.h +++ /dev/null @@ -1,58 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -/** - * @file DataFileMgr.h - * Declares DataFileMgr class, abstract loader for .INI files - * @author The GemRB Project - */ - - -#ifndef DATAFILEMGR_H -#define DATAFILEMGR_H - -#include "Plugin.h" -#include "System/DataStream.h" - -/** - * @class DataFileMgr - * Abstract loader for .INI files - */ - -class GEM_EXPORT DataFileMgr : public Plugin { -public: - DataFileMgr(void); - virtual ~DataFileMgr(void); - virtual bool Open(DataStream* stream) = 0; - virtual int GetTagsCount() const = 0; - virtual const char* GetTagNameByIndex(int index) const = 0; - virtual int GetKeysCount(const char* Tag) const = 0; - virtual const char* GetKeyNameByIndex(const char* Tag, int index) const = 0; - virtual const char* GetKeyAsString(const char* Tag, const char* Key, - const char* Default) const = 0; - virtual int GetKeyAsInt(const char* Tag, const char* Key, - const int Default) const = 0; - virtual float GetKeyAsFloat(const char* Tag, const char* Key, - const float Default) const = 0; - virtual bool GetKeyAsBool(const char* Tag, const char* Key, - const bool Default) const = 0; -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/Dialog.cpp b/project/jni/application/gemrb/gemrb/core/Dialog.cpp deleted file mode 100644 index a8399ee59..000000000 --- a/project/jni/application/gemrb/gemrb/core/Dialog.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "Dialog.h" - -#include "win32def.h" - -#include "GameScript/GameScript.h" - -Dialog::Dialog(void) -{ - TopLevelCount = 0; -} - -Dialog::~Dialog(void) -{ - if (initialStates) { - for (unsigned int i = 0; i < TopLevelCount; i++) { - if (initialStates[i]) { - FreeDialogState( initialStates[i] ); - } - } - free(initialStates); - } - if (Order) free(Order); -} - -DialogState* Dialog::GetState(unsigned int index) -{ - if (index >= TopLevelCount) { - return NULL; - } - return initialStates[index]; -} - -void Dialog::FreeDialogState(DialogState* ds) -{ - for (unsigned int i = 0; i < ds->transitionsCount; i++) { - DialogTransition *trans = ds->transitions[i]; - for (size_t j = 0; j < trans->actions.size(); ++j) - trans->actions[j]->Release(); - if (trans->condition) - delete trans->condition; - delete( trans ); - } - free( ds->transitions ); - if (ds->condition) { - delete ds->condition; - } - delete( ds ); -} - -int Dialog::FindFirstState(Scriptable* target) -{ - for (unsigned int i = 0; i < TopLevelCount; i++) { - Condition *cond = GetState( Order[i] )->condition; - if (cond && cond->Evaluate(target)) { - return Order[i]; - } - } - return -1; -} - -int Dialog::FindRandomState(Scriptable* target) -{ - unsigned int i; - unsigned int max = TopLevelCount; - if (!max) return -1; - unsigned int pick = rand()%max; - for (i=pick; i < max; i++) { - Condition *cond = GetState(i)->condition; - if (cond && cond->Evaluate(target)) { - return i; - } - } - for (i=0; i < pick; i++) { - Condition *cond = GetState(i)->condition; - if (cond && cond->Evaluate(target)) { - return i; - } - } - return -1; -} diff --git a/project/jni/application/gemrb/gemrb/core/Dialog.h b/project/jni/application/gemrb/gemrb/core/Dialog.h deleted file mode 100644 index 2b7e921c3..000000000 --- a/project/jni/application/gemrb/gemrb/core/Dialog.h +++ /dev/null @@ -1,83 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#ifndef DIALOG_H -#define DIALOG_H - -#include "exports.h" -#include "globals.h" - -#include - -#define IE_DLG_TR_TEXT 0x01 -#define IE_DLG_TR_TRIGGER 0x02 -#define IE_DLG_TR_ACTION 0x04 -#define IE_DLG_TR_FINAL 0x08 -#define IE_DLG_TR_JOURNAL 0x10 -#define IE_DLG_UNSOLVED 0x40 -#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; - ieStrRef journalStrRef; - Condition* condition; - std::vector actions; - ieResRef Dialog; - ieDword stateIndex; -}; - -struct DialogState { - ieStrRef StrRef; - DialogTransition** transitions; - unsigned int transitionsCount; - Condition* condition; - unsigned int weight; -}; - -class GEM_EXPORT Dialog { -public: - Dialog(void); - ~Dialog(void); -private: - void FreeDialogState(DialogState* ds); -public: - void AddState(DialogState* ds); - DialogState* GetState(unsigned int index); - int FindFirstState(Scriptable* target); - int FindRandomState(Scriptable* target); - - void Release() - { - delete this; - } -public: - ieResRef ResRef; - ieDword Flags; //freeze flags (bg2) - unsigned int TopLevelCount; - ieDword* Order; - DialogState** initialStates; -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/DialogHandler.cpp b/project/jni/application/gemrb/gemrb/core/DialogHandler.cpp deleted file mode 100644 index c2877defb..000000000 --- a/project/jni/application/gemrb/gemrb/core/DialogHandler.cpp +++ /dev/null @@ -1,487 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "DialogHandler.h" - -#include "strrefs.h" - -#include "DialogMgr.h" -#include "DisplayMessage.h" -#include "Game.h" -#include "GameData.h" -#include "GlobalTimer.h" -#include "PluginMgr.h" -#include "ScriptEngine.h" -#include "TableMgr.h" -#include "Video.h" -#include "GameScript/GameScript.h" -#include "GUI/GameControl.h" -#include "GUI/TextArea.h" - -//translate section values (journal, solved, unsolved, user) -static int sectionMap[4]={4,1,2,0}; -static const int bg2Sections[4]={4,1,2,0}; -static const int noSections[4]={0,0,0,0}; - -DialogHandler::DialogHandler(void) -{ - dlg = NULL; - targetID = 0; - originalTargetID = 0; - speakerID = 0; - if (core->HasFeature(GF_JOURNAL_HAS_SECTIONS) ) { - memcpy(sectionMap, bg2Sections, sizeof(sectionMap) ); - } else { - memcpy(sectionMap, noSections, sizeof(sectionMap) ); - } -} - -DialogHandler::~DialogHandler(void) -{ - if (dlg) { - delete dlg; - } -} - -//Try to start dialogue between two actors (one of them could be inanimate) -bool DialogHandler::InitDialog(Scriptable* spk, Scriptable* tgt, const char* dlgref) -{ - if (dlg) { - delete dlg; - dlg = NULL; - } - - PluginHolder dm(IE_DLG_CLASS_ID); - dm->Open(gamedata->GetResource(dlgref, IE_DLG_CLASS_ID)); - dlg = dm->GetDialog(); - - if (!dlg) { - printMessage("GameControl", "Cannot start dialog: %s\n", LIGHT_RED, dlgref); - return false; - } - - strnlwrcpy(dlg->ResRef, dlgref, 8); //this isn't handled by GetDialog??? - - //target is here because it could be changed when a dialog runs onto - //and external link, we need to find the new target (whose dialog was - //linked to) - - Actor *oldTarget = GetActorByGlobalID(targetID); - speakerID = spk->GetGlobalID(); - targetID = tgt->GetGlobalID(); - if (!originalTargetID) originalTargetID = tgt->GetGlobalID(); - if (tgt->Type==ST_ACTOR) { - Actor *tar = (Actor *) tgt; - // TODO: verify - spk->LastTalker=targetID; - tar->LastTalker=speakerID; - tar->SetCircleSize(); - } - if (oldTarget) oldTarget->SetCircleSize(); - - GameControl *gc = core->GetGameControl(); - - if (!gc) - return false; - - //check if we are already in dialog - if (gc->GetDialogueFlags()&DF_IN_DIALOG) { - return true; - } - - int si = dlg->FindFirstState( tgt ); - if (si < 0) { - return false; - } - - //we need GUI for dialogs - //but the guiscript must be in control here - //gc->UnhideGUI(); - - //no exploring while in dialogue - 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; - tar->DialogInterrupt(); - } - - //allow mouse selection from dialog (even though screen is locked) - Video *video = core->GetVideoDriver(); - Region vp = video->GetViewport(); - video->SetMouseEnabled(true); - core->timer->SetMoveViewPort( tgt->Pos.x, tgt->Pos.y, 0, true ); - video->MoveViewportTo( tgt->Pos.x-vp.w/2, tgt->Pos.y-vp.h/2 ); - //there are 3 bits, if they are all unset, the dialog freezes scripts - if (!(dlg->Flags&7) ) { - gc->SetDialogueFlags(DF_FREEZE_SCRIPTS, BM_OR); - } - //opening control size to maximum, enabling dialog window - //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 true; -} - -/*try to break will only try to break it, false means unconditional stop*/ -void DialogHandler::EndDialog(bool try_to_break) -{ - if (try_to_break && (core->GetGameControl()->GetDialogueFlags()&DF_UNBREAKABLE) ) { - return; - } - - Actor *tmp = GetSpeaker(); - if (tmp) { - tmp->LeaveDialog(); - } - speakerID = 0; - Scriptable *tmp2 = GetTarget(); - if (tmp2 && tmp2->Type == ST_ACTOR) { - tmp = (Actor *)tmp2; - } else { - tmp = NULL; - } - if (tmp) { - tmp->LeaveDialog(); - } - targetID = 0; - if (tmp) tmp->SetCircleSize(); - originalTargetID = 0; - ds = NULL; - if (dlg) { - 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); - core->GetGameControl()->SetDialogueFlags(0, BM_SET); - core->SetEventFlag(EF_PORTRAIT); -} - - -void DialogHandler::DialogChoose(unsigned int choose) -{ - TextArea* ta = core->GetMessageTextArea(); - if (!ta) { - printMessage("GameControl","Dialog aborted???",LIGHT_RED); - EndDialog(); - return; - } - - Actor *speaker = GetSpeaker(); - if (!speaker) { - printMessage("GameControl","Speaker gone???",LIGHT_RED); - EndDialog(); - return; - } - - Scriptable *target = GetTarget(); - if (!target) { - printMessage("GameControl","Target gone???",LIGHT_RED); - EndDialog(); - return; - } - Actor *tgt = NULL; - if (target->Type == ST_ACTOR) { - tgt = (Actor *)target; - } - - Video *video = core->GetVideoDriver(); - Region vp = video->GetViewport(); - video->SetMouseEnabled(true); - core->timer->SetMoveViewPort( target->Pos.x, target->Pos.y, 0, true ); - video->MoveViewportTo( target->Pos.x-vp.w/2, target->Pos.y-vp.h/2 ); - - if (choose == (unsigned int) -1) { - //increasing talkcount after top level condition was determined - - int si = dlg->FindFirstState( tgt ); - if (si<0) { - EndDialog(); - return; - } - - if (tgt) { - if (core->GetGameControl()->GetDialogueFlags()&DF_TALKCOUNT) { - core->GetGameControl()->SetDialogueFlags(DF_TALKCOUNT, BM_NAND); - tgt->TalkCount++; - } else if (core->GetGameControl()->GetDialogueFlags()&DF_INTERACT) { - core->GetGameControl()->SetDialogueFlags(DF_INTERACT, BM_NAND); - tgt->InteractCount++; - } - } - ds = dlg->GetState( si ); - } else { - if (ds->transitionsCount <= choose) { - return; - } - - DialogTransition* tr = ds->transitions[choose]; - - ta->PopMinRow(); - - if (tr->Flags&IE_DLG_TR_JOURNAL) { - int Section = 0; - if (tr->Flags&IE_DLG_UNSOLVED) { - Section |= 1; - } - if (tr->Flags&IE_DLG_SOLVED) { - Section |= 2; - } - if (core->GetGame()->AddJournalEntry(tr->journalStrRef, sectionMap[Section], tr->Flags>>16) ) { - displaymsg->DisplayConstantString(STR_JOURNALCHANGE,0xffff00); - char *string = core->GetString( tr->journalStrRef ); - //cutting off the strings at the first crlf - char *poi = strchr(string,'\n'); - if (poi) { - *poi='\0'; - } - displaymsg->DisplayString( string ); - free( string ); - } - } - - if (tr->textStrRef != 0xffffffff) { - //allow_zero is for PST (deionarra's text) - displaymsg->DisplayStringName( (int) (tr->textStrRef), 0x8080FF, speaker, IE_STR_SOUND|IE_STR_SPEECH|IE_STR_ALLOW_ZERO); - if (core->HasFeature( GF_DIALOGUE_SCROLLS )) { - ta->AppendText( "", -1 ); - } - } - - if (tr->actions.size()) { - // does this belong here? we must clear actions somewhere before - // we start executing them (otherwise queued actions interfere) - // executing actions directly does not work, because dialog - // needs to end before final actions are executed due to - // actions making new dialogs! - if (target->Type == ST_ACTOR) ((Movable *)target)->ClearPath(); // fuzzie added this - target->ClearActions(); - - // 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]); - } - strcpy(buf, "SetInterrupt(TRUE)"); - target->AddAction( GenerateAction( buf ) ); - } - - int final_dialog = tr->Flags & IE_DLG_TR_FINAL; - - if (final_dialog) { - ta->SetMinRow( false ); - EndDialog(); - } - - if (final_dialog) { - return; - } - - // avoid problems when dhjollde.dlg tries starting a cutscene in the middle of a dialog - // (it seems harmless doing it in non-HoW too, since other versions would just break in such a situation) - core->SetCutSceneMode( false ); - - //displaying dialog for selected option - int si = tr->stateIndex; - //follow external linkage, if required - if (tr->Dialog[0] && strnicmp( tr->Dialog, dlg->ResRef, 8 )) { - //target should be recalculated! - tgt = NULL; - if (originalTargetID) { - // always try original target first (sometimes there are multiple - // actors with the same dialog in an area, we want to pick the one - // we were talking to) - tgt = GetActorByGlobalID(originalTargetID); - if (tgt && strnicmp( tgt->GetDialog(GD_NORMAL), tr->Dialog, 8 ) != 0) { - tgt = NULL; - } - } - if (!tgt) { - // then just search the current area for an actor with the dialog - tgt = target->GetCurrentArea()->GetActorByDialog(tr->Dialog); - } - if (!tgt) { - // try searching for banter dialogue: the original engine seems to - // happily let you randomly switch between normal and banter dialogs - - // TODO: work out if this should go somewhere more central (such - // as GetActorByDialog), or if there's a less awful way to do this - // (we could cache the entries, for example) - // TODO: fix for ToB (see also the Interact action) - AutoTable pdtable("interdia"); - if (pdtable) { - int row = pdtable->FindTableValue( pdtable->GetColumnIndex("FILE"), tr->Dialog ); - tgt = target->GetCurrentArea()->GetActorByScriptName(pdtable->GetRowName(row)); - } - } - target = tgt; - if (!target) { - printMessage("Dialog","Can't redirect dialog\n",YELLOW); - ta->SetMinRow( false ); - EndDialog(); - return; - } - Actor *oldTarget = GetActorByGlobalID(targetID); - targetID = tgt->GetGlobalID(); - tgt->SetCircleSize(); - if (oldTarget) oldTarget->SetCircleSize(); - // we have to make a backup, tr->Dialog is freed - ieResRef tmpresref; - strnlwrcpy(tmpresref,tr->Dialog, 8); - /*if (target->GetInternalFlag()&IF_NOINT) { - // this whole check moved out of InitDialog by fuzzie, see comments - // for the IF_NOINT check in BeginDialog - displaymsg->DisplayConstantString(STR_TARGETBUSY,0xff0000); - ta->SetMinRow( false ); - EndDialog(); - return; - }*/ - if (!InitDialog( speaker, target, tmpresref)) { - // error was displayed by InitDialog - ta->SetMinRow( false ); - EndDialog(); - return; - } - } - ds = dlg->GetState( si ); - if (!ds) { - printMessage("Dialog","Can't find next dialog\n",YELLOW); - ta->SetMinRow( false ); - EndDialog(); - return; - } - } - //displaying npc text - displaymsg->DisplayStringName( ds->StrRef, 0x70FF70, target, IE_STR_SOUND|IE_STR_SPEECH); - //adding a gap between options and npc text - ta->AppendText("",-1); - int i; - int idx = 0; - ta->SetMinRow( true ); - //first looking for a 'continue' opportunity, the order is descending (a la IE) - unsigned int x = ds->transitionsCount; - while(x--) { - if (ds->transitions[x]->Flags & IE_DLG_TR_FINAL) { - continue; - } - if (ds->transitions[x]->textStrRef != 0xffffffff) { - continue; - } - if (ds->transitions[x]->Flags & IE_DLG_TR_TRIGGER) { - if (ds->transitions[x]->condition && - !ds->transitions[x]->condition->Evaluate(target)) { - continue; - } - } - core->GetDictionary()->SetAt("DialogOption",x); - core->GetGameControl()->SetDialogueFlags(DF_OPENCONTINUEWINDOW, BM_OR); - goto end_of_choose; - } - for (x = 0; x < ds->transitionsCount; x++) { - if (ds->transitions[x]->Flags & IE_DLG_TR_TRIGGER) { - if (ds->transitions[x]->condition && - !ds->transitions[x]->condition->Evaluate(target)) { - continue; - } - } - idx++; - if (ds->transitions[x]->textStrRef == 0xffffffff) { - //dialogchoose should be set to x - //it isn't important which END option was chosen, as it ends - core->GetDictionary()->SetAt("DialogOption",x); - core->GetGameControl()->SetDialogueFlags(DF_OPENENDWINDOW, BM_OR); - } else { - char *string = ( char * ) malloc( 40 ); - sprintf( string, "[s=%d,ffffff,ff0000]%d - [p]", x, idx ); - i = ta->AppendText( string, -1 ); - free( string ); - string = core->GetString( ds->transitions[x]->textStrRef ); - ta->AppendText( string, i ); - free( string ); - ta->AppendText( "[/p][/s]", i ); - } - } - // this happens if a trigger isn't implemented or the dialog is wrong - if (!idx) { - printMessage("Dialog", "There were no valid dialog options!\n", YELLOW); - core->GetGameControl()->SetDialogueFlags(DF_OPENENDWINDOW, BM_OR); - } -end_of_choose: - //padding the rows so our text will be at the top - if (core->HasFeature( GF_DIALOGUE_SCROLLS )) { - ta->AppendText( "", -1 ); - } - else { - ta->PadMinRow(); - } -} - -// TODO: duplicate of the one in GameControl -Actor *DialogHandler::GetActorByGlobalID(ieDword ID) -{ - if (!ID) - return NULL; - Game* game = core->GetGame(); - if (!game) - return NULL; - - Map* area = game->GetCurrentArea( ); - if (!area) - return NULL; - return area->GetActorByGlobalID(ID); -} - -Scriptable *DialogHandler::GetTarget() -{ - // TODO: area GetScriptableByGlobalID? - - if (!targetID) return NULL; - - Game *game = core->GetGame(); - if (!game) return NULL; - - Map *area = game->GetCurrentArea(); - if (!area) return NULL; - - Actor *actor = area->GetActorByGlobalID(targetID); - if (actor) return actor; - - Door *door = area->GetDoorByGlobalID(targetID); - if (door) return (Scriptable *)door; - Container *container = area->GetContainerByGlobalID(targetID); - if (container) return (Scriptable *)container; - InfoPoint *ip = area->GetInfoPointByGlobalID(targetID); - if (ip) return (Scriptable *)ip; - - return NULL; -} - -Actor *DialogHandler::GetSpeaker() -{ - return GetActorByGlobalID(speakerID); -} - diff --git a/project/jni/application/gemrb/gemrb/core/DialogHandler.h b/project/jni/application/gemrb/gemrb/core/DialogHandler.h deleted file mode 100644 index 8f80d147d..000000000 --- a/project/jni/application/gemrb/gemrb/core/DialogHandler.h +++ /dev/null @@ -1,51 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#ifndef DIALOGHANDLER_H -#define DIALOGHANDLER_H - -#include "exports.h" - -#include "Dialog.h" - -class GEM_EXPORT DialogHandler { -public: - DialogHandler(); - ~DialogHandler(); -private: - /** this function safely retrieves an Actor by ID */ - Actor *GetActorByGlobalID(ieDword ID); -private: - DialogState* ds; - Dialog* dlg; -public: - ieDword speakerID; - ieDword targetID; - ieDword originalTargetID; -public: - Scriptable *GetTarget(); - Actor *GetSpeaker(); - - bool InitDialog(Scriptable* speaker, Scriptable* target, const char* dlgref); - void EndDialog(bool try_to_break=false); - void DialogChoose(unsigned int choose); -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/DialogMgr.cpp b/project/jni/application/gemrb/gemrb/core/DialogMgr.cpp deleted file mode 100644 index bc68aa544..000000000 --- a/project/jni/application/gemrb/gemrb/core/DialogMgr.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "DialogMgr.h" - -DialogMgr::DialogMgr(void) -{ -} - -DialogMgr::~DialogMgr(void) -{ -} diff --git a/project/jni/application/gemrb/gemrb/core/DialogMgr.h b/project/jni/application/gemrb/gemrb/core/DialogMgr.h deleted file mode 100644 index be4128b31..000000000 --- a/project/jni/application/gemrb/gemrb/core/DialogMgr.h +++ /dev/null @@ -1,36 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#ifndef DIALOGMGR_H -#define DIALOGMGR_H - -#include "Dialog.h" -#include "Plugin.h" -#include "System/DataStream.h" - -class GEM_EXPORT DialogMgr : public Plugin { -public: - DialogMgr(void); - virtual ~DialogMgr(void); - virtual bool Open(DataStream* stream) = 0; - virtual Dialog* GetDialog() const = 0; -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/DisplayMessage.cpp b/project/jni/application/gemrb/gemrb/core/DisplayMessage.cpp deleted file mode 100644 index 26b016f20..000000000 --- a/project/jni/application/gemrb/gemrb/core/DisplayMessage.cpp +++ /dev/null @@ -1,240 +0,0 @@ -/* 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 "DisplayMessage.h" - -#include "strrefs.h" - -#include "Interface.h" -#include "TableMgr.h" -#include "GUI/Label.h" -#include "GUI/TextArea.h" -#include "Scriptable/Actor.h" - -GEM_EXPORT DisplayMessage * displaymsg; - -static int strref_table[STRREF_COUNT]; - -#define PALSIZE 8 -static Color ActorColor[PALSIZE]; -static const char* DisplayFormatName = "[color=%06X]%s - [/color][p][color=%06X]%s[/color][/p]"; -static const char* DisplayFormatAction = "[color=%06X]%s - [/color][p][color=%06X]%s %s[/color][/p]"; -static const char* DisplayFormat = "[/color][p][color=%06X]%s[/color][/p]"; -static const char* DisplayFormatValue = "[/color][p][color=%06X]%s: %d[/color][/p]"; -static const char* DisplayFormatNameString = "[color=%06X]%s - [/color][p][color=%06X]%s: %s[/color][/p]"; - -DisplayMessage::DisplayMessage(void) { - ReadStrrefs(); -} - -bool DisplayMessage::ReadStrrefs() -{ - int i; - memset(strref_table,-1,sizeof(strref_table) ); - AutoTable tab("strings"); - if (!tab) { - return false; - } - for(i=0;iQueryField(i,0)); - } - return true; -} - -void DisplayMessage::DisplayString(const char* Text, Scriptable *target) const -{ - Label *l = core->GetMessageLabel(); - if (l) { - l->SetText(Text); - } - TextArea *ta = core->GetMessageTextArea(); - if (ta) { - ta->AppendText( Text, -1 ); - } else { - if(target) { - char *tmp = strdup(Text); - - target->DisplayHeadText(tmp); - } - } -} - -ieStrRef DisplayMessage::GetStringReference(int stridx) const -{ - return strref_table[stridx]; -} - -bool DisplayMessage::HasStringReference(int stridx) const -{ - return strref_table[stridx] != -1; -} - -unsigned int DisplayMessage::GetSpeakerColor(const char *&name, const Scriptable *&speaker) const -{ - unsigned int speaker_color; - - if(!speaker) return 0; - switch (speaker->Type) { - case ST_ACTOR: - name = speaker->GetName(-1); - core->GetPalette( ((Actor *) speaker)->GetStat(IE_MAJOR_COLOR) & 0xFF, PALSIZE, ActorColor ); - 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( speaker->DialogName ); - speaker_color = 0xc0c0c0; - break; - default: - name = ""; - speaker_color = 0x800000; - break; - } - return speaker_color; -} - - -//simply displaying a constant string -void DisplayMessage::DisplayConstantString(int stridx, unsigned int color, Scriptable *target) const -{ - if (stridx<0) return; - char* text = core->GetString( strref_table[stridx], IE_STR_SOUND ); - DisplayString(text, color, target); - core->FreeString(text); -} - -void DisplayMessage::DisplayString(int stridx, unsigned int color, ieDword flags) const -{ - if (stridx<0) return; - char* text = core->GetString( stridx, flags); - DisplayString(text, color, NULL); - core->FreeString(text); -} - -void DisplayMessage::DisplayString(const char *text, unsigned int color, Scriptable *target) const -{ - if (!text) return; - int newlen = (int)(strlen( DisplayFormat) + strlen( text ) + 12); - char* newstr = ( char* ) malloc( newlen ); - snprintf( newstr, newlen, DisplayFormat, color, text ); - DisplayString( newstr, target ); - free( newstr ); -} - -// String format is -// blah : whatever -void DisplayMessage::DisplayConstantStringValue(int stridx, unsigned int color, ieDword value) const -{ - if (stridx<0) return; - char* text = core->GetString( strref_table[stridx], IE_STR_SOUND ); - int newlen = (int)(strlen( DisplayFormat ) + strlen( text ) + 28); - char* newstr = ( char* ) malloc( newlen ); - snprintf( newstr, newlen, DisplayFormatValue, color, text, (int) value ); - core->FreeString( text ); - DisplayString( newstr ); - free( newstr ); -} - -// String format is -// - blah blah : whatever -void DisplayMessage::DisplayConstantStringNameString(int stridx, unsigned int color, int stridx2, const Scriptable *actor) const -{ - unsigned int actor_color; - const char *name = 0; - - if (stridx<0) return; - actor_color = GetSpeakerColor(name, actor); - char* text = core->GetString( strref_table[stridx], IE_STR_SOUND ); - char* text2 = core->GetString( strref_table[stridx2], IE_STR_SOUND ); - int newlen = (int)(strlen( DisplayFormat ) + strlen(name) + strlen( text ) + strlen(text2) + 20); - char* newstr = ( char* ) malloc( newlen ); - if (strlen(text2)) { - snprintf( newstr, newlen, DisplayFormatNameString, actor_color, name, color, text, text2 ); - } else { - snprintf( newstr, newlen, DisplayFormatName, color, name, color, text ); - } - core->FreeString( text ); - core->FreeString( text2 ); - DisplayString( newstr ); - free( newstr ); -} - -// String format is -// - blah blah -void DisplayMessage::DisplayConstantStringName(int stridx, unsigned int color, const Scriptable *speaker) const -{ - if (stridx<0) return; - if(!speaker) return; - - char* text = core->GetString( strref_table[stridx], IE_STR_SOUND|IE_STR_SPEECH ); - DisplayStringName(text, color, speaker); - core->FreeString(text); -} - -// String format is -// - blah blah -void DisplayMessage::DisplayConstantStringAction(int stridx, unsigned int color, const Scriptable *attacker, const Scriptable *target) const -{ - unsigned int attacker_color; - const char *name1 = 0; - const char *name2 = 0; - - if (stridx<0) return; - - GetSpeakerColor(name2, target); - attacker_color = GetSpeakerColor(name1, attacker); - - char* text = core->GetString( strref_table[stridx], IE_STR_SOUND|IE_STR_SPEECH ); - int newlen = (int)(strlen( DisplayFormatAction ) + strlen( name1 ) + - + strlen( name2 ) + strlen( text ) + 18); - char* newstr = ( char* ) malloc( newlen ); - snprintf( newstr, newlen, DisplayFormatAction, attacker_color, name1, color, - text, name2); - core->FreeString( text ); - DisplayString( newstr ); - free( newstr ); -} - -void DisplayMessage::DisplayStringName(int stridx, unsigned int color, const Scriptable *speaker, ieDword flags) const -{ - if (stridx<0) return; - - char* text = core->GetString( stridx, flags); - DisplayStringName(text, color, speaker); - core->FreeString( text ); -} - -void DisplayMessage::DisplayStringName(const char *text, unsigned int color, const Scriptable *speaker) const -{ - unsigned int speaker_color; - const char *name = 0; - - if (!text) return; - speaker_color = GetSpeakerColor(name, speaker); - - //FIXME: what happens if there is no name? - if (name) { - int newlen = (int)(strlen( DisplayFormatName ) + strlen( name ) + - + strlen( text ) + 18); - char* newstr = ( char* ) malloc( newlen ); - snprintf( newstr, newlen, DisplayFormatName, speaker_color, name, color, text ); - DisplayString( newstr ); - free( newstr ); - } -} diff --git a/project/jni/application/gemrb/gemrb/core/DisplayMessage.h b/project/jni/application/gemrb/gemrb/core/DisplayMessage.h deleted file mode 100644 index 02a6d48ab..000000000 --- a/project/jni/application/gemrb/gemrb/core/DisplayMessage.h +++ /dev/null @@ -1,73 +0,0 @@ -/* 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. -* -* -*/ - -/** - * @file DisplayMessage.h - * Declaration of the DisplayMessage class used for displaying messages in - * game message window - */ - -#ifndef DISPLAYMESSAGE_H -#define DISPLAYMESSAGE_H - -#include "exports.h" -#include "ie_types.h" - -#include - -class Scriptable; - -class GEM_EXPORT DisplayMessage -{ -private: - bool ReadStrrefs(); - -public: - DisplayMessage(void); - - /** returns a string reference from a string reference index constant */ - ieStrRef GetStringReference(int stridx) const; - /** returns true if a string reference for a string reference index constant exists */ - bool HasStringReference(int stridx) const; - /** returns the speaker's color and name */ - unsigned int GetSpeakerColor(const char *&name, const Scriptable *&speaker) const; - /** displays any string in the textarea */ - void DisplayString(const char *txt, Scriptable *speaker=NULL) const; - /** displays a string constant in the textarea */ - void DisplayConstantString(int stridx, unsigned int color, Scriptable *speaker=NULL) const; - /** displays actor name - action : parameter */ - void DisplayConstantStringNameString(int stridx, unsigned int color, int stridx2, const Scriptable *actor) const; - /** displays a string constant followed by a number in the textarea */ - void DisplayConstantStringValue(int stridx, unsigned int color, ieDword value) const; - /** displays a string constant in the textarea, starting with speaker's name */ - void DisplayConstantStringName(int stridx, unsigned int color, const Scriptable *speaker) const; - /** displays a string constant in the textarea, starting with actor, and ending with target */ - void DisplayConstantStringAction(int stridx, unsigned int color, const Scriptable *actor, const Scriptable *target) const; - /** displays a string in the textarea */ - void DisplayString(int stridx, unsigned int color, ieDword flags) const; - void DisplayString(const char *text, unsigned int color, Scriptable *target) const; - /** displays a string in the textarea, starting with speaker's name */ - void DisplayStringName(int stridx, unsigned int color, const Scriptable *speaker, ieDword flags) const; - void DisplayStringName(const char *text, unsigned int color, const Scriptable *speaker) const; -}; - -extern GEM_EXPORT DisplayMessage * displaymsg; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/Effect.h b/project/jni/application/gemrb/gemrb/core/Effect.h deleted file mode 100644 index 400c6bcbd..000000000 --- a/project/jni/application/gemrb/gemrb/core/Effect.h +++ /dev/null @@ -1,139 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -/** - * @file Effect.h - * Declares Effect class implementing spell and spell-like effects - * and related defines - */ - -#ifndef EFFECT_H -#define EFFECT_H - -#include "ie_types.h" - -#include "Region.h" - -class Actor; - -//local variables in creatures are stored in fake opcodes -#define FAKE_VARIABLE_OPCODE 187 -#define FAKE_VARIABLE_MARKER 1 - -// Effect target types -#define FX_TARGET_UNKNOWN 0 -#define FX_TARGET_SELF 1 -#define FX_TARGET_PRESET 2 -#define FX_TARGET_PARTY 3 -#define FX_TARGET_ALL 4 -#define FX_TARGET_ALL_BUT_PARTY 5 -#define FX_TARGET_OWN_SIDE 6 -#define FX_TARGET_OTHER_SIDE 7 -#define FX_TARGET_ALL_BUT_SELF 8 -#define FX_TARGET_ORIGINAL 9 - -// Effect duration/timing types -#define FX_DURATION_INSTANT_LIMITED 0 -#define FX_DURATION_INSTANT_PERMANENT 1 -#define FX_DURATION_INSTANT_WHILE_EQUIPPED 2 -#define FX_DURATION_DELAY_LIMITED 3 //this contains a relative onset time (delay) also used as duration, transforms to 6 when applied -#define FX_DURATION_DELAY_PERMANENT 4 //this transforms to 9 (i guess) -#define FX_DURATION_DELAY_UNSAVED 5 //this transforms to 8 -#define FX_DURATION_DELAY_LIMITED_PENDING 6 //this contains an absolute onset time and a duration -#define FX_DURATION_AFTER_EXPIRES 7 //this is a delayed non permanent effect (resolves to JUST_EXPIRED) -#define FX_DURATION_PERMANENT_UNSAVED 8 -#define FX_DURATION_INSTANT_PERMANENT_AFTER_BONUSES 9//this is a special permanent -#define FX_DURATION_JUST_EXPIRED 10 -#define MAX_TIMING_MODE 11 -#define FX_DURATION_ABSOLUTE 0x1000 - -// Effect resistance types -#define FX_NO_RESIST_NO_DISPEL 0 -#define FX_CAN_RESIST_CAN_DISPEL 1 -//#define FX_CAN_RESIST_NO_DISPEL 2 //same as 0 (not resistable, not dispellable) -#define FX_NO_RESIST_CAN_DISPEL 3 -#define FX_CAN_DISPEL 1 -#define FX_CAN_RESIST 3 - -/** - * @class Effect - * Structure holding information about single spell or spell-like effect. - */ - -// the same as ITMFeature and SPLFeature -struct Effect { - ieDword Opcode; - ieDword Target; - ieDword Power; - ieDword Parameter1; - ieDword Parameter2; - ieWord TimingMode; //0x1000 -- no need of conversion - ieWord unknown2; - ieDword Resistance; - ieDword Duration; - ieWord Probability1; - ieWord Probability2; - //keep these four in one bunch, VariableName will - //spread across them - ieResRef Resource; - ieResRef Resource2; //vvc in a lot of effects - ieResRef Resource3; - ieResRef Resource4; - ieDword DiceThrown; - ieDword DiceSides; - ieDword SavingThrowType; - ieDword SavingThrowBonus; - ieWord IsVariable; - ieWord IsSaveForHalfDamage; - - // EFF V2.0 fields: - ieDword PrimaryType; //school - ieDword MinAffectedLevel; - ieDword MaxAffectedLevel; - ieDword Parameter3; - ieDword Parameter4; - ieDword PosX, PosY; - ieDword SourceType; //1-item, 2-spell - ieResRef Source; - ieDword SourceFlags; - ieDword Projectile; //9c - ieDwordSigned InventorySlot; //a0 - //Original engine had a VariableName here, but it is stored in the resource fields - ieDword CasterLevel; //c4 in both - ieDword FirstApply; //c8 in bg2, cc in iwd2 - ieDword SecondaryType; - ieDword SecondaryDelay; //still not sure about this - ieDword CasterID; //10c in bg2 (not saved?) - // These are not in the IE files, but are our precomputed values - ieDword random_value; -public: - //don't modify position in case it was already set - void SetPosition(const Point &p) { - if(PosX==0xffffffff && PosY==0xffffffff) { - PosX=p.x; - PosY=p.y; - } - } -}; - -// FIXME: what about area spells? They can have map & coordinates as target -//void AddEffect(Effect* fx, Actor* self, Actor* pretarget); - -#endif // ! EFFECT_H diff --git a/project/jni/application/gemrb/gemrb/core/EffectMgr.cpp b/project/jni/application/gemrb/gemrb/core/EffectMgr.cpp deleted file mode 100644 index 7ca50f42e..000000000 --- a/project/jni/application/gemrb/gemrb/core/EffectMgr.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "EffectMgr.h" - -EffectMgr::EffectMgr(void) -{ -} - -EffectMgr::~EffectMgr(void) -{ -} diff --git a/project/jni/application/gemrb/gemrb/core/EffectMgr.h b/project/jni/application/gemrb/gemrb/core/EffectMgr.h deleted file mode 100644 index 689651c55..000000000 --- a/project/jni/application/gemrb/gemrb/core/EffectMgr.h +++ /dev/null @@ -1,56 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -/** - * @file EffectMgr.h - * Declares EffectMgr class, loader for Effect objects - * @author The GemRB Project - */ - - -#ifndef EFFECTMGR_H -#define EFFECTMGR_H - -#include "Effect.h" -#include "Plugin.h" -#include "System/DataStream.h" - -/** - * @class EffectMgr - * Abstract loader for Effect objects - */ - -class GEM_EXPORT EffectMgr : public Plugin { -public: - EffectMgr(void); - virtual ~EffectMgr(void); - virtual bool Open(DataStream* stream, bool autoFree = true) = 0; - - /** Fills fx with Effect data loaded from the stream */ - virtual Effect* GetEffect(Effect *fx) = 0; - /** Fills fx with Effect v1 data loaded from the stream*/ - virtual Effect* GetEffectV1(Effect *fx) = 0; - /** Fills fx with Effect v2.0 data loaded from the stream*/ - virtual Effect* GetEffectV20(Effect *fx) = 0; - /** Fills the stream with Effect v2 data loaded from the effect*/ - virtual void PutEffectV2(DataStream *stream, const Effect *fx) = 0; -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/EffectQueue.cpp b/project/jni/application/gemrb/gemrb/core/EffectQueue.cpp deleted file mode 100644 index 878ee02c5..000000000 --- a/project/jni/application/gemrb/gemrb/core/EffectQueue.cpp +++ /dev/null @@ -1,1960 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "EffectQueue.h" - -#include "DisplayMessage.h" -#include "Effect.h" -#include "Game.h" -#include "Interface.h" -#include "Map.h" -#include "SymbolMgr.h" -#include "Scriptable/Actor.h" -#include "Spell.h" //needs for the source flags bitfield -#include "TableMgr.h" - -#include - -static struct { - const char* Name; - EffectFunction Function; - int Strref; - int Flags; -} Opcodes[MAX_EFFECTS]; - -static int initialized = 0; -static EffectDesc *effectnames = NULL; -static int effectnames_count = 0; -static int pstflags = false; - -bool EffectQueue::match_ids(Actor *target, int table, ieDword value) -{ - if( value == 0) { - return true; - } - - int a, stat; - - switch (table) { - 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; - case 5: //CLASS - stat = IE_CLASS; break; - case 6: //SPECIFIC - stat = IE_SPECIFIC; break; - case 7: //GENDER - stat = IE_SEX; break; - case 8: //ALIGNMENT - stat = target->GetStat(IE_ALIGNMENT); - a = value&15; - if( a) { - if( a != ( stat & 15 )) { - return false; - } - } - a = value & 0xf0; - if( a) { - if( a != ( stat & 0xf0 )) { - return false; - } - } - return true; - default: - return false; - } - if( target->GetStat(stat)==value) { - return true; - } - return false; -} - -static const bool fx_instant[MAX_TIMING_MODE]={true,true,true,false,false,false,false,false,true,true,true}; - -static inline bool IsInstant(ieByte timingmode) -{ - if( timingmode>=MAX_TIMING_MODE) return false; - return fx_instant[timingmode]; -} - -static const bool fx_equipped[MAX_TIMING_MODE]={false,false,true,false,false,true,false,false,true,false,false}; - -static inline bool IsEquipped(ieByte timingmode) -{ - if( timingmode>=MAX_TIMING_MODE) return false; - return fx_equipped[timingmode]; -} - -// 0 1 2 3 4 5 6 7 8 9 10 -static const bool fx_relative[MAX_TIMING_MODE]={true,false,false,true,true,true,false,false,false,false,false}; - -static inline bool NeedPrepare(ieWord timingmode) -{ - if( timingmode>=MAX_TIMING_MODE) return false; - return fx_relative[timingmode]; -} - -#define INVALID -1 -#define PERMANENT 0 -#define DELAYED 1 -#define DURATION 2 - -static const int fx_prepared[MAX_TIMING_MODE]={DURATION,PERMANENT,PERMANENT,DELAYED, //0-3 -DELAYED,DELAYED,DELAYED,DELAYED,PERMANENT,PERMANENT,PERMANENT}; //4-7 - -static inline int DelayType(ieByte timingmode) -{ - if( timingmode>=MAX_TIMING_MODE) return INVALID; - return fx_prepared[timingmode]; -} - -//which effects are removable -static const bool fx_removable[MAX_TIMING_MODE]={true,true,false,true,true,false,true,true,false,false,true}; - -static inline int IsRemovable(ieByte timingmode) -{ - if( timingmode>=MAX_TIMING_MODE) return INVALID; - return fx_removable[timingmode]; -} - -//change the timing method after the effect triggered -static const ieByte fx_triggered[MAX_TIMING_MODE]={FX_DURATION_JUST_EXPIRED,FX_DURATION_INSTANT_PERMANENT,//0,1 -FX_DURATION_INSTANT_WHILE_EQUIPPED,FX_DURATION_DELAY_LIMITED_PENDING,//2,3 -FX_DURATION_AFTER_EXPIRES,FX_DURATION_PERMANENT_UNSAVED, //4,5 -FX_DURATION_INSTANT_LIMITED,FX_DURATION_JUST_EXPIRED,FX_DURATION_PERMANENT_UNSAVED,//6,8 -FX_DURATION_INSTANT_PERMANENT_AFTER_BONUSES,FX_DURATION_JUST_EXPIRED};//9,10 - -//change the timing method for effect that should trigger after this effect expired -static const ieDword fx_to_delayed[]={FX_DURATION_JUST_EXPIRED,FX_DURATION_JUST_EXPIRED, -FX_DURATION_PERMANENT_UNSAVED,FX_DURATION_DELAY_LIMITED_PENDING, -FX_DURATION_AFTER_EXPIRES,FX_DURATION_PERMANENT_UNSAVED, //4,5 -FX_DURATION_JUST_EXPIRED,FX_DURATION_JUST_EXPIRED,FX_DURATION_JUST_EXPIRED,//6,8 -FX_DURATION_JUST_EXPIRED,FX_DURATION_JUST_EXPIRED};//9,10 - -static inline ieByte TriggeredEffect(ieByte timingmode) -{ - if( timingmode>=MAX_TIMING_MODE) return false; - return fx_triggered[timingmode]; -} - -static int compare_effects(const void *a, const void *b) -{ - return stricmp(((EffectRef *) a)->Name,((EffectRef *) b)->Name); -} - -static int find_effect(const void *a, const void *b) -{ - return stricmp((const char *) a,((const EffectRef *) b)->Name); -} - -static EffectDesc* FindEffect(const char* effectname) -{ - if( !effectname || !effectnames) { - return NULL; - } - void *tmp = bsearch(effectname, effectnames, effectnames_count, sizeof(EffectDesc), find_effect); - if( !tmp) { - printMessage("EffectQueue", "Couldn't assign effect: %s\n", YELLOW, effectname); - } - return (EffectDesc *) tmp; -} - -static EffectRef fx_protection_from_display_string_ref = { "Protection:String", -1 }; - -static inline void ResolveEffectRef(EffectRef &effect_reference) -{ - if( effect_reference.opcode==-1) { - EffectDesc* ref = FindEffect(effect_reference.Name); - if( ref && ref->opcode>=0) { - effect_reference.opcode = ref->opcode; - return; - } - effect_reference.opcode = -2; - } -} - -bool Init_EffectQueue() -{ - int i; - - if( initialized) { - return true; - } - pstflags = !!core->HasFeature(GF_PST_STATE_FLAGS); - - memset( Opcodes, 0, sizeof( Opcodes ) ); - for(i=0;iLoadSymbol( "effects" ); - if( eT < 0) { - printMessage( "EffectQueue","A critical scripting file is missing!\n",LIGHT_RED ); - return false; - } - Holder effectsTable = core->GetSymbol( eT ); - if( !effectsTable) { - printMessage( "EffectQueue","A critical scripting file is damaged!\n",LIGHT_RED ); - return false; - } - - for (i = 0; i < MAX_EFFECTS; i++) { - const char* effectname = effectsTable->GetValue( i ); - if( efftextTable) { - int row = efftextTable->GetRowCount(); - while (row--) { - const char* ret = efftextTable->GetRowName( row ); - long val; - if( valid_number( ret, val ) && (i == val) ) { - Opcodes[i].Strref = atoi( efftextTable->QueryField( row, 1 ) ); - } - } - } - - 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]!='*') { - error("EffectQueue", "Clashing Opcodes FN: %d vs. %d, %s\n", i, poi->opcode, effectname); - } - poi->opcode = i; - } - //print("-------- FN: %d, %s\n", i, effectname); - } - core->DelSymbol( eT ); - - return true; -} - -void EffectQueue_ReleaseMemory() -{ - if( effectnames) { - free (effectnames); - } - effectnames_count = 0; - effectnames = NULL; -} - -void EffectQueue_RegisterOpcodes(int count, const EffectDesc* opcodes) -{ - if( ! effectnames) { - effectnames = (EffectDesc*) malloc( (count+1) * sizeof( EffectDesc ) ); - } else { - effectnames = (EffectDesc*) realloc( effectnames, (effectnames_count + count + 1) * sizeof( EffectDesc ) ); - } - - 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(EffectDesc), compare_effects); -} - -EffectQueue::EffectQueue() -{ - Owner = NULL; -} - -EffectQueue::~EffectQueue() -{ - std::list< Effect* >::iterator f; - - for ( f = effects.begin(); f != effects.end(); f++ ) { - delete (*f); - } -} - -Effect *EffectQueue::CreateEffect(ieDword opcode, ieDword param1, ieDword param2, ieWord timing) -{ - if( opcode==0xffffffff) { - return NULL; - } - Effect *fx = new Effect(); - if( !fx) { - return NULL; - } - memset(fx,0,sizeof(Effect)); - fx->Target = FX_TARGET_SELF; - fx->Opcode = opcode; - //probability2 is the low number (by effectqueue 331) - fx->Probability1 = 100; - fx->Parameter1 = param1; - fx->Parameter2 = param2; - fx->TimingMode = timing; - fx->PosX = 0xffffffff; - fx->PosY = 0xffffffff; - return fx; -} - -//return the count of effects with matching parameters -//useful for effects where there is no separate stat to see -ieDword EffectQueue::CountEffects(EffectRef &effect_reference, ieDword param1, ieDword param2, const char *resource) const -{ - ResolveEffectRef(effect_reference); - if( effect_reference.opcode<0) { - return 0; - } - return CountEffects(effect_reference.opcode, param1, param2, resource); -} - -//Change the location of an existing effect -//this is used when some external code needs to adjust the effect's location -//used when the gui sets the effect's final target -void EffectQueue::ModifyEffectPoint(EffectRef &effect_reference, ieDword x, ieDword y) const -{ - ResolveEffectRef(effect_reference); - if( effect_reference.opcode<0) { - return; - } - ModifyEffectPoint(effect_reference.opcode, x, y); -} - -Effect *EffectQueue::CreateEffect(EffectRef &effect_reference, ieDword param1, ieDword param2, ieWord timing) -{ - ResolveEffectRef(effect_reference); - if( effect_reference.opcode<0) { - return NULL; - } - return CreateEffect(effect_reference.opcode, param1, param2, timing); -} - -//copies the whole effectqueue (area projectiles use it) -EffectQueue *EffectQueue::CopySelf() const -{ - EffectQueue *effects; - - effects = new EffectQueue(); - std::list< Effect* >::const_iterator fxit = GetFirstEffect(); - Effect *fx; - - while( (fx = GetNextEffect(fxit))) { - effects->AddEffect(fx, false); - } - effects->SetOwner(GetOwner()); - return effects; -} - -//create a new effect with most of the characteristics of the old effect -//only opcode and parameters are changed -//This is used mostly inside effects, when an effect needs to spawn -//other effects with the same coordinates, source, duration, etc. -Effect *EffectQueue::CreateEffectCopy(Effect *oldfx, ieDword opcode, ieDword param1, ieDword param2) -{ - if( opcode==0xffffffff) { - return NULL; - } - Effect *fx = new Effect(); - if( !fx) { - return NULL; - } - memcpy(fx,oldfx,sizeof(Effect) ); - fx->Opcode=opcode; - fx->Parameter1=param1; - fx->Parameter2=param2; - return fx; -} - -Effect *EffectQueue::CreateEffectCopy(Effect *oldfx, EffectRef &effect_reference, ieDword param1, ieDword param2) -{ - ResolveEffectRef(effect_reference); - if( effect_reference.opcode<0) { - return NULL; - } - return CreateEffectCopy(oldfx, effect_reference.opcode, param1, param2); -} - -static EffectRef fx_unsummon_creature_ref = { "UnsummonCreature", -1 }; - -Effect *EffectQueue::CreateUnsummonEffect(Effect *fx) -{ - Effect *newfx = NULL; - if( (fx->TimingMode&0xff) == FX_DURATION_INSTANT_LIMITED) { - newfx = CreateEffectCopy(fx, fx_unsummon_creature_ref, 0, 0); - newfx->TimingMode = FX_DURATION_DELAY_PERMANENT; - if( newfx->Resource3[0]) { - strnuprcpy(newfx->Resource,newfx->Resource3, sizeof(ieResRef)-1 ); - } else { - strnuprcpy(newfx->Resource,"SPGFLSH1", sizeof(ieResRef)-1 ); - } - if( fx->TimingMode == FX_DURATION_ABSOLUTE) { - //unprepare duration - newfx->Duration = (newfx->Duration-core->GetGame()->GameTime)/AI_UPDATE_TIME; - } - } - - return newfx; -} - -void EffectQueue::AddEffect(Effect* fx, bool insert) -{ - Effect* new_fx = new Effect; - memcpy( new_fx, fx, sizeof( Effect ) ); - if( insert) { - effects.insert( effects.begin(), new_fx ); - } else { - effects.push_back( new_fx ); - } -} - -//This method can remove an effect described by a pointer to it, or -//an exact matching effect -bool EffectQueue::RemoveEffect(Effect* fx) -{ - int invariant_size = offsetof( Effect, random_value ); - - for (std::list< Effect* >::iterator f = effects.begin(); f != effects.end(); f++ ) { - Effect* fx2 = *f; - - if( (fx==fx2) || !memcmp( fx, fx2, invariant_size)) { - delete fx2; - effects.erase( f ); - return true; - } - } - return false; -} - -//this is where we reapply all effects when loading a saved game -//The effects are already in the fxqueue of the target -void EffectQueue::ApplyAllEffects(Actor* target) const -{ - std::list< Effect* >::const_iterator f; - for ( f = effects.begin(); f != effects.end(); f++ ) { - ApplyEffect( target, *f, 0 ); - } -} - -void EffectQueue::Cleanup() -{ - std::list< Effect* >::iterator f; - - for ( f = effects.begin(); f != effects.end(); ) { - if( (*f)->TimingMode == FX_DURATION_JUST_EXPIRED) { - delete *f; - effects.erase(f++); - } else { - f++; - } - } -} - -//Handle the target flag when the effect is applied first -int EffectQueue::AddEffect(Effect* fx, Scriptable* self, Actor* pretarget, const Point &dest) const -{ - int i; - Game *game; - Map *map; - int flg; - ieDword spec = 0; - Actor *st = (self && (self->Type==ST_ACTOR)) ?(Actor *) self:NULL; - Effect* new_fx; - - switch (fx->Target) { - case FX_TARGET_ORIGINAL: - fx->SetPosition(self->Pos); - - flg = ApplyEffect( st, fx, 1 ); - if( fx->TimingMode != FX_DURATION_JUST_EXPIRED) { - if( st) { - st->fxqueue.AddEffect( fx, flg==FX_INSERT ); - } - } - break; - case FX_TARGET_SELF: - fx->SetPosition(dest); - - flg = ApplyEffect( st, fx, 1 ); - if( fx->TimingMode != FX_DURATION_JUST_EXPIRED) { - if( st) { - st->fxqueue.AddEffect( fx, flg==FX_INSERT ); - } - } - break; - - case FX_TARGET_ALL_BUT_SELF: - new_fx = new Effect; - map=self->GetCurrentArea(); - i= map->GetActorCount(true); - while(i--) { - Actor* actor = map->GetActor( i, true ); - //don't pick ourselves - if( st==actor) { - continue; - } - memcpy( new_fx, fx, sizeof( Effect ) ); - new_fx->SetPosition(actor->Pos); - - flg = ApplyEffect( actor, new_fx, 1 ); - if( new_fx->TimingMode != FX_DURATION_JUST_EXPIRED) { - actor->fxqueue.AddEffect( new_fx, flg==FX_INSERT ); - } - } - delete new_fx; - flg = FX_APPLIED; - break; - - case FX_TARGET_OWN_SIDE: - if( !st || st->InParty) { - goto all_party; - } - map = self->GetCurrentArea(); - spec = st->GetStat(IE_SPECIFIC); - - new_fx = new Effect; - //GetActorCount(false) returns all nonparty critters - i = map->GetActorCount(false); - while(i--) { - Actor* actor = map->GetActor( i, false ); - if( actor->GetStat(IE_SPECIFIC)!=spec) { - continue; - } - memcpy( new_fx, fx, sizeof( Effect ) ); - new_fx->SetPosition(actor->Pos); - - flg = ApplyEffect( actor, new_fx, 1 ); - if( new_fx->TimingMode != FX_DURATION_JUST_EXPIRED) { - actor->fxqueue.AddEffect( new_fx, flg==FX_INSERT ); - } - } - delete new_fx; - flg = FX_APPLIED; - break; - case FX_TARGET_OTHER_SIDE: - if( !pretarget || pretarget->InParty) { - goto all_party; - } - map = self->GetCurrentArea(); - spec = pretarget->GetStat(IE_SPECIFIC); - - new_fx = new Effect; - //GetActorCount(false) returns all nonparty critters - i = map->GetActorCount(false); - while(i--) { - Actor* actor = map->GetActor( i, false ); - if( actor->GetStat(IE_SPECIFIC)!=spec) { - continue; - } - memcpy( new_fx, fx, sizeof( Effect ) ); - new_fx->SetPosition(actor->Pos); - - flg = ApplyEffect( actor, new_fx, 1 ); - //GetActorCount can now return all nonparty critters - if( new_fx->TimingMode != FX_DURATION_JUST_EXPIRED) { - actor->fxqueue.AddEffect( new_fx, flg==FX_INSERT ); - } - } - delete new_fx; - flg = FX_APPLIED; - break; - case FX_TARGET_PRESET: - fx->SetPosition(pretarget->Pos); - - flg = ApplyEffect( pretarget, fx, 1 ); - if( fx->TimingMode != FX_DURATION_JUST_EXPIRED) { - if( pretarget) { - pretarget->fxqueue.AddEffect( fx, flg==FX_INSERT ); - } - } - break; - - case FX_TARGET_PARTY: -all_party: - new_fx = new Effect; - game = core->GetGame(); - i = game->GetPartySize(false); - while(i--) { - Actor* actor = game->GetPC( i, false ); - memcpy( new_fx, fx, sizeof( Effect ) ); - new_fx->SetPosition(actor->Pos); - - flg = ApplyEffect( actor, new_fx, 1 ); - if( new_fx->TimingMode != FX_DURATION_JUST_EXPIRED) { - actor->fxqueue.AddEffect( new_fx, flg==FX_INSERT ); - } - } - delete new_fx; - flg = FX_APPLIED; - break; - - case FX_TARGET_ALL: - new_fx = new Effect; - map = self->GetCurrentArea(); - i = map->GetActorCount(true); - while(i--) { - Actor* actor = map->GetActor( i, true ); - memcpy( new_fx, fx, sizeof( Effect ) ); - new_fx->SetPosition(actor->Pos); - - flg = ApplyEffect( actor, new_fx, 1 ); - if( new_fx->TimingMode != FX_DURATION_JUST_EXPIRED) { - actor->fxqueue.AddEffect( new_fx, flg==FX_INSERT ); - } - } - delete new_fx; - flg = FX_APPLIED; - break; - - case FX_TARGET_ALL_BUT_PARTY: - new_fx = new Effect; - map = self->GetCurrentArea(); - i = map->GetActorCount(false); - while(i--) { - Actor* actor = map->GetActor( i, false ); - memcpy( new_fx, fx, sizeof( Effect ) ); - new_fx->SetPosition(actor->Pos); - - flg = ApplyEffect( actor, new_fx, 1 ); - //GetActorCount can now return all nonparty critters - if( new_fx->TimingMode != FX_DURATION_JUST_EXPIRED) { - actor->fxqueue.AddEffect( new_fx, flg==FX_INSERT ); - } - } - delete new_fx; - flg = FX_APPLIED; - break; - - case FX_TARGET_UNKNOWN: - default: - print( "Unknown FX target type: %d\n", fx->Target); - flg = FX_ABORT; - break; - } - - return flg; -} - -//this is where effects from spells first get in touch with the target -//the effects are currently NOT in the target's fxqueue, those that stick -//will get copied (hence the fxqueue.AddEffect call) -//if this returns FX_NOT_APPLIED, then the whole stack was resisted -//or expired -int EffectQueue::AddAllEffects(Actor* target, const Point &destination) const -{ - int res = FX_NOT_APPLIED; - // pre-roll dice for fx needing them and stow them in the effect - ieDword random_value = core->Roll( 1, 100, -1 ); - - if( target) { - target->RollSaves(); - } - std::list< Effect* >::const_iterator f; - for ( f = effects.begin(); f != effects.end(); f++ ) { - //handle resistances and saving throws here - (*f)->random_value = random_value; - //if applyeffect returns true, we stop adding the future effects - //this is to simulate iwd2's on the fly spell resistance - - int tmp = AddEffect(*f, Owner, target, destination); - //lets try without Owner, any crash? - //If yes, then try to fix the individual effect - //If you use target for Owner here, the wand in chateau irenicus will work - //the same way as Imoen's monster summoning, which is a BAD THING (TM) - //int tmp = AddEffect(*f, Owner?Owner:target, target, destination); - if( tmp == FX_ABORT) { - res = FX_NOT_APPLIED; - break; - } - if( tmp != FX_NOT_APPLIED) { - res = FX_APPLIED; - } - } - return res; -} - -//resisted effect based on level -static inline bool check_level(Actor *target, Effect *fx) -{ - //skip non level based effects - //check if an effect has no level based resistance, but instead the dice sizes/count - //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) ) { - if( memcmp(fx->Resource,"NEG",4) ) { - fx->IsSaveForHalfDamage=1; - } - } else { - if( (fx->Parameter2&3)==3) { - fx->IsSaveForHalfDamage=1; - } - } - return false; - } - //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; - } - - if( !target) { - return false; - } - if(fx->Target == FX_TARGET_SELF) { - return false; - } - - ieDword level = (ieDword) target->GetXPLevel( true ); - //return true if resisted - if (fx->MinAffectedLevel > 0 || fx->MaxAffectedLevel > 0) { - if (level < fx->MinAffectedLevel || level > fx->MaxAffectedLevel) { - return true; - } - } - return false; -} - -//roll for the effect probability, there is a high and a low treshold, the d100 -//roll should hit in the middle -static inline bool check_probability(Effect* fx) -{ - //watch for this, probability1 is the high number - //probability2 is the low number - //random value is 0-99 - if( fx->random_value<=fx->Probability2 || fx->random_value>fx->Probability1) { - return false; - } - return true; -} - -//immunity effects -static EffectRef fx_level_immunity_ref = { "Protection:Spelllevel", -1 }; -static EffectRef fx_opcode_immunity_ref = { "Protection:Opcode", -1 }; //bg2 -static EffectRef fx_opcode_immunity2_ref = { "Protection:Opcode2", -1 };//iwd -static EffectRef fx_spell_immunity_ref = { "Protection:Spell", -1 }; //bg2 -static EffectRef fx_spell_immunity2_ref = { "Protection:Spell2", -1 };//iwd -static EffectRef fx_store_spell_sequencer_ref = { "Sequencer:Store", -1 }; //bg2, works against sequencers -static EffectRef fx_school_immunity_ref = { "Protection:School", -1 }; -static EffectRef fx_secondary_type_immunity_ref = { "Protection:SecondaryType", -1 }; - -//decrementing immunity effects -static EffectRef fx_level_immunity_dec_ref = { "Protection:SpellLevelDec", -1 }; -static EffectRef fx_spell_immunity_dec_ref = { "Protection:SpellDec", -1 }; -static EffectRef fx_school_immunity_dec_ref = { "Protection:SchoolDec", -1 }; -static EffectRef fx_secondary_type_immunity_dec_ref = { "Protection:SecondaryTypeDec", -1 }; - -//bounce effects -static EffectRef fx_level_bounce_ref = { "Bounce:SpellLevel", -1 }; -//static EffectRef fx_opcode_bounce_ref = { "Bounce:Opcode", -1 }; -static EffectRef fx_spell_bounce_ref = { "Bounce:Spell", -1 }; -static EffectRef fx_school_bounce_ref = { "Bounce:School", -1 }; -static EffectRef fx_secondary_type_bounce_ref = { "Bounce:SecondaryType", -1 }; - -//decrementing bounce effects -static EffectRef fx_level_bounce_dec_ref = { "Bounce:SpellLevelDec", -1 }; -static EffectRef fx_spell_bounce_dec_ref = { "Bounce:SpellDec", -1 }; -static EffectRef fx_school_bounce_dec_ref = { "Bounce:SchoolDec", -1 }; -static EffectRef fx_secondary_type_bounce_dec_ref = { "Bounce:SecondaryTypeDec", -1 }; - -//spelltrap (multiple decrementing immunity) -static EffectRef fx_spelltrap = { "SpellTrap", -1 }; - -//this is for whole spell immunity/bounce -static inline void DecreaseEffect(Effect *efx) -{ - efx->Parameter1--; - if( (int) efx->Parameter1<1) { - //don't remove effects directly!!! - efx->TimingMode = FX_DURATION_JUST_EXPIRED; - } -} - -//lower decreasing immunities/bounces -static int check_type(Actor* actor, Effect* fx) -{ - //the protective effect (if any) - Effect *efx; - - ieDword bounce = actor->GetStat(IE_BOUNCE); - - //immunity checks -/*opcode immunity is in the per opcode checks - if( actor->fxqueue.HasEffectWithParam(fx_opcode_immunity_ref, fx->Opcode) ) { - return 0; - } - if( actor->fxqueue.HasEffectWithParam(fx_opcode_immunity2_ref, fx->Opcode) ) { - return 0; - } -*/ - //spell level immunity - if(fx->Power && actor->fxqueue.HasEffectWithParamPair(fx_level_immunity_ref, fx->Power, 0) ) { - return 0; - } - - //source immunity (spell name) - //if source is unspecified, don't resist it - if( fx->Source[0]) { - if( actor->fxqueue.HasEffectWithResource(fx_spell_immunity_ref, fx->Source) ) { - return 0; - } - if( actor->fxqueue.HasEffectWithResource(fx_spell_immunity2_ref, fx->Source) ) { - return 0; - } - if (actor->fxqueue.HasEffectWithResource(fx_store_spell_sequencer_ref, fx->Source) ) { - return 0; - } - } - - //primary type immunity (school) - if( fx->PrimaryType) { - if( actor->fxqueue.HasEffectWithParam(fx_school_immunity_ref, fx->PrimaryType)) { - return 0; - } - } - - //secondary type immunity (usage) - if( fx->SecondaryType) { - if( actor->fxqueue.HasEffectWithParam(fx_secondary_type_immunity_ref, fx->SecondaryType) ) { - return 0; - } - } - - //decrementing immunity checks - //decrementing level immunity - efx = actor->fxqueue.HasEffectWithParamPair(fx_level_immunity_dec_ref, fx->Power, 0); - if( efx ) { - DecreaseEffect(efx); - return 0; - } - - //decrementing spell immunity - if( fx->Source[0]) { - efx = actor->fxqueue.HasEffectWithResource(fx_spell_immunity_dec_ref, fx->Source); - if( efx) { - DecreaseEffect(efx); - return 0; - } - } - //decrementing primary type immunity (school) - if( fx->PrimaryType) { - efx = actor->fxqueue.HasEffectWithParam(fx_school_immunity_dec_ref, fx->PrimaryType); - if( efx) { - DecreaseEffect(efx); - return 0; - } - } - - //decrementing secondary type immunity (usage) - if( fx->SecondaryType) { - efx = actor->fxqueue.HasEffectWithParam(fx_secondary_type_immunity_dec_ref, fx->SecondaryType); - if( efx) { - DecreaseEffect(efx); - return 0; - } - } - - //spelltrap (absorb) - //FIXME: - //if the spelltrap effect already absorbed enough levels - //but still didn't get removed, it will absorb levels it shouldn't - //it will also absorb multiple spells in a single round - efx=actor->fxqueue.HasEffectWithParamPair(fx_spelltrap, 0, fx->Power); - if( efx) { - //storing the absorbed spell level - efx->Parameter3+=fx->Power; - //instead of a single effect, they had to create an effect for each level - //HOW DAMN LAME - //if decrease needs the spell level, use fx->Power here - actor->fxqueue.DecreaseParam1OfEffect(fx_spelltrap, 1); - //efx->Parameter1--; - return 0; - } - - //bounce checks - if( (bounce&BNC_LEVEL) && actor->fxqueue.HasEffectWithParamPair(fx_level_bounce_ref, fx->Power, 0) ) { - return 0; - } - - if( fx->Source[0] && (bounce&BNC_RESOURCE) && actor->fxqueue.HasEffectWithResource(fx_spell_bounce_ref, fx->Source) ) { - return -1; - } - - if( fx->PrimaryType && (bounce&BNC_SCHOOL) ) { - if( actor->fxqueue.HasEffectWithParam(fx_school_bounce_ref, fx->PrimaryType)) { - return -1; - } - } - - if( fx->SecondaryType && (bounce&BNC_SECTYPE) ) { - if( actor->fxqueue.HasEffectWithParam(fx_secondary_type_bounce_ref, fx->SecondaryType)) { - return -1; - } - } - //decrementing bounce checks - - //level decrementing bounce check - if( (bounce&BNC_LEVEL_DEC)) { - efx=actor->fxqueue.HasEffectWithParamPair(fx_level_bounce_dec_ref, fx->Power, 0); - if( efx) { - DecreaseEffect(efx); - return -1; - } - } - - if( fx->Source[0] && (bounce&BNC_RESOURCE_DEC)) { - efx=actor->fxqueue.HasEffectWithResource(fx_spell_bounce_dec_ref, fx->Resource); - if( efx) { - DecreaseEffect(efx); - return -1; - } - } - - if( fx->PrimaryType && (bounce&BNC_SCHOOL_DEC) ) { - efx=actor->fxqueue.HasEffectWithParam(fx_school_bounce_dec_ref, fx->PrimaryType); - if( efx) { - DecreaseEffect(efx); - return -1; - } - } - - if( fx->SecondaryType && (bounce&BNC_SECTYPE_DEC) ) { - efx=actor->fxqueue.HasEffectWithParam(fx_secondary_type_bounce_dec_ref, fx->SecondaryType); - if( efx) { - DecreaseEffect(efx); - return -1; - } - } - - return 1; -} - -//check resistances, saving throws -static bool check_resistance(Actor* actor, Effect* fx) -{ - if( !actor) { - return false; - } - - //opcode immunity - if( actor->fxqueue.HasEffectWithParam(fx_opcode_immunity_ref, fx->Opcode) ) { - print ("immune to effect: %s\n", (char*) Opcodes[fx->Opcode].Name); - return true; - } - if( actor->fxqueue.HasEffectWithParam(fx_opcode_immunity2_ref, fx->Opcode) ) { - print ("immune2 to effect: %s\n", (char*) Opcodes[fx->Opcode].Name); - return true; - } - -/* opcode bouncing isn't implemented? - //opcode bouncing - if( actor->fxqueue.HasEffectWithParam(fx_opcode_bounce_ref, fx->Opcode) ) { - return false; - } -*/ - - //not resistable (no saves either?) - if( fx->Resistance != FX_CAN_RESIST_CAN_DISPEL) { - return false; - } - - if (pstflags && (actor->GetSafeStat(IE_STATE_ID) & (STATE_ANTIMAGIC) ) ) { - return false; - } - - //don't resist self - bool selective_mr = core->HasFeature(GF_SELECTIVE_MAGIC_RES); - if (fx->Target==FX_TARGET_SELF) { - if (selective_mr) { - return false; - } - } - - //magic immunity - ieDword val = actor->GetStat(IE_RESISTMAGIC); - if( (signed) fx->random_value < (signed) val) { - // when using biased magic resistance non-hostile spells aren't resisted - if ((selective_mr && (fx->SourceFlags&SF_HOSTILE)) || !selective_mr) { - print ("effect resisted: %s\n", (char*) Opcodes[fx->Opcode].Name); - return true; - } - } - - //saving throws - bool saved = false; - for (int i=0;i<5;i++) { - if( fx->SavingThrowType&(1<GetSavingThrow(i, fx->SavingThrowBonus); - if( saved) { - break; - } - } - } - if( saved) { - if( fx->IsSaveForHalfDamage) { - fx->Parameter1/=2; - } else { - print ("%s saved against effect: %s\n", actor->GetName(1), (char*) Opcodes[fx->Opcode].Name); - return true; - } - } - return false; -} - -// this function is called two different ways -// when FirstApply is set, then the effect isn't stuck on the target -// this happens when a new effect comes in contact with the target. -// if the effect returns FX_DURATION_JUST_EXPIRED then it won't stick -// when first_apply is unset, the effect is already on the target -// this happens on load time too! -// returns FX_NOT_APPLIED if the process shouldn't be calling applyeffect anymore -// returns FX_ABORT if the whole spell this effect is in should be aborted -// it will disable all future effects of same source (only on first apply) - -int EffectQueue::ApplyEffect(Actor* target, Effect* fx, ieDword first_apply, ieDword resistance) const -{ - //print( "FX 0x%02x: %s(%d, %d)\n", fx->Opcode, effectnames[fx->Opcode].Name, fx->Parameter1, fx->Parameter2 ); - if( fx->Opcode >= MAX_EFFECTS) { - fx->TimingMode = FX_DURATION_JUST_EXPIRED; - return FX_NOT_APPLIED; - } - - ieDword GameTime = core->GetGame()->GameTime; - - 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; - } - - //gemrb specific, stat based chance - if ((fx->Probability2 == 100) && Owner && (Owner->Type==ST_ACTOR) ) { - fx->Probability2 = 0; - fx->Probability1 = ((Actor *) Owner)->GetSafeStat(fx->Probability1); - } - - if (resistance) { - //the effect didn't pass the probability check - if( !check_probability(fx) ) { - fx->TimingMode = FX_DURATION_JUST_EXPIRED; - return FX_NOT_APPLIED; - } - - //the effect didn't pass the target level check - if( check_level(target, fx) ) { - fx->TimingMode = FX_DURATION_JUST_EXPIRED; - return FX_NOT_APPLIED; - } - - //the effect didn't pass the resistance check - if( check_resistance(target, fx) ) { - fx->TimingMode = FX_DURATION_JUST_EXPIRED; - return FX_NOT_APPLIED; - } - } - - //Same as in items and spells - if (fx->SourceFlags & SF_HOSTILE) { - if (target && (target != Owner) && Owner && (Owner->Type==ST_ACTOR) ) { - target->AttackedBy((Actor *) Owner); - } - } - - if( NeedPrepare(fx->TimingMode) ) { - //save delay for later - fx->SecondaryDelay = fx->Duration; - if( fx->TimingMode == FX_DURATION_INSTANT_LIMITED) { - fx->TimingMode = FX_DURATION_ABSOLUTE; - } - PrepareDuration(fx); - } - } - //check if the effect has triggered or expired - switch (DelayType(fx->TimingMode&0xff) ) { - case DELAYED: - if( fx->Duration>GameTime) { - return FX_NOT_APPLIED; - } - //effect triggered - //delayed duration (3) - if( NeedPrepare(fx->TimingMode) ) { - //prepare for delayed duration effects - fx->Duration = fx->SecondaryDelay; - PrepareDuration(fx); - } - fx->TimingMode=TriggeredEffect(fx->TimingMode); - break; - case DURATION: - if( fx->Duration<=GameTime) { - fx->TimingMode = FX_DURATION_JUST_EXPIRED; - //add a return here, if 0 duration effects shouldn't work - } - break; - //permanent effect (so there is no warning) - case PERMANENT: - break; - //this shouldn't happen - default: - error("EffectQueue", "Unknown delay type: %d (from %d)\n", DelayType(fx->TimingMode&0xff), fx->TimingMode); - } - - EffectFunction fn = 0; - if( fx->OpcodeOpcode].Function; - if (!(target || (Opcodes[fx->Opcode].Flags & EFFECT_NO_ACTOR))) { - print("targetless opcode without EFFECT_NO_ACTOR: %d, skipping\n", fx->Opcode); - return FX_NOT_APPLIED; - } - } - int res = FX_ABORT; - if( fn) { - if( target && first_apply ) { - if( !target->fxqueue.HasEffectWithParamPair(fx_protection_from_display_string_ref, fx->Parameter1, 0) ) { - displaymsg->DisplayStringName( Opcodes[fx->Opcode].Strref, 0xf0f0f0, - target, IE_STR_SOUND); - } - } - - res=fn( Owner, target, fx ); - - //if there is no owner, we assume it is the target - switch( res ) { - case FX_APPLIED: - //normal effect with duration - break; - case FX_NOT_APPLIED: - //instant effect, pending removal - //for example, a damage effect - fx->TimingMode = FX_DURATION_JUST_EXPIRED; - break; - case FX_INSERT: - //put this effect in the beginning of the queue - //all known insert effects are 'permanent' too - //that is the AC effect only - //actually, permanent effects seem to be - //inserted by the game engine too - case FX_PERMANENT: - //don't stick around if it was executed permanently - //for example, a permanent strength modifier effect - if( fx->TimingMode == FX_DURATION_INSTANT_PERMANENT ) { - fx->TimingMode = FX_DURATION_JUST_EXPIRED; - } - break; - case FX_ABORT: - break; - default: - abort(); - } - } else { - //effect not found, it is going to be discarded - fx->TimingMode = FX_DURATION_JUST_EXPIRED; - } - return res; -} - -// looks for opcode with param2 - -#define MATCH_OPCODE() if((*f)->Opcode!=opcode) { continue; } - -// useful for: remove equipped item -#define MATCH_SLOTCODE() if((*f)->InventorySlot!=slotcode) { continue; } - -// useful for: remove projectile type -#define MATCH_PROJECTILE() if((*f)->Projectile!=projectile) { continue; } - -static const bool fx_live[MAX_TIMING_MODE]={true,true,true,false,false,false,false,false,true,true,false}; -static inline bool IsLive(ieByte timingmode) -{ - if( timingmode>=MAX_TIMING_MODE) return false; - return fx_live[timingmode]; -} - -#define MATCH_LIVE_FX() if(!IsLive((*f)->TimingMode)) { continue; } -#define MATCH_PARAM1() if((*f)->Parameter1!=param1) { continue; } -#define MATCH_PARAM2() if((*f)->Parameter2!=param2) { continue; } -#define MATCH_RESOURCE() if( strnicmp( (*f)->Resource, resource, 8) ) { continue; } -#define MATCH_SOURCE() if( strnicmp( (*f)->Source, Removed, 8) ) { continue; } -#define MATCH_TIMING() if( (*f)->TimingMode!=timing) { continue; } - -//call this from an applied effect, after it returns, these effects -//will be killed along with it -void EffectQueue::RemoveAllEffects(ieDword opcode) const -{ - std::list< Effect* >::const_iterator f; - for ( f = effects.begin(); f != effects.end(); f++ ) { - MATCH_OPCODE(); - MATCH_LIVE_FX(); - - (*f)->TimingMode = FX_DURATION_JUST_EXPIRED; - } -} - -//removes all equipping effects that match slotcode -void EffectQueue::RemoveEquippingEffects(ieDwordSigned slotcode) const -{ - std::list< Effect* >::const_iterator f; - for ( f = effects.begin(); f != effects.end(); f++ ) { - if( !IsEquipped((*f)->TimingMode)) continue; - MATCH_SLOTCODE(); - - (*f)->TimingMode = FX_DURATION_JUST_EXPIRED; - } -} - -//removes all effects that match projectile -void EffectQueue::RemoveAllEffectsWithProjectile(ieDword projectile) const -{ - std::list< Effect* >::const_iterator f; - for ( f = effects.begin(); f != effects.end(); f++ ) { - MATCH_PROJECTILE(); - - (*f)->TimingMode = FX_DURATION_JUST_EXPIRED; - } -} - -//remove effects belonging to a given spell -void EffectQueue::RemoveAllEffects(const ieResRef Removed) const -{ - std::list< Effect* >::const_iterator f; - for ( f = effects.begin(); f != effects.end(); f++ ) { - MATCH_LIVE_FX(); - MATCH_SOURCE(); - - (*f)->TimingMode = FX_DURATION_JUST_EXPIRED; - } -} - -//remove effects belonging to a given spell, but only if they match timing method x -void EffectQueue::RemoveAllEffects(const ieResRef Removed, ieByte timing) const -{ - std::list< Effect* >::const_iterator f; - for ( f = effects.begin(); f != effects.end(); f++ ) { - MATCH_TIMING(); - MATCH_SOURCE(); - - (*f)->TimingMode = FX_DURATION_JUST_EXPIRED; - } -} - -//this will modify effect reference -void EffectQueue::RemoveAllEffects(EffectRef &effect_reference) const -{ - ResolveEffectRef(effect_reference); - if( effect_reference.opcode<0) { - return; - } - RemoveAllEffects(effect_reference.opcode); -} - -//Removes all effects with a matching resource field -void EffectQueue::RemoveAllEffectsWithResource(ieDword opcode, const ieResRef resource) const -{ - std::list< Effect* >::const_iterator f; - for ( f = effects.begin(); f != effects.end(); f++ ) { - MATCH_OPCODE(); - MATCH_LIVE_FX(); - MATCH_RESOURCE(); - - (*f)->TimingMode = FX_DURATION_JUST_EXPIRED; - } -} - -void EffectQueue::RemoveAllEffectsWithResource(EffectRef &effect_reference, const ieResRef resource) const -{ - ResolveEffectRef(effect_reference); - RemoveAllEffectsWithResource(effect_reference.opcode, resource); -} - -//This method could be used to remove stat modifiers that would lower a stat -//(works only if a higher stat means good for the target) -void EffectQueue::RemoveAllDetrimentalEffects(ieDword opcode, ieDword current) const -{ - std::list< Effect* >::const_iterator f; - for ( f = effects.begin(); f != effects.end(); f++ ) { - MATCH_OPCODE(); - MATCH_LIVE_FX(); - switch((*f)->Parameter2) { - case 0:case 3: - if( ((signed) (*f)->Parameter1)>=0) continue; - break; - case 1:case 4: - if( ((signed) (*f)->Parameter1)>=(signed) current) continue; - break; - case 2:case 5: - if( ((signed) (*f)->Parameter1)>=100) continue; - break; - default: - break; - } - (*f)->TimingMode = FX_DURATION_JUST_EXPIRED; - } -} - -//Removes all effects with a matching param2 -//param2 is usually an effect's subclass (quality) while param1 is more like quantity. -//So opcode+param2 usually pinpoints an effect better when not all effects of a given -//opcode need to be removed (see removal of portrait icon) -void EffectQueue::RemoveAllEffectsWithParam(ieDword opcode, ieDword param2) const -{ - std::list< Effect* >::const_iterator f; - for ( f = effects.begin(); f != effects.end(); f++ ) { - MATCH_OPCODE(); - MATCH_LIVE_FX(); - MATCH_PARAM2(); - - (*f)->TimingMode = FX_DURATION_JUST_EXPIRED; - } -} - -//this function is called by FakeEffectExpiryCheck -//probably also called by rest -void EffectQueue::RemoveExpiredEffects(ieDword futuretime) const -{ - ieDword GameTime = core->GetGame()->GameTime; - if( GameTime+futuretime*AI_UPDATE_TIME::const_iterator f; - for ( f = effects.begin(); f != effects.end(); f++ ) { - //FIXME: how this method handles delayed effects??? - //it should remove them as well, i think - if( DelayType( ((*f)->TimingMode) )!=PERMANENT ) { - if( (*f)->Duration<=GameTime) { - (*f)->TimingMode = FX_DURATION_JUST_EXPIRED; - } - } - } -} - -//this effect will expire all effects that are not truly permanent -//which i call permanent after death (iesdp calls it permanent after bonuses) -void EffectQueue::RemoveAllNonPermanentEffects() const -{ - std::list< Effect* >::const_iterator f; - for ( f = effects.begin(); f != effects.end(); f++ ) { - if( IsRemovable((*f)->TimingMode) ) { - (*f)->TimingMode = FX_DURATION_JUST_EXPIRED; - } - } -} - -//this will modify effect reference - -void EffectQueue::RemoveAllDetrimentalEffects(EffectRef &effect_reference, ieDword current) const -{ - ResolveEffectRef(effect_reference); - RemoveAllDetrimentalEffects(effect_reference.opcode, current); -} - -void EffectQueue::RemoveAllEffectsWithParam(EffectRef &effect_reference, ieDword param2) const -{ - ResolveEffectRef(effect_reference); - RemoveAllEffectsWithParam(effect_reference.opcode, param2); -} - -//remove certain levels of effects, possibly matching school/secondary type -//this method removes whole spells (tied together by their source) -//FIXME: probably this isn't perfect -void EffectQueue::RemoveLevelEffects(ieResRef &Removed, ieDword level, ieDword Flags, ieDword match) const -{ - Removed[0]=0; - std::list< Effect* >::const_iterator f; - for ( f = effects.begin(); f != effects.end(); f++ ) { - if( (*f)->Power>level) { - continue; - } - - if( Removed[0]) { - MATCH_SOURCE(); - } - if( Flags&RL_MATCHSCHOOL) { - if( (*f)->PrimaryType!=match) { - continue; - } - } - if( Flags&RL_MATCHSECTYPE) { - if( (*f)->SecondaryType!=match) { - continue; - } - } - //if dispellable was not set, or the effect is dispellable - //then remove it - if( Flags&RL_DISPELLABLE) { - if( !((*f)->Resistance&FX_CAN_DISPEL)) { - continue; - } - } - (*f)->TimingMode = FX_DURATION_JUST_EXPIRED; - if( Flags&RL_REMOVEFIRST) { - memcpy(Removed,(*f)->Source, sizeof(Removed)); - } - } -} - -Effect *EffectQueue::HasOpcode(ieDword opcode) const -{ - std::list< Effect* >::const_iterator f; - for ( f = effects.begin(); f != effects.end(); f++ ) { - MATCH_OPCODE(); - MATCH_LIVE_FX(); - - return (*f); - } - return NULL; -} - -Effect *EffectQueue::HasEffect(EffectRef &effect_reference) const -{ - ResolveEffectRef(effect_reference); - if( effect_reference.opcode<0) { - return NULL; - } - return HasOpcode(effect_reference.opcode); -} - -Effect *EffectQueue::HasOpcodeWithParam(ieDword opcode, ieDword param2) const -{ - std::list< Effect* >::const_iterator f; - for ( f = effects.begin(); f != effects.end(); f++ ) { - MATCH_OPCODE(); - MATCH_LIVE_FX(); - MATCH_PARAM2(); - - return (*f); - } - return NULL; -} - -Effect *EffectQueue::HasEffectWithParam(EffectRef &effect_reference, ieDword param2) const -{ - ResolveEffectRef(effect_reference); - if( effect_reference.opcode<0) { - return NULL; - } - return HasOpcodeWithParam(effect_reference.opcode, param2); -} - -//looks for opcode with pairs of parameters (useful for protection against creature, extra damage or extra thac0 against creature) -//generally an IDS targeting - -Effect *EffectQueue::HasOpcodeWithParamPair(ieDword opcode, ieDword param1, ieDword param2) const -{ - std::list< Effect* >::const_iterator f; - for ( f = effects.begin(); f != effects.end(); f++ ) { - MATCH_OPCODE(); - MATCH_LIVE_FX(); - MATCH_PARAM2(); - //0 is always accepted as first parameter - if( param1) { - MATCH_PARAM1(); - } - - return (*f); - } - return NULL; -} - -Effect *EffectQueue::HasEffectWithParamPair(EffectRef &effect_reference, ieDword param1, ieDword param2) const -{ - ResolveEffectRef(effect_reference); - if( effect_reference.opcode<0) { - return NULL; - } - return HasOpcodeWithParamPair(effect_reference.opcode, param1, param2); -} - -// sums all the values of the specific damage bonus effects of the passed "damage type" -int EffectQueue::SpecificDamageBonus(ieDword opcode, ieDword param2) const -{ - int bonus = 0; - std::list< Effect* >::const_iterator f; - for ( f = effects.begin(); f != effects.end(); f++ ) { - MATCH_OPCODE(); - MATCH_LIVE_FX(); - MATCH_PARAM2(); - bonus += (signed) (*f)->Parameter1; - } - return bonus; -} - -static EffectRef fx_damage_bonus_modifier_ref = { "DamageBonusModifier", -1 }; -int EffectQueue::SpecificDamageBonus(ieDword damage_type) const -{ - ResolveEffectRef(fx_damage_bonus_modifier_ref); - if(fx_damage_bonus_modifier_ref.opcode < 0) { - return 0; - } - return SpecificDamageBonus(fx_damage_bonus_modifier_ref.opcode, damage_type); -} - -//this could be used for stoneskins and mirror images as well -void EffectQueue::DecreaseParam1OfEffect(ieDword opcode, ieDword amount) const -{ - std::list< Effect* >::const_iterator f; - for ( f = effects.begin(); f != effects.end(); f++ ) { - MATCH_OPCODE(); - MATCH_LIVE_FX(); - ieDword value = (*f)->Parameter1; - if( value>amount) value-=amount; - else value = 0; - (*f)->Parameter1=value; - } -} - -void EffectQueue::DecreaseParam1OfEffect(EffectRef &effect_reference, ieDword amount) const -{ - ResolveEffectRef(effect_reference); - if( effect_reference.opcode<0) { - return; - } - DecreaseParam1OfEffect(effect_reference.opcode, amount); -} - - -//this function does IDS targeting for effects (extra damage/thac0 against creature) -static const int ids_stats[7]={IE_EA, IE_GENERAL, IE_RACE, IE_CLASS, IE_SPECIFIC, IE_SEX, IE_ALIGNMENT}; - -int EffectQueue::BonusAgainstCreature(ieDword opcode, Actor *actor) const -{ - int sum = 0; - std::list< Effect* >::const_iterator f; - for ( f = effects.begin(); f != effects.end(); f++ ) { - MATCH_OPCODE(); - MATCH_LIVE_FX(); - if( (*f)->Parameter1) { - ieDword ids = (*f)->Parameter2; - if( ids<2 || ids>8) { - ids=2; - } - ieDword param1 = actor->GetStat(ids_stats[ids-2]); - MATCH_PARAM1(); - } - int val = (int) (*f)->Parameter3; - if( !val) val = 2; - sum += val; - } - return sum; -} - -int EffectQueue::BonusAgainstCreature(EffectRef &effect_reference, Actor *actor) const -{ - ResolveEffectRef(effect_reference); - if( effect_reference.opcode<0) { - return 0; - } - return BonusAgainstCreature(effect_reference.opcode, actor); -} - -bool EffectQueue::WeaponImmunity(ieDword opcode, int enchantment, ieDword weapontype) const -{ - std::list< Effect* >::const_iterator f; - for ( f = effects.begin(); f != effects.end(); f++ ) { - MATCH_OPCODE(); - MATCH_LIVE_FX(); - // - int magic = (int) (*f)->Parameter1; - ieDword mask = (*f)->Parameter3; - ieDword value = (*f)->Parameter4; - if( magic==0) { - if( enchantment) continue; - } else if( magic>0) { - if( enchantment>magic) continue; - } - - if( (weapontype&mask) != value) { - continue; - } - return true; - } - return false; -} - -static EffectRef fx_weapon_immunity_ref = { "Protection:Weapons", -1 }; - -bool EffectQueue::WeaponImmunity(int enchantment, ieDword weapontype) const -{ - ResolveEffectRef(fx_weapon_immunity_ref); - if( fx_weapon_immunity_ref.opcode<0) { - return 0; - } - return WeaponImmunity(fx_weapon_immunity_ref.opcode, enchantment, weapontype); -} - -void EffectQueue::AddWeaponEffects(EffectQueue *fxqueue, EffectRef &fx_ref) const -{ - ResolveEffectRef(fx_ref); - if( fx_ref.opcode<0) { - return; - } - - ieDword opcode = fx_ref.opcode; - Point p(-1,-1); - - std::list< Effect* >::const_iterator f; - for ( f = effects.begin(); f != effects.end(); f++ ) { - MATCH_OPCODE(); - MATCH_LIVE_FX(); - // - Effect *fx = core->GetEffect( (*f)->Resource, (*f)->Power, p); - if (!fx) continue; - fx->Target = FX_TARGET_PRESET; - fxqueue->AddEffect(fx, true); - } -} - -/* no longer needed, use IE_CASTING stat -static EffectRef fx_disable_spellcasting_ref = { "DisableCasting", -1 }; -int EffectQueue::DisabledSpellcasting(int types) const -{ - ResolveEffectRef(fx_disable_spellcasting_ref); - if( fx_disable_spellcasting_ref.opcode < 0) { - return 0; - } - - unsigned int spelltype_mask = 0; - bool iwd2 = !!core->HasFeature(GF_ENHANCED_EFFECTS); - ieDword opcode = fx_disable_spellcasting_ref.opcode; - std::list< Effect* >::const_iterator f; - for ( f = effects.begin(); f != effects.end(); f++ ) { - MATCH_OPCODE(); - MATCH_LIVE_FX(); - - if (iwd2) { - switch((*f)->Parameter2) { - case 0: // all - spelltype_mask |= 7; - break; - case 1: // mage and cleric - spelltype_mask |= 3; - break; - case 2: // mage - spelltype_mask |= 2; - break; - case 3: // cleric - spelltype_mask |= 1; - break; - case 4: // innate - spelltype_mask |= 4; - break; - } - } else { - switch((*f)->Parameter2) { - case 0: // mage - spelltype_mask |= 2; - break; - case 1: // cleric - spelltype_mask |= 1; - break; - case 2: // innate - spelltype_mask |= 4; - break; - } - } - } - return spelltype_mask & types; -} -*/ - -//useful for immunity vs spell, can't use item, etc. -Effect *EffectQueue::HasOpcodeWithResource(ieDword opcode, const ieResRef resource) const -{ - std::list< Effect* >::const_iterator f; - for ( f = effects.begin(); f != effects.end(); f++ ) { - MATCH_OPCODE(); - MATCH_LIVE_FX(); - MATCH_RESOURCE(); - - return (*f); - } - return NULL; -} - -Effect *EffectQueue::HasEffectWithResource(EffectRef &effect_reference, const ieResRef resource) const -{ - ResolveEffectRef(effect_reference); - return HasOpcodeWithResource(effect_reference.opcode, resource); -} - -//used in contingency/sequencer code (cannot have the same contingency twice) -Effect *EffectQueue::HasOpcodeWithSource(ieDword opcode, const ieResRef Removed) const -{ - std::list< Effect* >::const_iterator f; - for ( f = effects.begin(); f != effects.end(); f++ ) { - MATCH_OPCODE(); - MATCH_LIVE_FX(); - MATCH_SOURCE(); - - return (*f); - } - return NULL; -} - -Effect *EffectQueue::HasEffectWithSource(EffectRef &effect_reference, const ieResRef resource) const -{ - ResolveEffectRef(effect_reference); - return HasOpcodeWithSource(effect_reference.opcode, resource); -} - -bool EffectQueue::HasAnyDispellableEffect() const -{ - std::list< Effect* >::const_iterator f; - for ( f = effects.begin(); f != effects.end(); f++ ) { - if( (*f)->Resistance&FX_CAN_DISPEL) { - return true; - } - } - return false; -} - -void EffectQueue::dump() const -{ - print( "EFFECT QUEUE:\n" ); - int i = 0; - std::list< Effect* >::const_iterator f; - for ( f = effects.begin(); f != effects.end(); f++ ) { - Effect* fx = *f; - if( fx) { - char *Name = NULL; - if( fx->Opcode < MAX_EFFECTS) - Name = (char*) Opcodes[fx->Opcode].Name; - - print( " %2d: 0x%02x: %s (%d, %d) S:%s\n", i++, fx->Opcode, Name, fx->Parameter1, fx->Parameter2, fx->Source ); - } - } -} -/* -Effect *EffectQueue::GetEffect(ieDword idx) const -{ - if( effects.size()<=idx) { - return NULL; - } - return effects[idx]; -} -*/ - -//returns true if the effect supports simplified duration -bool EffectQueue::HasDuration(Effect *fx) -{ - switch(fx->TimingMode) { - case FX_DURATION_INSTANT_LIMITED: //simple duration - case FX_DURATION_DELAY_LIMITED: //delayed duration - case FX_DURATION_DELAY_PERMANENT: //simple delayed - return true; - } - return false; -} - -static EffectRef fx_variable_ref = { "Variable:StoreLocalVariable", -1 }; - -//returns true if the effect must be saved -bool EffectQueue::Persistent(Effect* fx) -{ - // local variable effects self-destruct if they were processed already - // but if they weren't processed, e.g. in a global actor, we must save them - // TODO: do we really need to special-case this? leaving it for now - fuzzie - if( fx->Opcode==(ieDword) ResolveEffect(fx_variable_ref)) { - return true; - } - - switch (fx->TimingMode) { - //normal equipping fx of items - case FX_DURATION_INSTANT_WHILE_EQUIPPED: - //delayed effect not saved - case FX_DURATION_DELAY_UNSAVED: - //permanent effect not saved - case FX_DURATION_PERMANENT_UNSAVED: - //just expired effect - case FX_DURATION_JUST_EXPIRED: - return false; - } - return true; -} - -//alter the color effect in case the item is equipped in the shield slot -void EffectQueue::HackColorEffects(Actor *Owner, Effect *fx) -{ - if( fx->InventorySlot!=Owner->inventory.GetShieldSlot()) return; - - unsigned int gradienttype = fx->Parameter2 & 0xF0; - if( gradienttype == 0x10) { - gradienttype = 0x20; // off-hand - fx->Parameter2 &= ~0xF0; - fx->Parameter2 |= gradienttype; - } -} - -//iterate through saved effects -const Effect *EffectQueue::GetNextSavedEffect(std::list< Effect* >::const_iterator &f) const -{ - while(f!=effects.end()) { - Effect *effect = *f; - f++; - if( Persistent(effect)) { - return effect; - } - } - return NULL; -} - -Effect *EffectQueue::GetNextEffect(std::list< Effect* >::const_iterator &f) const -{ - if( f!=effects.end()) return *f++; - return NULL; -} - -ieDword EffectQueue::CountEffects(ieDword opcode, ieDword param1, ieDword param2, const char *resource) const -{ - ieDword cnt = 0; - - std::list< Effect* >::const_iterator f; - - for ( f = effects.begin(); f != effects.end(); f++ ) { - MATCH_OPCODE(); - if( param1!=0xffffffff) - MATCH_PARAM1(); - if( param2!=0xffffffff) - MATCH_PARAM2(); - if( resource) { - MATCH_RESOURCE(); - } - cnt++; - } - return cnt; -} - -void EffectQueue::ModifyEffectPoint(ieDword opcode, ieDword x, ieDword y) const -{ - std::list< Effect* >::const_iterator f; - - for ( f = effects.begin(); f != effects.end(); f++ ) { - MATCH_OPCODE(); - (*f)->PosX=x; - (*f)->PosY=y; - (*f)->Parameter3=0; - return; - } -} - -//count effects that get saved -ieDword EffectQueue::GetSavedEffectsCount() const -{ - ieDword cnt = 0; - - std::list< Effect* >::const_iterator f; - - for ( f = effects.begin(); f != effects.end(); f++ ) { - Effect* fx = *f; - if( Persistent(fx)) - cnt++; - } - return cnt; -} - -void EffectQueue::TransformToDelay(ieByte &TimingMode) -{ - if( TimingModeImmuneToProjectile(fx->Projectile)) return 0; - - //don't resist item projectile payloads based on spell school, bounce, etc. - if( fx->InventorySlot) { - return 1; - } - - //check level resistances - //check specific spell immunity - //check school/sectype immunity - return check_type(target, fx); - } - return 0; -} - -void EffectQueue::AffectAllInRange(Map *map, const Point &pos, int idstype, int idsvalue, - unsigned int range, Actor *except) -{ - int cnt = map->GetActorCount(true); - while(cnt--) { - Actor *actor = map->GetActor(cnt,true); - if( except==actor) { - continue; - } - //distance - if( Distance(pos, actor)>range) { - continue; - } - //ids targeting - if( !match_ids(actor, idstype, idsvalue)) { - continue; - } - //line of sight - if( !map->IsVisible(actor->Pos, pos)) { - continue; - } - AddAllEffects(actor, actor->Pos); - } -} - diff --git a/project/jni/application/gemrb/gemrb/core/EffectQueue.h b/project/jni/application/gemrb/gemrb/core/EffectQueue.h deleted file mode 100644 index 0f4aed862..000000000 --- a/project/jni/application/gemrb/gemrb/core/EffectQueue.h +++ /dev/null @@ -1,314 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -/** - * @file EffectQueue.h - * Declares EffectQueue class holding and processing all spell effects - * on a single Actor - * @author The GemRB Project - */ - -#ifndef EFFECTQUEUE_H -#define EFFECTQUEUE_H - -#include "exports.h" - -#include "Effect.h" -#include "Region.h" - -#include -#include - -class Actor; -class Map; -class Scriptable; - -/** Maximum number of different Effect opcodes */ -#define MAX_EFFECTS 512 - -///** if the effect returns this, stop adding any other effect */ -#define FX_ABORT 0 -/** these effects don't stick around if used as permanent, - * in that case they modify a base stat like charisma modifier */ -#define FX_PERMANENT 2 -/** these effects never stick around, use them for instant effects like damage */ -#define FX_NOT_APPLIED 3 -/** these effects always stick around when applied as permanent or duration */ -#define FX_APPLIED 1 -///** insert the effect instead of push back */ -#define FX_INSERT 4 - -//remove level effects flags -#define RL_DISPELLABLE 1 //only dispellables -#define RL_MATCHSCHOOL 2 //match school -#define RL_MATCHSECTYPE 4 //match secondary type -#define RL_REMOVEFIRST 8 //remove only one spell (could be more effects) - -//bouncing immunities -#define BNC_PROJECTILE 1 -#define BNC_OPCODE 2 -#define BNC_LEVEL 4 -#define BNC_SCHOOL 8 -#define BNC_SECTYPE 0x10 -#define BNC_RESOURCE 0x20 -#define BNC_PROJECTILE_DEC 0x100 -#define BNC_OPCODE_DEC 0x200 -#define BNC_LEVEL_DEC 0x400 -#define BNC_SCHOOL_DEC 0x800 -#define BNC_SECTYPE_DEC 0x1000 -#define BNC_RESOURCE_DEC 0x2000 - -//normal immunities -#define IMM_PROJECTILE 1 -#define IMM_OPCODE 2 -#define IMM_LEVEL 4 -#define IMM_SCHOOL 8 -#define IMM_SECTYPE 16 -#define IMM_RESOURCE 32 -#define IMM_PROJECTILE_DEC 0x100 -#define IMM_OPCODE_DEC 0x200 -#define IMM_LEVEL_DEC 0x400 -#define IMM_SCHOOL_DEC 0x800 -#define IMM_SECTYPE_DEC 0x1000 -#define IMM_RESOURCE_DEC 0x2000 - -// FIXME: Dice roll should be probably done just once, e.g. when equipping -// the item, not each time the fx are applied -// the dice values are actually level limits, except in 3 hp modifier functions -// the damage function is an instant (the other 2 functions might be tricky with random values) -//#define DICE_ROLL(max_val) ((fx->DiceThrown && fx->DiceSides) ? ((max_val >=0) ? (MIN( core->Roll( fx->DiceThrown, fx->DiceSides, 0 ), max_val )) : (MAX( core->Roll( fx->DiceThrown, fx->DiceSides, 0 ), max_val ))) : max_val) - -//sometimes damage doesn't comply with the calculated value -#define DICE_ROLL(adjustment) (core->Roll( fx->DiceThrown, fx->DiceSides, adjustment) ) - -// 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 ]) -#define STAT_ADD(stat, mod) target->SetStat( stat, STAT_GET( stat ) + ( mod ), 0 ) -#define STAT_SUB(stat, mod) target->SetStat( stat, STAT_GET( stat ) - ( mod ), 0 ) -#define STAT_BIT_OR(stat, mod) target->SetStat( stat, STAT_GET( stat ) | ( mod ), 0 ) -#define STAT_SET(stat, mod) target->SetStat( stat, ( mod ), 0 ) -#define STAT_SET_PCF(stat, mod) target->SetStat( stat, ( mod ), 1 ) -#define STAT_BIT_OR_PCF(stat, mod) target->SetStat( stat, STAT_GET( stat ) | ( mod ), 1 ) -#define STAT_MUL(stat, mod) target->SetStat( stat, STAT_GET(stat) * ( mod ) / 100, 0 ) -//if an effect sticks around -#define STATE_CURE( mod ) target->Modified[ IE_STATE_ID ] &= ~(ieDword) ( mod ) -#define STATE_SET( mod ) target->Modified[ IE_STATE_ID ] |= (ieDword) ( mod ) -#define EXTSTATE_SET( mod ) target->Modified[ IE_EXTSTATE_ID ] |= (ieDword) ( mod ) -#define STATE_GET( mod ) (target->Modified[ IE_STATE_ID ] & (ieDword) ( mod ) ) -#define EXTSTATE_GET( mod ) (target->Modified[ IE_EXTSTATE_ID ] & (ieDword) ( mod ) ) -#define STAT_MOD( stat ) target->NewStat(stat, fx->Parameter1, fx->Parameter2) -#define STAT_MOD_VAR( stat, mod ) target->NewStat(stat, ( mod ) , fx->Parameter2 ) -#define BASE_GET(stat) (target->BaseStats[ stat ]) -#define BASE_SET(stat, mod) target->SetBase( stat, ( mod ) ) -#define BASE_ADD(stat, mod) target->SetBase( stat, BASE_GET(stat)+ ( mod ) ) -#define BASE_SUB(stat, mod) target->SetBase( stat, BASE_GET(stat)- ( mod ) ) -#define BASE_MUL(stat, mod) target->SetBase( stat, BASE_GET(stat)* ( mod ) / 100 ) -#define BASE_MOD(stat) target->NewBase( stat, fx->Parameter1, fx->Parameter2) -#define BASE_MOD_VAR(stat, mod) target->NewBase( stat, (mod), fx->Parameter2 ) -//if an effect doesn't stick (and has permanent until cured effect) then -//it has to modify the base stat (which is saved) -//also use this one if the effect starts a cure effect automatically -#define BASE_STATE_SET( mod ) target->SetBaseBit( IE_STATE_ID, ( mod ), true ) -#define BASE_STATE_CURE( mod ) target->SetBaseBit( IE_STATE_ID, ( mod ), false ) - -/** Prototype of a function implementing a particular Effect opcode */ -typedef int (* EffectFunction)(Scriptable*, Actor*, Effect*); - - -/** Cached Effect -> opcode mapping */ -struct EffectRef { - const char* Name; - 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 EffectDesc *opcodes); - -/** release effect list when Interface is destroyed */ -void EffectQueue_ReleaseMemory(); - -/** Check if opcode is for an effect that takes a color slot as parameter. */ -bool IsColorslotEffect(int opcode); - -/** - * @class EffectQueue - * Class holding and processing spell Effects on a single Actor - */ - -class GEM_EXPORT EffectQueue { -private: - /** List of Effects applied on the Actor */ - std::list< Effect* > effects; - /** Actor which is target of the Effects */ - Scriptable* Owner; - -public: - EffectQueue(); - virtual ~EffectQueue(); - - /** Sets Actor which is affected by these effects */ - void SetOwner(Scriptable* act) { Owner = act; } - /** Returns Actor affected by these effects */ - Scriptable* GetOwner() const { return Owner; } - - /** adds an effect to the queue, it could also insert it if flagged so - * fx should be freed by the caller - */ - void AddEffect(Effect* fx, bool insert=false); - /** Adds an Effect to the queue, subject to level and other checks. - * Returns FX_ABORT is unsuccessful. fx is just a reference, AddEffect() - * will malloc its own copy */ - int AddEffect(Effect* fx, Scriptable* self, Actor* pretarget, const Point &dest) const; - /** Removes first Effect matching fx from the queue. - * Effects are matched based on their contents */ - bool RemoveEffect(Effect* fx); - - int AddAllEffects(Actor* target, const Point &dest) const; - void ApplyAllEffects(Actor* target) const; - /** remove effects marked for removal */ - void Cleanup(); - - /* directly removes effects with specified opcode, use effect_reference when you can */ - void RemoveAllEffects(ieDword opcode) const; - void RemoveAllEffectsWithResource(ieDword opcode, const ieResRef resource) const; - - /* removes any effects (delayed or not) which were using projectile */ - void RemoveAllEffectsWithProjectile(ieDword projectile) const; - - /* removes equipping effects with specified inventory slot code */ - void RemoveEquippingEffects(ieDwordSigned slotcode) const; - - /* removes all effects of a given spell */ - void RemoveAllEffects(const ieResRef Removed) const; - void RemoveAllEffects(const ieResRef Removed, ieByte timing) const; - /* removes all effects of type */ - void RemoveAllEffects(EffectRef &effect_reference) const; - /* removes expired or to be expired effects */ - void RemoveExpiredEffects(ieDword futuretime) const; - /* removes all effects except timing mode 9 */ - void RemoveAllNonPermanentEffects() const; - void RemoveAllDetrimentalEffects(EffectRef &effect_reference, ieDword current) const; - void RemoveAllEffectsWithParam(EffectRef &effect_reference, ieDword param2) const; - void RemoveAllEffectsWithResource(EffectRef &effect_reference, const ieResRef resource) const; - void RemoveLevelEffects(ieResRef &Removed, ieDword level, ieDword flags, ieDword match) const; - - /* returns true if the timing method supports simplified duration */ - static bool HasDuration(Effect *fx); - /* returns true if the effect should be saved */ - static bool Persistent(Effect* fx); - /* returns next saved effect, increases index */ - std::list< Effect* >::const_iterator GetFirstEffect() const - { - return effects.begin(); - } - const Effect *GetNextSavedEffect(std::list< Effect* >::const_iterator &f) const; - Effect *GetNextEffect(std::list< Effect* >::const_iterator &f) const; - ieDword CountEffects(EffectRef &effect_reference, ieDword param1, ieDword param2, const char *ResRef) const; - void ModifyEffectPoint(EffectRef &effect_reference, ieDword x, ieDword y) const; - /* returns the number of saved effects */ - ieDword GetSavedEffectsCount() const; - size_t GetEffectsCount() const { return effects.size(); } - /* this method hacks the offhand weapon color effects */ - static void HackColorEffects(Actor *Owner, Effect *fx); - static Effect *CreateEffect(EffectRef &effect_reference, ieDword param1, ieDword param2, ieWord timing); - EffectQueue *CopySelf() const; - static Effect *CreateEffectCopy(Effect *oldfx, EffectRef &effect_reference, ieDword param1, ieDword param2); - static Effect *CreateUnsummonEffect(Effect *fx); - //locating opcodes - Effect *HasEffect(EffectRef &effect_reference) const; - Effect *HasEffectWithParam(EffectRef &effect_reference, ieDword param2) const; - Effect *HasEffectWithParamPair(EffectRef &effect_reference, ieDword param1, ieDword param2) const; - Effect *HasEffectWithResource(EffectRef &effect_reference, const ieResRef resource) const; - Effect *HasEffectWithSource(EffectRef &effect_reference, const ieResRef source) const; - void DecreaseParam1OfEffect(EffectRef &effect_reference, ieDword amount) const; - int SpecificDamageBonus(ieDword damage_type) const; - bool HasAnyDispellableEffect() const; - //transforming timing modes - static void TransformToDelay(ieByte &TimingMode); - //getting summarised effects - int BonusAgainstCreature(EffectRef &effect_reference, Actor *actor) const; - //getting weapon immunity flag - bool WeaponImmunity(int enchantment, ieDword weapontype) const; - //melee and ranged effects - void AddWeaponEffects(EffectQueue *fxqueue, EffectRef &fx_ref) const; - // checks if spells of type "types" are disabled (usually by armor) - // returns a bitfield of disabled spelltypes - // it is no longer used - //int DisabledSpellcasting(int types) const; - - // returns -1 if bounced, 0 if resisted, 1 if accepted spell - int CheckImmunity(Actor *target) const; - // apply this effectqueue on all actors matching ids targeting - // from pos, in range (no cone size yet) - void AffectAllInRange(Map *map, const Point &pos, int idstype, int idsvalue, unsigned int range, Actor *except); - /** Lists contents of the queue on a terminal for debugging */ - void dump() const; - //resolve effect - static int ResolveEffect(EffectRef &effect_reference); - static bool match_ids(Actor *target, int table, ieDword value); - /** returns true if the process should abort applying a stack of effects */ - int ApplyEffect(Actor* target, Effect* fx, ieDword first_apply, ieDword resistance=1) const; -private: - /** counts effects of specific opcode, parameters and resource */ - ieDword CountEffects(ieDword opcode, ieDword param1, ieDword param2, const char *ResRef) const; - void ModifyEffectPoint(ieDword opcode, ieDword x, ieDword y) const; - //use the effect reference style calls from outside - static Effect *CreateEffect(ieDword opcode, ieDword param1, ieDword param2, ieWord timing); - static Effect *CreateEffectCopy(Effect *oldfx, ieDword opcode, ieDword param1, ieDword param2); - void RemoveAllDetrimentalEffects(ieDword opcode, ieDword current) const; - void RemoveAllEffectsWithParam(ieDword opcode, ieDword param2) const; - Effect *HasOpcode(ieDword opcode) const; - Effect *HasOpcodeWithParam(ieDword opcode, ieDword param2) const; - Effect *HasOpcodeWithParamPair(ieDword opcode, ieDword param1, ieDword param2) const; - Effect *HasOpcodeWithResource(ieDword opcode, const ieResRef resource) const; - Effect *HasOpcodeWithSource(ieDword opcode, const ieResRef source) const; - void DecreaseParam1OfEffect(ieDword opcode, ieDword amount) const; - int SpecificDamageBonus(ieDword opcode, ieDword param2) const; - int BonusAgainstCreature(ieDword opcode, Actor *actor) const; - bool WeaponImmunity(ieDword opcode, int enchantment, ieDword weapontype) const; -}; - -#endif // ! EFFECTQUEUE_H diff --git a/project/jni/application/gemrb/gemrb/core/Factory.cpp b/project/jni/application/gemrb/gemrb/core/Factory.cpp deleted file mode 100644 index 797c4a09d..000000000 --- a/project/jni/application/gemrb/gemrb/core/Factory.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "Factory.h" - -#include "win32def.h" - -#include - -Factory::Factory(void) -{ -} - -Factory::~Factory(void) -{ - for (unsigned int i = 0; i < fobjects.size(); i++) { - delete( fobjects[i] ); - } -} - -void Factory::AddFactoryObject(FactoryObject* fobject) -{ - fobjects.push_back( fobject ); -} - -int Factory::IsLoaded(const char* ResRef, SClass_ID type) const -{ - for (unsigned int i = 0; i < fobjects.size(); i++) { - if (fobjects[i]->SuperClassID == type) { - if (strnicmp( fobjects[i]->ResRef, ResRef, 8 ) == 0) { - return i; - } - } - } - return -1; -} - -FactoryObject* Factory::GetFactoryObject(int pos) const -{ - return fobjects[pos]; -} - -void Factory::FreeObjects(void) -{ - for (unsigned int i = 0; i < fobjects.size(); i++) { - delete( fobjects[i] ); - } -} diff --git a/project/jni/application/gemrb/gemrb/core/Factory.h b/project/jni/application/gemrb/gemrb/core/Factory.h deleted file mode 100644 index d6c1c09e3..000000000 --- a/project/jni/application/gemrb/gemrb/core/Factory.h +++ /dev/null @@ -1,42 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#ifndef FACTORY_H -#define FACTORY_H - -#include "exports.h" -#include "globals.h" - -#include "AnimationFactory.h" -#include "FactoryObject.h" - -class GEM_EXPORT Factory { -private: - std::vector< FactoryObject*> fobjects; -public: - Factory(void); - ~Factory(void); - void AddFactoryObject(FactoryObject* fobject); - int IsLoaded(const char* ResRef, SClass_ID type) const; - FactoryObject* GetFactoryObject(int pos) const; - void FreeObjects(void); -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/FactoryObject.cpp b/project/jni/application/gemrb/gemrb/core/FactoryObject.cpp deleted file mode 100644 index 8c0da9bae..000000000 --- a/project/jni/application/gemrb/gemrb/core/FactoryObject.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "FactoryObject.h" - -#include "win32def.h" - -FactoryObject::FactoryObject(const char* name, SClass_ID SuperClassID) -{ - strnlwrcpy( ResRef, name, 8 ); - this->SuperClassID = SuperClassID; -} - -FactoryObject::~FactoryObject(void) -{ -} diff --git a/project/jni/application/gemrb/gemrb/core/FactoryObject.h b/project/jni/application/gemrb/gemrb/core/FactoryObject.h deleted file mode 100644 index a1189c6eb..000000000 --- a/project/jni/application/gemrb/gemrb/core/FactoryObject.h +++ /dev/null @@ -1,35 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#ifndef FACTORYOBJECT_H -#define FACTORYOBJECT_H - -#include "exports.h" -#include "globals.h" - -class GEM_EXPORT FactoryObject { -public: - SClass_ID SuperClassID; - ieResRef ResRef; - FactoryObject(const char* ResRef, SClass_ID SuperClassID); - virtual ~FactoryObject(void); -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/FileCache.cpp b/project/jni/application/gemrb/gemrb/core/FileCache.cpp deleted file mode 100644 index 3da6ea27a..000000000 --- a/project/jni/application/gemrb/gemrb/core/FileCache.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "FileCache.h" - -#include "Compressor.h" -#include "Interface.h" -#include "PluginMgr.h" -#include "System/FileStream.h" -#include "System/VFS.h" - -DataStream* CacheCompressedStream(DataStream *stream, const char* filename, int length, bool overwrite) -{ - if (!core->IsAvailable(PLUGIN_COMPRESSION_ZLIB)) { - print( "No Compression Manager Available.\nCannot Load Compressed File.\n" ); - return NULL; - } - - char fname[_MAX_PATH]; - ExtractFileFromPath(fname, filename); - char path[_MAX_PATH]; - PathJoin(path, core->CachePath, fname, NULL); - - if (overwrite || !file_exists(path)) { - FileStream out; - if (!out.Create(path)) { - printMessage("FileCache", "Cannot write %s.\n", RED, path); - return NULL; - } - - PluginHolder comp(PLUGIN_COMPRESSION_ZLIB); - if (comp->Decompress(&out, stream, length) != GEM_OK) - return NULL; - } else { - stream->Seek(length, GEM_CURRENT_POS); - } - return FileStream::OpenFile(path); -} - -DataStream* CacheFile(const char* path) -{ - if (!core->GameOnCD) - return FileStream::OpenFile(path); - - char filename[_MAX_PATH]; - char cachedfile[_MAX_PATH]; - ExtractFileFromPath(filename, path); - PathJoin(cachedfile, core->CachePath, filename, NULL); - - if (!file_exists(cachedfile)) { // File was not found in cache - FileStream* src = FileStream::OpenFile(path); - FileStream* dest = FileStream::OpenFile(cachedfile); - if (!src || !dest) { - error("Cache", "CachedFile failed to write to cached file '%s' (from '%s')\n", cachedfile, path); - } - - size_t blockSize = 1024 * 1000; - char buff[1024 * 1000]; - do { - if (blockSize > src->Remains()) - blockSize = src->Remains(); - size_t len = src->Read(buff, blockSize); - size_t c = dest->Write(buff, len); - if (c != len) { - error("Cache", "CacheFile failed to write to cached file '%s' (from '%s')\n", cachedfile, path); - } - } while (src->Remains()); - delete src; - delete dest; - } - return FileStream::OpenFile(cachedfile); -} diff --git a/project/jni/application/gemrb/gemrb/core/FileCache.h b/project/jni/application/gemrb/gemrb/core/FileCache.h deleted file mode 100644 index 1345a4aa1..000000000 --- a/project/jni/application/gemrb/gemrb/core/FileCache.h +++ /dev/null @@ -1,27 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef FILECACHE_H -#define FILECACHE_H - -#include "System/DataStream.h" - -GEM_EXPORT DataStream* CacheCompressedStream(DataStream *stream, const char* filename, int length = 0, bool overwrite = false); -GEM_EXPORT DataStream* CacheFile(const char* path); - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/Font.cpp b/project/jni/application/gemrb/gemrb/core/Font.cpp deleted file mode 100644 index 7cb1bec4a..000000000 --- a/project/jni/application/gemrb/gemrb/core/Font.cpp +++ /dev/null @@ -1,579 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -//This class represents game fonts. Fonts are special .bam files. -//Each cycle stands for a letter. - -#include "Font.h" - -#include "win32def.h" - -#include "GameData.h" -#include "Interface.h" -#include "Palette.h" -#include "Sprite2D.h" -#include "Video.h" - -#include - -unsigned int lastX = 0; - -#define PARAGRAPH_START_X 5; - -static const Color black = {0, 0, 0, 0}; - -inline size_t mystrlen(const char* string) -{ - if (!string) { - return ( size_t ) 0; - } - const char* tmp = string; - size_t count = 0; - while (*tmp != 0) { - if (( ( unsigned char ) * tmp ) >= 0xf0) { - tmp += 3; - count += 3; - } - count++; - tmp++; - } - return count; -} - -Font::Font(int w, int h, Palette* pal) -{ - lastX = 0; - count = 0; - FirstChar = 0; - sprBuffer = 0; - - width = w; - height = h; - tmpPixels = (unsigned char*)malloc(width*height); - - memset( xPos, 0, sizeof( xPos) ); - memset( yPos, 0, sizeof( yPos) ); - - pal->IncRef(); - palette = pal; - maxHeight = h; -} - -Font::~Font(void) -{ - Video *video = core->GetVideoDriver(); - gamedata->FreePalette( palette ); - video->FreeSprite( sprBuffer ); -} - -void Font::FinalizeSprite(bool cK, int index) -{ - sprBuffer = core->GetVideoDriver()->CreateSprite8( width, height, 8, tmpPixels, palette ? palette->col : 0, cK, index ); - tmpPixels = 0; -} - -void Font::AddChar(unsigned char* spr, int w, int h, short xPos, short yPos) -{ - if (!spr) { - size[count].x = 0; - size[count].y = 0; - size[count].w = 0; - size[count].h = 0; - this->xPos[count] = 0; - this->yPos[count] = 0; - count++; - return; - } - unsigned char * currPtr = tmpPixels + lastX; - unsigned char * srcPtr = ( unsigned char * ) spr; - for (int y = 0; y < h; y++) { - memcpy( currPtr, srcPtr, w ); - srcPtr += w; - currPtr += width; - } - size[count].x = lastX; - size[count].y = 0; - size[count].w = w; - size[count].h = h; - this->xPos[count] = xPos; - this->yPos[count] = yPos; - count++; - lastX += w; -} - -void Font::PrintFromLine(int startrow, Region rgn, const unsigned char* string, - Palette* hicolor, unsigned char Alignment, Font* initials, - Sprite2D* cursor, unsigned int curpos, bool NoColor) const -{ - bool enablecap=false; - int capital = 0; - if (initials) - { - capital=1; - enablecap=true; - } - int initials_rows = 0; - int initials_x = 0; - - unsigned int psx = PARAGRAPH_START_X; - Palette *pal = hicolor; - if (!pal) { - pal = palette; - } - if (startrow) enablecap=false; - - if (initials==this) { - enablecap=false; - } - - sprBuffer->SetPalette( pal ); - size_t len = strlen( ( char* ) string ); - char* tmp = ( char* ) malloc( len + 1 ); - memcpy( tmp, ( char * ) string, len + 1 ); - SetupString( tmp, rgn.w, NoColor, initials, enablecap ); - int ystep = 0; - if (Alignment & IE_FONT_SINGLE_LINE) { - for (size_t i = 0; i < len; i++) { - int height = yPos[( unsigned char ) tmp[i] - 1]; - if (ystep < height) - ystep = height; - } - } else { - ystep = size[1].h; - } - if (!ystep) ystep = maxHeight; - int x = psx, y = ystep; - int w = CalcStringWidth( tmp, NoColor ); - if (Alignment & IE_FONT_ALIGN_CENTER) { - x = ( rgn.w - w) / 2; - } else if (Alignment & IE_FONT_ALIGN_RIGHT) { - x = ( rgn.w - w ); - } - if (Alignment & IE_FONT_ALIGN_MIDDLE) { - int h = 0; - for (size_t i = 0; i <= len; i++) { - if (( tmp[i] == 0 ) || ( tmp[i] == '\n' )) - h++; - } - h = h * ystep; - y += ( rgn.h - h ) / 2; - } else if (Alignment & IE_FONT_ALIGN_BOTTOM) { - int h = 1; - for (size_t i = 0; i <= len; i++) { - if (( tmp[i] == 0 ) || ( tmp[i] == '\n' )) - h++; - } - h = h * ystep; - y += ( rgn.h - h ); - } else if (Alignment & IE_FONT_ALIGN_TOP) { - y += 5; - } - - Video* video = core->GetVideoDriver(); - int row = 0; - for (size_t i = 0; i < len; i++) { - if (( ( unsigned char ) tmp[i] ) == '[' && !NoColor) { - i++; - char tag[256]; - tag[0]=0; - - for (int k = 0; k < 256 && i=startrow) ) { - enablecap=true; - } - continue; - } - - - if (strnicmp( tag, "color=", 6 ) == 0) { - unsigned int r,g,b; - if (sscanf( tag, "color=%02X%02X%02X", &r, &g, &b ) != 3) - continue; - const Color c = {(unsigned char) r,(unsigned char)g, (unsigned char)b, 0}; - Palette* newPal = core->CreatePalette( c, palette->back ); - sprBuffer->SetPalette( newPal ); - gamedata->FreePalette( newPal ); - continue; - } - if (stricmp( tag, "/color" ) == 0) { - sprBuffer->SetPalette( pal ); - continue; - } - - if (stricmp( "p", tag ) == 0) { - psx = x; - continue; - } - if (stricmp( "/p", tag ) == 0) { - psx = PARAGRAPH_START_X; - } - continue; - } - - if (row < startrow) { - if (tmp[i] == 0) { - row++; - } - continue; - } - if (( tmp[i] == 0 ) || ( tmp[i] == '\n' )) { - y += ystep; - x = psx; - int w = CalcStringWidth( &tmp[i + 1], NoColor ); - if (initials_rows > 0) { - initials_rows--; - x += initials_x; - w += initials_x; - } - if (Alignment & IE_FONT_ALIGN_CENTER) { - x = ( rgn.w - w ) / 2; - } else if (Alignment & IE_FONT_ALIGN_RIGHT) { - x = ( rgn.w - w ); - } - continue; - } - unsigned char currChar = ( unsigned char ) tmp[i] - 1; - if (initials && capital && enablecap) { - x = initials->PrintInitial( x, y, rgn, currChar ); - initials_x = x; - - //how many more lines to be indented (one was already indented) - initials_rows = (initials->maxHeight-1)/maxHeight; - enablecap = false; - continue; - } - video->BlitSpriteRegion( sprBuffer, size[currChar], - x + rgn.x, y + rgn.y - yPos[currChar], true, &rgn ); - if (cursor && ( i == curpos )) { - video->BlitSprite( cursor, x + rgn.x, - y + rgn.y, true, &rgn ); - } - x += size[currChar].w; - } - if (cursor && ( curpos == len )) { - video->BlitSprite( cursor, x + rgn.x, - y + rgn.y, true, &rgn ); - } - free( tmp ); -} - -void Font::Print(Region rgn, const unsigned char* string, Palette* hicolor, - unsigned char Alignment, bool anchor, Font* initials, - Sprite2D* cursor, unsigned int curpos, bool NoColor) const -{ - Print(rgn, rgn, string, hicolor, Alignment, anchor, initials, cursor, curpos, NoColor); -} - -void Font::Print(Region cliprgn, Region rgn, const unsigned char* string, - Palette* hicolor, unsigned char Alignment, bool anchor, Font* initials, - Sprite2D* cursor, unsigned int curpos, bool NoColor) const -{ - bool enablecap=false; - int capital = 0; - if (initials) - { - capital=1; - enablecap=true; - } - - unsigned int psx = PARAGRAPH_START_X; - Palette* pal = hicolor; - if (!pal) { - pal = palette; - } - if (initials==this) { - initials = NULL; - } - - sprBuffer->SetPalette( pal ); - size_t len = strlen( ( char* ) string ); - char* tmp = ( char* ) malloc( len + 1 ); - memcpy( tmp, ( char * ) string, len + 1 ); - while (len > 0 && (tmp[len - 1] == '\n' || tmp[len - 1] == '\r')) { - // ignore trailing newlines - tmp[len - 1] = 0; - len--; - } - - SetupString( tmp, rgn.w, NoColor, initials, capital ); - int ystep = 0; - if (Alignment & IE_FONT_SINGLE_LINE) { - - for (size_t i = 0; i < len; i++) { - if (tmp[i] == 0) continue; - int height = yPos[( unsigned char ) tmp[i] - 1]; - if (ystep < height) - ystep = height; - } - } else { - ystep = size[1].h; - } - if (!ystep) ystep = maxHeight; - int x = psx, y = ystep; - Video* video = core->GetVideoDriver(); - - if (Alignment & IE_FONT_ALIGN_CENTER) { - int w = CalcStringWidth( tmp, NoColor ); - x = ( rgn.w - w ) / 2; - } else if (Alignment & IE_FONT_ALIGN_RIGHT) { - int w = CalcStringWidth( tmp, NoColor ); - x = ( rgn.w - w ); - } - - if (Alignment & IE_FONT_ALIGN_MIDDLE) { - int h = 0; - for (size_t i = 0; i <= len; i++) { - if (tmp[i] == 0) - h++; - } - h = h * ystep; - y += ( rgn.h - h ) / 2; - } else if (Alignment & IE_FONT_ALIGN_BOTTOM) { - int h = 1; - for (size_t i = 0; i <= len; i++) { - if (tmp[i] == 0) - h++; - } - h = h * ystep; - y += ( rgn.h - h ); - } else if (Alignment & IE_FONT_ALIGN_TOP) { - y += 5; - } - for (size_t i = 0; i < len; i++) { - if (( ( unsigned char ) tmp[i] ) == '[' && !NoColor) { - i++; - char tag[256]; - tag[0]=0; - for (int k = 0; k < 256 && iCreatePalette( c, palette->back ); - sprBuffer->SetPalette( newPal ); - gamedata->FreePalette( newPal ); - continue; - } - if (stricmp( tag, "/color" ) == 0) { - sprBuffer->SetPalette( pal ); - continue; - } - if (stricmp( "p", tag ) == 0) { - psx = x; - continue; - } - if (stricmp( "/p", tag ) == 0) { - psx = PARAGRAPH_START_X; - continue; - } - continue; - } - - if (tmp[i] == 0) { - y += ystep; - x = psx; - int w = CalcStringWidth( &tmp[i + 1], NoColor ); - if (Alignment & IE_FONT_ALIGN_CENTER) { - x = ( rgn.w - w ) / 2; - } else if (Alignment & IE_FONT_ALIGN_RIGHT) { - x = ( rgn.w - w ); - } - continue; - } - unsigned char currChar = ( unsigned char ) tmp[i] - 1; - if (initials && capital) { - x = initials->PrintInitial( x, y, rgn, currChar ); - enablecap=false; - continue; - } - video->BlitSpriteRegion( sprBuffer, size[currChar], - x + rgn.x, y + rgn.y - yPos[currChar], - anchor, &cliprgn ); - if (cursor && ( curpos == i )) - video->BlitSprite( cursor, x + rgn.x, y + rgn.y, anchor, &cliprgn ); - x += size[currChar].w; - } - if (cursor && ( curpos == len )) { - video->BlitSprite( cursor, x + rgn.x, y + rgn.y, anchor, &cliprgn ); - } - free( tmp ); -} - -int Font::PrintInitial(int x, int y, const Region &rgn, unsigned char currChar) const -{ - Video *video = core->GetVideoDriver(); - video->BlitSpriteRegion( sprBuffer, size[currChar], - x + rgn.x, y + rgn.y - yPos[currChar], true, &rgn ); - x += size[currChar].w; - return x; -} - -int Font::CalcStringWidth(const char* string, bool NoColor) const -{ - size_t ret = 0, len = strlen( string ); - for (size_t i = 0; i < len; i++) { - if (( ( unsigned char ) string[i] ) == '[' && !NoColor) { - while(i width) { - // we wrapped, force a new line somewhere - if (!endword && ( x == psx )) - lastpos = ( int ) pos; - else - string[lastpos] = 0; - x = psx; - if (initials_rows > 0) { - initials_rows--; - x += initials_x; - } - } - if (string[pos] == 0) { - continue; - } - endword = false; - if (string[pos] == '\r') - string[pos] = ' '; - if (string[pos] == '\n') { - // force a new line here - string[pos] = 0; - x = psx; - wx = 0; - if (initials_rows > 0) { - initials_rows--; - x += initials_x; - } - lastpos = ( int ) pos; - endword = true; - continue; - } - if (( ( unsigned char ) string[pos] ) == '[' && !NoColor) { - pos++; - if (pos>=len) - break; - char tag[256]; - int k = 0; - for (k = 0; k < 256; k++) { - if (string[pos] == ']') { - tag[k] = 0; - break; - } - tag[k] = string[pos++]; - } - if (strnicmp( tag, "capital=",8)==0) { - int capital = 0; - sscanf( tag, "capital=%d", &capital); - if (capital) { - enablecap=true; - } - continue; - } - if (stricmp( "p", tag ) == 0) { - psx = x; - continue; - } - if (stricmp( "/p", tag ) == 0) { - psx = PARAGRAPH_START_X; - continue; - } - continue; - } - - if (string[pos] && string[pos] != ' ') { - string[pos] = ( unsigned char ) (string[pos] - FirstChar); - } - - wx += size[( unsigned char ) string[pos] - 1].w; - if (initials && enablecap) { - wx += initials->size[(unsigned char) string[pos] - 1].w; - enablecap=false; - initials_x = wx; - //how many more lines to be indented (one was already indented) - initials_rows = (initials->maxHeight-1)/maxHeight; - continue; - } - if (( string[pos] == ' ' ) || ( string[pos] == '-' )) { - x += wx; - wx = 0; - lastpos = ( int ) pos; - endword = true; - } - } -} - -Palette* Font::GetPalette() const -{ - assert(palette); - palette->IncRef(); - return palette; -} - -void Font::SetPalette(Palette* pal) -{ - if (palette) palette->Release(); - pal->IncRef(); - palette = pal; -} - -void Font::SetFirstChar( unsigned char first) -{ - FirstChar = first; -} diff --git a/project/jni/application/gemrb/gemrb/core/Font.h b/project/jni/application/gemrb/gemrb/core/Font.h deleted file mode 100644 index df2f06f38..000000000 --- a/project/jni/application/gemrb/gemrb/core/Font.h +++ /dev/null @@ -1,112 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -/** - * @file Font.h - * Declares Font, class for manipulating images serving as fonts - * @author The GemRB Project - */ - -#ifndef FONT_H -#define FONT_H - -#include "globals.h" -#include "exports.h" - -#include - -class Palette; -class Sprite2D; - -struct StringList { - Sprite2D*** strings; - unsigned int* heights; - unsigned int* lengths; - int StringCount; - int starty; - int curx; - int cury; -}; - -#define IE_FONT_ALIGN_LEFT 0x00 -#define IE_FONT_ALIGN_CENTER 0x01 -#define IE_FONT_ALIGN_RIGHT 0x02 -#define IE_FONT_ALIGN_BOTTOM 0x04 -#define IE_FONT_ALIGN_TOP 0x10 //Single-Line and Multi-Line Text -#define IE_FONT_ALIGN_MIDDLE 0x20 //Only for single line Text -#define IE_FONT_SINGLE_LINE 0x40 - -/** - * @class Font - * Class for using and manipulating images serving as fonts - */ - -class GEM_EXPORT Font { -private: - int count; - Palette* palette; - Sprite2D* sprBuffer; - unsigned char FirstChar; - - short xPos[256]; - short yPos[256]; - - // For the temporary bitmap - unsigned char* tmpPixels; - unsigned int width, height; -public: - /** ResRef of the Font image */ - ieResRef ResRef; - int maxHeight; - Region size[256]; -public: - Font(int w, int h, Palette* palette); - ~Font(void); - void AddChar(unsigned char* spr, int w, int h, short xPos, short yPos); - /** Call this after adding all characters */ - void FinalizeSprite(bool cK, int index); - - void Print(Region cliprgn, Region rgn, const unsigned char* string, - Palette* color, unsigned char Alignment, bool anchor = false, - Font* initials = NULL, Sprite2D* cursor = NULL, - unsigned int curpos = 0, bool NoColor = false) const; - void Print(Region rgn, const unsigned char* string, Palette* color, - unsigned char Alignment, bool anchor = false, - Font* initials = NULL, Sprite2D* cursor = NULL, - unsigned int curpos = 0, bool NoColor = false) const; - void PrintFromLine(int startrow, Region rgn, const unsigned char* string, - Palette* color, unsigned char Alignment, - Font* initials = NULL, Sprite2D* cursor = NULL, - unsigned int curpos = 0, bool NoColor = false) const; - - Palette* GetPalette() const; - void SetPalette(Palette* pal); - /** Returns width of the string rendered in this font in pixels */ - int CalcStringWidth(const char* string, bool NoColor = false) const; - void SetupString(char* string, unsigned int width, bool NoColor = false, Font *initials = NULL, bool enablecap = false) const; - /** Sets ASCII code of the first character in the font. - * (it allows remapping numeric fonts from \000 to '0') */ - void SetFirstChar(unsigned char first); - -private: - int PrintInitial(int x, int y, const Region &rgn, unsigned char currChar) const; -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/GUI/Button.cpp b/project/jni/application/gemrb/gemrb/core/GUI/Button.cpp deleted file mode 100644 index c2d4efa17..000000000 --- a/project/jni/application/gemrb/gemrb/core/GUI/Button.cpp +++ /dev/null @@ -1,728 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "GUI/Button.h" - -#include "GUI/GameControl.h" -#include "GUI/EventMgr.h" -#include "GUI/ScrollBar.h" -#include "GUI/Window.h" - -#include "defsounds.h" -#include "win32def.h" - -#include "GameData.h" -#include "Interface.h" -#include "Palette.h" -#include "Variables.h" -#include "Video.h" - -Button::Button() -{ - Unpressed = Pressed = Selected = Disabled = NULL; - State = IE_GUI_BUTTON_UNPRESSED; - ResetEventHandler( ButtonOnPress ); - ResetEventHandler( ButtonOnDoublePress ); - ResetEventHandler( ButtonOnShiftPress ); - ResetEventHandler( ButtonOnRightPress ); - ResetEventHandler( ButtonOnDragDrop ); - ResetEventHandler( ButtonOnDrag ); - ResetEventHandler( MouseEnterButton ); - ResetEventHandler( MouseLeaveButton ); - ResetEventHandler( MouseOverButton ); - //Text = ( char * ) calloc( 64, sizeof(char) ); - Text = NULL; - hasText = false; - font = core->GetButtonFont(); - normal_palette = NULL; - disabled_palette = font->GetPalette()->Copy(); - for (int i = 0; i < 256; i++) { - disabled_palette->col[i].r = ( disabled_palette->col[i].r * 2 ) / 3; - disabled_palette->col[i].g = ( disabled_palette->col[i].g * 2 ) / 3; - disabled_palette->col[i].b = ( disabled_palette->col[i].b * 2 ) / 3; - } - Flags = IE_GUI_BUTTON_NORMAL; - ToggleState = false; - Picture = NULL; - Clipping = 1.0; - memset(&SourceRGB,0,sizeof(SourceRGB)); - memset(&DestRGB,0,sizeof(DestRGB)); - memset( borders, 0, sizeof( borders )); - starttime = 0; - Anchor.null(); -} -Button::~Button() -{ - Video* video = core->GetVideoDriver(); - video->FreeSprite( Disabled ); - video->FreeSprite( Selected ); - video->FreeSprite( Pressed ); - video->FreeSprite( Unpressed ); - video->FreeSprite( Picture ); - ClearPictureList(); - if (Text) { - free( Text ); - } - gamedata->FreePalette( normal_palette); - gamedata->FreePalette( disabled_palette); -} -/** Sets the 'type' Image of the Button to 'img'. -'type' may assume the following values: -- IE_GUI_BUTTON_UNPRESSED -- IE_GUI_BUTTON_PRESSED -- IE_GUI_BUTTON_SELECTED -- IE_GUI_BUTTON_DISABLED */ -void Button::SetImage(unsigned char type, Sprite2D* img) -{ - switch (type) { - case IE_GUI_BUTTON_UNPRESSED: - case IE_GUI_BUTTON_LOCKED: - case IE_GUI_BUTTON_LOCKED_PRESSED: - core->GetVideoDriver()->FreeSprite( Unpressed ); - Unpressed = img; - break; - - case IE_GUI_BUTTON_SECOND: - case IE_GUI_BUTTON_PRESSED: - core->GetVideoDriver()->FreeSprite( Pressed ); - Pressed = img; - break; - - case IE_GUI_BUTTON_SELECTED: - core->GetVideoDriver()->FreeSprite( Selected ); - Selected = img; - break; - - case IE_GUI_BUTTON_DISABLED: - case IE_GUI_BUTTON_THIRD: - core->GetVideoDriver()->FreeSprite( Disabled ); - Disabled = img; - break; - } - Changed = true; -} - -/** make SourceRGB go closer to DestRGB */ -void Button::CloseUpColor() -{ - if (!starttime) return; - //using the realtime timer, because i don't want to - //handle Game at this point - unsigned long newtime; - - Changed = true; - newtime = GetTickCount(); - if (newtimeFlags&WF_FLOAT) ) { - return; - } - Changed = false; - if (XPos == 65535 || Width == 0) { - return; - } - - Video * video = core->GetVideoDriver(); - - // Button image - if (!( Flags & IE_GUI_BUTTON_NO_IMAGE )) { - Sprite2D* Image = NULL; - - switch (State) { - case IE_GUI_BUTTON_UNPRESSED: - case IE_GUI_BUTTON_LOCKED: - case IE_GUI_BUTTON_LOCKED_PRESSED: - Image = Unpressed; - break; - - case IE_GUI_BUTTON_SECOND: - case IE_GUI_BUTTON_PRESSED: - Image = Pressed; - if (! Image) - Image = Unpressed; - break; - - case IE_GUI_BUTTON_SELECTED: - Image = Selected; - if (! Image) - Image = Unpressed; - break; - - case IE_GUI_BUTTON_DISABLED: - case IE_GUI_BUTTON_THIRD: - Image = Disabled; - if (! Image) - Image = Unpressed; - break; - } - if (Image) { - // FIXME: maybe it's useless... - int xOffs = ( Width / 2 ) - ( Image->Width / 2 ); - int yOffs = ( Height / 2 ) - ( Image->Height / 2 ); - - video->BlitSprite( Image, x + XPos + xOffs, y + YPos + yOffs, true ); - } - } - - if (State == IE_GUI_BUTTON_PRESSED) { - //shift the writing/border a bit - x+= 2; - y+= 2; - } - - // Button picture - if (Picture && (Flags & IE_GUI_BUTTON_PICTURE) ) { - // Picture is drawn centered - int xOffs = ( Width / 2 ) - ( Picture->Width / 2 ); - int yOffs = ( Height / 2 ) - ( Picture->Height / 2 ); - if (Flags & IE_GUI_BUTTON_HORIZONTAL) { - xOffs += x + XPos + Picture->XPos; - yOffs += y + YPos + Picture->YPos; - video->BlitSprite( Picture, xOffs, yOffs, true ); - Region r = Region( xOffs, yOffs + (int) (Picture->Height * Clipping), Picture->Width, (int) (Picture->Height*(1.0 - Clipping)) ); - video->DrawRect( r, SourceRGB, true ); - // do NOT uncomment this, you can't change Changed or invalidate things from - // the middle of Window::DrawWindow() -- it needs moving to somewhere else - //CloseUpColor(); - } - else { - Region r( x + XPos + xOffs, y + YPos + yOffs, (int)(Picture->Width * Clipping), Picture->Height ); - video->BlitSprite( Picture, x + XPos + xOffs + Picture->XPos, y + YPos + yOffs + Picture->YPos, true, &r ); - } - } - - // Composite pictures (paperdolls/description icons) - if (!PictureList.empty() && (Flags & IE_GUI_BUTTON_PICTURE) ) { - std::list::iterator iter = PictureList.begin(); - int xOffs = 0, yOffs = 0; - if (Flags & IE_GUI_BUTTON_CENTER_PICTURES) { - // Center the hotspots of all pictures - xOffs = Width/2; - yOffs = Height/2; - } else if (Flags & IE_GUI_BUTTON_BG1_PAPERDOLL) { - // Display as-is - xOffs = 0; - yOffs = 0; - } else { - // Center the first picture, and align the rest to that - xOffs = Width/2 - (*iter)->Width/2 + (*iter)->XPos; - yOffs = Height/2 - (*iter)->Height/2 + (*iter)->YPos; - } - - for (; iter != PictureList.end(); ++iter) { - video->BlitSprite( *iter, x + XPos + xOffs, y + YPos + yOffs, true ); - } - } - - // Button picture - if (AnimPicture) { - int xOffs = ( Width / 2 ) - ( AnimPicture->Width / 2 ); - int yOffs = ( Height / 2 ) - ( AnimPicture->Height / 2 ); - Region r( x + XPos + xOffs, y + YPos + yOffs, (int)(AnimPicture->Width * Clipping), AnimPicture->Height ); - - if (Flags & IE_GUI_BUTTON_CENTER_PICTURES) { - video->BlitSprite( AnimPicture, x + XPos + xOffs + AnimPicture->XPos, y + YPos + yOffs + AnimPicture->YPos, true, &r ); - } else { - video->BlitSprite( AnimPicture, x + XPos + xOffs, y + YPos + yOffs, true, &r ); - } - } - - // Button label - if (hasText && ! ( Flags & IE_GUI_BUTTON_NO_TEXT )) { - Palette* ppoi = normal_palette; - int align = 0; - - if (State == IE_GUI_BUTTON_DISABLED) - ppoi = disabled_palette; - // FIXME: hopefully there's no button which sinks when selected - // AND has text label - //else if (State == IE_GUI_BUTTON_PRESSED || State == IE_GUI_BUTTON_SELECTED) { - - if (Flags & IE_GUI_BUTTON_ALIGN_LEFT) - align |= IE_FONT_ALIGN_LEFT; - else if (Flags & IE_GUI_BUTTON_ALIGN_RIGHT) - align |= IE_FONT_ALIGN_RIGHT; - else - align |= IE_FONT_ALIGN_CENTER; - - if (Flags & IE_GUI_BUTTON_ALIGN_TOP) - align |= IE_FONT_ALIGN_TOP; - else if (Flags & IE_GUI_BUTTON_ALIGN_BOTTOM) - align |= IE_FONT_ALIGN_BOTTOM; - else - align |= IE_FONT_ALIGN_MIDDLE; - - if (! (Flags & IE_GUI_BUTTON_MULTILINE)) { - align |= IE_FONT_SINGLE_LINE; - } - font->Print( Region( x + XPos, y + YPos, Width - 2, Height - 2), - ( unsigned char * ) Text, ppoi, - (ieByte) align, true ); - } - - if (! (Flags&IE_GUI_BUTTON_NO_IMAGE)) { - for (int i = 0; i < MAX_NUM_BORDERS; i++) { - ButtonBorder *fr = &borders[i]; - if (! fr->enabled) continue; - - Region r = Region( x + XPos + fr->dx1, y + YPos + fr->dy1, Width - (fr->dx1 + fr->dx2 + 1), Height - (fr->dy1 + fr->dy2 + 1) ); - video->DrawRect( r, fr->color, fr->filled ); - } - } -} -/** Sets the Button State */ -void Button::SetState(unsigned char state) -{ - if (state > IE_GUI_BUTTON_LOCKED_PRESSED) {// If wrong value inserted - return; - } - if (State != state) { - Changed = true; - State = state; - } -} -void Button::SetBorder(int index, int dx1, int dy1, int dx2, int dy2, const Color &color, bool enabled, bool filled) -{ - if (index >= MAX_NUM_BORDERS) - return; - - ButtonBorder *fr = &borders[index]; - fr->dx1 = dx1; - fr->dy1 = dy1; - fr->dx2 = dx2; - fr->dy2 = dy2; - fr->color = color; - fr->enabled = enabled; - fr->filled = filled; - Changed = true; -} - -void Button::EnableBorder(int index, bool enabled) -{ - if (index >= MAX_NUM_BORDERS) - return; - - if (borders[index].enabled != enabled) { - borders[index].enabled = enabled; - Changed = true; - } -} - -void Button::SetFont(Font* newfont) -{ - font = newfont; -} -/** Handling The default button (enter) */ -void Button::OnSpecialKeyPress(unsigned char Key) -{ - if (State != IE_GUI_BUTTON_DISABLED && State != IE_GUI_BUTTON_LOCKED) { - if (Key == GEM_RETURN) { - if (Flags & IE_GUI_BUTTON_DEFAULT ) { - RunEventHandler( ButtonOnPress ); - return; - } - } - else if (Key == GEM_ESCAPE) { - if (Flags & IE_GUI_BUTTON_CANCEL ) { - RunEventHandler( ButtonOnPress ); - return; - } - } - } - Control::OnSpecialKeyPress(Key); -} - -/** Mouse Button Down */ -void Button::OnMouseDown(unsigned short x, unsigned short y, - unsigned short Button, unsigned short Mod) -{ - if (State == IE_GUI_BUTTON_DISABLED) { - Control::OnMouseDown(x,y,Button,Mod); - return; - } - - if (core->GetDraggedItem () && !ButtonOnDragDrop) { - Control::OnMouseDown(x,y,Button,Mod); - return; - } - - ScrollBar* scrlbr = (ScrollBar*) sb; - if (!scrlbr) { - Control *ctrl = Owner->GetScrollControl(); - if (ctrl && (ctrl->ControlType == IE_GUI_SCROLLBAR)) { - scrlbr = (ScrollBar *) ctrl; - } - } - - //Button == 1 means Left Mouse Button - switch(Button&GEM_MB_NORMAL) { - case GEM_MB_ACTION: - // We use absolute screen position here, so drag_start - // remains valid even after window/control is moved - drag_start.x = Owner->XPos + XPos + x; - drag_start.y = Owner->YPos + YPos + y; - - if (State == IE_GUI_BUTTON_LOCKED) { - SetState( IE_GUI_BUTTON_LOCKED_PRESSED ); - return; - } - SetState( IE_GUI_BUTTON_PRESSED ); - if (Flags & IE_GUI_BUTTON_SOUND) { - core->PlaySound( DS_BUTTON_PRESSED ); - } - if ((Button & GEM_MB_DOUBLECLICK) && ButtonOnDoublePress) { - RunEventHandler( ButtonOnDoublePress ); - printMessage("Button","Doubleclick detected\n",GREEN); - } - break; - case GEM_MB_SCRLUP: - if (scrlbr) { - scrlbr->ScrollUp(); - core->RedrawAll(); - } - break; - case GEM_MB_SCRLDOWN: - if (scrlbr) { - scrlbr->ScrollDown(); - core->RedrawAll(); - } - break; - } -} -/** Mouse Button Up */ -void Button::OnMouseUp(unsigned short x, unsigned short y, - unsigned short Button, unsigned short Mod) -{ - if (State == IE_GUI_BUTTON_DISABLED) { - return; - } - - //what was just dropped? - int dragtype = 0; - if (core->GetDraggedItem ()) dragtype=1; - if (core->GetDraggedPortrait ()) dragtype=2; - - //if something was dropped, but it isn't handled here: it didn't happen - if (dragtype && !ButtonOnDragDrop) - return; - - switch (State) { - case IE_GUI_BUTTON_PRESSED: - if (ToggleState) { - SetState( IE_GUI_BUTTON_SELECTED ); - } else { - SetState( IE_GUI_BUTTON_UNPRESSED ); - } - break; - case IE_GUI_BUTTON_LOCKED_PRESSED: - SetState( IE_GUI_BUTTON_LOCKED ); - break; - } - - //in case of dragged/dropped portraits, allow the event to happen even - //when we are out of bound - if (dragtype!=2) { - if (( x >= Width ) || ( y >= Height )) { - return; - } - } - if (Flags & IE_GUI_BUTTON_CHECKBOX) { - //checkbox - ToggleState = !ToggleState; - if (ToggleState) - SetState( IE_GUI_BUTTON_SELECTED ); - else - SetState( IE_GUI_BUTTON_UNPRESSED ); - if (VarName[0] != 0) { - ieDword tmp = 0; - core->GetDictionary()->Lookup( VarName, tmp ); - tmp ^= Value; - core->GetDictionary()->SetAt( VarName, tmp ); - Owner->RedrawControls( VarName, tmp ); - } - } else { - if (Flags & IE_GUI_BUTTON_RADIOBUTTON) { - //radio button - ToggleState = true; - SetState( IE_GUI_BUTTON_SELECTED ); - } - if (VarName[0] != 0) { - core->GetDictionary()->SetAt( VarName, Value ); - Owner->RedrawControls( VarName, Value ); - } - } - - switch (dragtype) { - case 1: - RunEventHandler( ButtonOnDragDrop ); - return; - case 2: - RunEventHandler( ButtonOnDragDropPortrait ); - return; - } - - if ((Button&GEM_MB_NORMAL) == GEM_MB_ACTION) { - if ((Mod & GEM_MOD_SHIFT) && ButtonOnShiftPress) - RunEventHandler( ButtonOnShiftPress ); - else - RunEventHandler( ButtonOnPress ); - } else { - if (Button == GEM_MB_MENU && ButtonOnRightPress) - RunEventHandler( ButtonOnRightPress ); - } -} - -void Button::OnMouseOver(unsigned short x, unsigned short y) -{ - Owner->Cursor = IE_CURSOR_NORMAL; - if (State == IE_GUI_BUTTON_DISABLED) { - return; - } - - if ( RunEventHandler( MouseOverButton )) { - //event handler destructed this object - return; - } - - //well, no more flags for buttons, and the portraits we can perform action on - //are in fact 'draggable multiline pictures' (with image) - if ((Flags & IE_GUI_BUTTON_DISABLED_P) == IE_GUI_BUTTON_PORTRAIT) { - GameControl *gc = core->GetGameControl(); - if (gc) { - Owner->Cursor = gc->GetDefaultCursor(); - } - } - - if (State == IE_GUI_BUTTON_LOCKED) { - return; - } - - //portrait buttons are draggable and locked - if ((Flags & IE_GUI_BUTTON_DRAGGABLE) && - (State == IE_GUI_BUTTON_PRESSED || State ==IE_GUI_BUTTON_LOCKED_PRESSED)) { - // We use absolute screen position here, so drag_start - // remains valid even after window/control is moved - int dx = Owner->XPos + XPos + x - drag_start.x; - int dy = Owner->YPos + YPos + y - drag_start.y; - core->GetDictionary()->SetAt( "DragX", dx ); - core->GetDictionary()->SetAt( "DragY", dy ); - drag_start.x = (ieWord) (drag_start.x + dx); - drag_start.y = (ieWord) (drag_start.y + dy); - RunEventHandler( ButtonOnDrag ); - } -} - -void Button::OnMouseEnter(unsigned short /*x*/, unsigned short /*y*/) -{ - if (State == IE_GUI_BUTTON_DISABLED) { - return; - } - - if (MouseEnterButton !=0 && VarName[0] != 0) { - core->GetDictionary()->SetAt( VarName, Value ); - } - - RunEventHandler( MouseEnterButton ); -} - -void Button::OnMouseLeave(unsigned short /*x*/, unsigned short /*y*/) -{ - if (State == IE_GUI_BUTTON_DISABLED) { - return; - } - - if (MouseLeaveButton !=0 && VarName[0] != 0) { - core->GetDictionary()->SetAt( VarName, Value ); - } - - RunEventHandler( MouseLeaveButton ); -} - - -/** Sets the Text of the current control */ -void Button::SetText(const char* string) -{ - free(Text); - Text = NULL; - if (string == NULL) { - hasText = false; - } else if (string[0] == 0) { - hasText = false; - } else { - Text = strndup( string, 255 ); - if (Flags&IE_GUI_BUTTON_LOWERCASE) - strlwr( Text ); - else if (Flags&IE_GUI_BUTTON_CAPS) - strupr( Text ); - hasText = true; - } - Changed = true; -} - -/** Set Event Handler */ -bool Button::SetEvent(int eventType, EventHandler handler) -{ - Changed = true; - - switch (eventType) { - case IE_GUI_BUTTON_ON_PRESS: - ButtonOnPress = handler; - break; - case IE_GUI_MOUSE_OVER_BUTTON: - MouseOverButton = handler; - break; - case IE_GUI_MOUSE_ENTER_BUTTON: - MouseEnterButton = handler; - break; - case IE_GUI_MOUSE_LEAVE_BUTTON: - MouseLeaveButton = handler; - break; - case IE_GUI_BUTTON_ON_SHIFT_PRESS: - ButtonOnShiftPress = handler; - break; - case IE_GUI_BUTTON_ON_RIGHT_PRESS: - ButtonOnRightPress = handler; - break; - case IE_GUI_BUTTON_ON_DRAG_DROP: - ButtonOnDragDrop = handler; - break; - case IE_GUI_BUTTON_ON_DRAG_DROP_PORTRAIT: - ButtonOnDragDropPortrait = handler; - break; - case IE_GUI_BUTTON_ON_DRAG: - ButtonOnDrag = handler; - break; - case IE_GUI_BUTTON_ON_DOUBLE_PRESS: - ButtonOnDoublePress = handler; - break; - default: - return false; - } - - return true; -} - -/** Redraws a button from a given radio button group */ -void Button::RedrawButton(const char* VariableName, unsigned int Sum) -{ - if (strnicmp( VarName, VariableName, MAX_VARIABLE_LENGTH )) { - return; - } - if (State == IE_GUI_BUTTON_DISABLED) { - return; - } - if (Flags & IE_GUI_BUTTON_RADIOBUTTON) { - ToggleState = ( Sum == Value ); - } //radio button, exact value - else if (Flags & IE_GUI_BUTTON_CHECKBOX) { - ToggleState = !!( Sum & Value ); - } //checkbox, bitvalue - else { - return; - } //other buttons, nothing to redraw - if (ToggleState) { - SetState(IE_GUI_BUTTON_SELECTED); - } else { - SetState(IE_GUI_BUTTON_UNPRESSED); - } -} -/** Sets the Picture */ -void Button::SetPicture(Sprite2D* newpic) -{ - core->GetVideoDriver()->FreeSprite( Picture ); - ClearPictureList(); - Picture = newpic; - Changed = true; - Flags |= IE_GUI_BUTTON_PICTURE; - Owner->Invalidate(); -} - -/** Clears the list of Pictures */ -void Button::ClearPictureList() -{ - Video* video = core->GetVideoDriver(); - for (std::list::iterator iter = PictureList.begin(); - iter != PictureList.end(); ++iter) - video->FreeSprite( *iter ); - PictureList.clear(); - Changed = true; - Owner->Invalidate(); -} - -/** Add picture to the end of the list of Pictures */ -void Button::StackPicture(Sprite2D* Picture) -{ - PictureList.push_back(Picture); - Changed = true; - Flags |= IE_GUI_BUTTON_PICTURE; - Owner->Invalidate(); -} - -bool Button::IsPixelTransparent(unsigned short x, unsigned short y) -{ - // some buttons have hollow Image frame filled w/ Picture - // some buttons in BG2 are text only (if BAM == 'GUICTRL') - if (Picture || PictureList.size() || ! Unpressed) return false; - return Unpressed->IsPixelTransparent(x, y); -} - -// Set palette used for drawing button label in normal state -void Button::SetTextColor(const Color &fore, const Color &back) -{ - gamedata->FreePalette( normal_palette ); - normal_palette = core->CreatePalette( fore, back ); - Changed = true; -} - -void Button::SetHorizontalOverlay(double clip, const Color &src, const Color &dest) -{ - if ((Clipping>clip) || !(Flags&IE_GUI_BUTTON_HORIZONTAL) ) { - Flags |= IE_GUI_BUTTON_HORIZONTAL; - SourceRGB=src; - DestRGB=dest; - starttime = GetTickCount(); - starttime += 40; - } - Clipping = clip; - Changed = true; -} - -void Button::SetAnchor(ieWord x, ieWord y) -{ - Anchor = Point(x,y); -} diff --git a/project/jni/application/gemrb/gemrb/core/GUI/Button.h b/project/jni/application/gemrb/gemrb/core/GUI/Button.h deleted file mode 100644 index 35c6cf2a1..000000000 --- a/project/jni/application/gemrb/gemrb/core/GUI/Button.h +++ /dev/null @@ -1,219 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -/** - * @file Button.h - * Declares Button widget, for displaying buttons in the GUI - * @author GemRB Development Team - */ - - -#ifndef BUTTON_H -#define BUTTON_H - -#include "GUI/Control.h" - -#include "exports.h" - -#include "Font.h" -#include "Sprite2D.h" - -#include - -class Palette; - -// NOTE: keep these synchronized with GUIDefines.py!!! -#define IE_GUI_BUTTON_UNPRESSED 0 -#define IE_GUI_BUTTON_PRESSED 1 -#define IE_GUI_BUTTON_SELECTED 2 -#define IE_GUI_BUTTON_DISABLED 3 -// Like DISABLED, but processes MouseOver events and draws UNPRESSED bitmap -#define IE_GUI_BUTTON_LOCKED 4 -// Draws the disabled bitmap, but otherwise works like unpressed -#define IE_GUI_BUTTON_THIRD 5 -#define IE_GUI_BUTTON_SECOND 6 -#define IE_GUI_BUTTON_LOCKED_PRESSED 7 //all the same as LOCKED - -#define IE_GUI_BUTTON_NO_IMAGE 0x00000001 // don't draw image (BAM) -#define IE_GUI_BUTTON_PICTURE 0x00000002 // draw picture (BMP, MOS, ...) -#define IE_GUI_BUTTON_SOUND 0x00000004 -#define IE_GUI_BUTTON_ALT_SOUND 0x00000008 -#define IE_GUI_BUTTON_CHECKBOX 0x00000010 // or radio button -#define IE_GUI_BUTTON_RADIOBUTTON 0x00000020 // sticks in a state -#define IE_GUI_BUTTON_DEFAULT 0x00000040 // enter key triggers it -#define IE_GUI_BUTTON_ANIMATED 0x00000080 - -//these bits are hardcoded in the .chu structure -#define IE_GUI_BUTTON_ALIGN_LEFT 0x00000100 -#define IE_GUI_BUTTON_ALIGN_RIGHT 0x00000200 -#define IE_GUI_BUTTON_ALIGN_TOP 0x00000400 -#define IE_GUI_BUTTON_ALIGN_BOTTOM 0x00000800 -#define IE_GUI_BUTTON_ANCHOR 0x00001000 //not implemented yet -#define IE_GUI_BUTTON_LOWERCASE 0x00002000 -#define IE_GUI_BUTTON_MULTILINE 0x00004000 // don't set the single line flag -//end of hardcoded part -#define IE_GUI_BUTTON_DRAGGABLE 0x00008000 -#define IE_GUI_BUTTON_NO_TEXT 0x00010000 // don't draw button label -#define IE_GUI_BUTTON_PLAYRANDOM 0x00020000 -#define IE_GUI_BUTTON_PLAYONCE 0x00040000 - -#define IE_GUI_BUTTON_CENTER_PICTURES 0x00080000 // center button's PictureList -#define IE_GUI_BUTTON_BG1_PAPERDOLL 0x00100000 // BG1-style paperdoll PictureList -#define IE_GUI_BUTTON_HORIZONTAL 0x00200000 // horizontal clipping of overlay -#define IE_GUI_BUTTON_CANCEL 0x00400000 // cancel key triggers it -#define IE_GUI_BUTTON_CAPS 0x00800000 // convert text to uppercase - -//composite button flags -#define IE_GUI_BUTTON_NORMAL 0x00000004 // default button, doesn't stick -#define IE_GUI_BUTTON_PORTRAIT 0x0000c002 // portrait -#define IE_GUI_BUTTON_DISABLED_P 0x0000c003 // disabled portrait - -// !!! Keep these synchronized with GUIDefines.py !!! -#define IE_GUI_BUTTON_ON_PRESS 0x00000000 -#define IE_GUI_MOUSE_OVER_BUTTON 0x00000001 -#define IE_GUI_MOUSE_ENTER_BUTTON 0x00000002 -#define IE_GUI_MOUSE_LEAVE_BUTTON 0x00000003 -#define IE_GUI_BUTTON_ON_SHIFT_PRESS 0x00000004 -#define IE_GUI_BUTTON_ON_RIGHT_PRESS 0x00000005 -#define IE_GUI_BUTTON_ON_DRAG_DROP 0x00000006 -#define IE_GUI_BUTTON_ON_DRAG_DROP_PORTRAIT 0x00000007 -#define IE_GUI_BUTTON_ON_DRAG 0x00000008 -#define IE_GUI_BUTTON_ON_DOUBLE_PRESS 0x00000009 - -/** Border/frame settings for a button */ -struct ButtonBorder { - int dx1; - int dy1; - int dx2; - int dy2; - Color color; - bool filled; - bool enabled; -}; - -#define MAX_NUM_BORDERS 3 - - -/** - * @class Button - * Button widget, used mainly for buttons, but also for PixMaps (static images) - * or for Toggle Buttons. - */ - -class GEM_EXPORT Button : public Control { -public: - Button(); - ~Button(); - /** Sets the 'type' Image of the Button to 'img'. - 'type' may assume the following values: - - IE_GUI_BUTTON_UNPRESSED - - IE_GUI_BUTTON_PRESSED - - IE_GUI_BUTTON_SELECTED - - IE_GUI_BUTTON_DISABLED */ - void SetImage(unsigned char type, Sprite2D* img); - /** Draws the Control on the Output Display */ - void Draw(unsigned short x, unsigned short y); - /** Sets the Button State */ - void SetState(unsigned char state); - /** Sets the Text of the current control */ - void SetText(const char* string); - /** Sets the Picture */ - void SetPicture(Sprite2D* Picture); - /** Clears the list of Pictures */ - void ClearPictureList(); - /** Add picture to the end of the list of Pictures */ - void StackPicture(Sprite2D* Picture); - /** Sets border/frame parameters */ - void SetBorder(int index, int dx1, int dy1, int dx2, int dy2, const Color &color, bool enabled = false, bool filled = false); - /** Sets horizontal overlay, used in portrait hp overlay */ - void SetHorizontalOverlay(double clip, const Color &src, const Color &dest); - /** Sets font used for drawing button label */ - void SetFont(Font* newfont); - /** Enables or disables specified border/frame */ - void EnableBorder(int index, bool enabled); -public: // Public Events - /** Mouse Enter */ - void OnMouseEnter(unsigned short x, unsigned short y); - /** Mouse Leave */ - void OnMouseLeave(unsigned short x, unsigned short y); - /** Mouse Over */ - void OnMouseOver(unsigned short x, unsigned short y); - /** Mouse Button Down */ - void OnMouseDown(unsigned short x, unsigned short y, unsigned short Button, - unsigned short Mod); - /** Mouse Button Up */ - void OnMouseUp(unsigned short x, unsigned short y, unsigned short Button, - unsigned short Mod); - /** A special key has been pressed */ - void OnSpecialKeyPress(unsigned char Key); - /** Set handler for specified event */ - bool SetEvent(int eventType, EventHandler handler); - /** Button Pressed Event Script Function Name */ - EventHandler ButtonOnPress; - EventHandler ButtonOnShiftPress; - EventHandler ButtonOnRightPress; - EventHandler ButtonOnDoublePress; - EventHandler ButtonOnDragDrop; - EventHandler ButtonOnDragDropPortrait; - EventHandler ButtonOnDrag; - EventHandler MouseEnterButton; - EventHandler MouseLeaveButton; - EventHandler MouseOverButton; - /** Refreshes the button from a radio group */ - void RedrawButton(const char* VariableName, unsigned int Sum); - /** Set palette used for drawing button label in normal state. */ - void SetTextColor(const Color &fore, const Color &back); - /** Sets percent (0-1.0) of width for clipping picture */ - void SetPictureClipping(double clip) { Clipping = clip; } - void SetAnchor(ieWord x, ieWord y); -private: // Private attributes - char* Text; - bool hasText; - Font* font; - bool ToggleState; - Palette* normal_palette; - Palette* disabled_palette; - /** Button Unpressed Image */ - Sprite2D* Unpressed; - /** Button Pressed Image */ - Sprite2D* Pressed; - /** Button Selected Image */ - Sprite2D* Selected; - /** Button Disabled Image */ - Sprite2D* Disabled; - /** Pictures to Apply when the hasPicture flag is set */ - Sprite2D* Picture; - /** If non-empty, list of Pictures to draw when hasPicture is set */ - std::list PictureList; - /** The current state of the Button */ - unsigned char State; - double Clipping; - Point drag_start; - /** HP Bar over portraits */ - unsigned long starttime; - Color SourceRGB, DestRGB; - Point Anchor; - /** frame settings */ - ButtonBorder borders[MAX_NUM_BORDERS]; - bool IsPixelTransparent (unsigned short x, unsigned short y); - void CloseUpColor(); -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/GUI/Console.cpp b/project/jni/application/gemrb/gemrb/core/GUI/Console.cpp deleted file mode 100644 index ba602847f..000000000 --- a/project/jni/application/gemrb/gemrb/core/GUI/Console.cpp +++ /dev/null @@ -1,221 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "GUI/Console.h" - -#include "win32def.h" - -#include "GameData.h" -#include "Interface.h" -#include "Palette.h" -#include "ScriptEngine.h" -#include "Video.h" -#include "GUI/EventMgr.h" - -Console::Console(void) -{ - Cursor = NULL; - Back = NULL; - max = 128; - Buffer = ( unsigned char * ) malloc( max ); - Buffer[0] = 0; - for(size_t i=0;iGetVideoDriver(); - - gamedata->FreePalette( palette ); - video->FreeSprite( Cursor ); -} - -/** Draws the Console on the Output Display */ -void Console::Draw(unsigned short x, unsigned short y) -{ - if (Back) { - core->GetVideoDriver()->BlitSprite( Back, 0, y, true ); - } - Color black = { - 0x00, 0x00, 0x00, 0xff - }; - Region r( x + XPos, y + YPos, Width, Height ); - core->GetVideoDriver()->DrawRect( r, black ); - font->Print( r, Buffer, palette, - IE_FONT_ALIGN_LEFT | IE_FONT_ALIGN_MIDDLE, true, NULL, - Cursor, CurPos, true ); -} -/** Set Font */ -void Console::SetFont(Font* f) -{ - if (f != NULL) { - font = f; - } -} -/** Set Cursor */ -void Console::SetCursor(Sprite2D* cur) -{ - if (cur != NULL) { - Cursor = cur; - } -} -/** Set BackGround */ -void Console::SetBackGround(Sprite2D* back) -{ - //if 'back' is NULL then no BackGround will be drawn - Back = back; -} -/** Sets the Text of the current control */ -void Console::SetText(const char* string) -{ - strncpy( ( char * ) Buffer, string, max ); -} -/** Key Press Event */ -void Console::OnKeyPress(unsigned char Key, unsigned short /*Mod*/) -{ - if (Key >= 0x20) { - size_t len = strlen( ( char* ) Buffer ); - if (len + 1 < max) { - for (size_t i = len; i > CurPos; i--) { - Buffer[i] = Buffer[i - 1]; - } - Buffer[CurPos++] = Key; - Buffer[len + 1] = 0; - } - } -} -/** Special Key Press */ -void Console::OnSpecialKeyPress(unsigned char Key) -{ - size_t len; - - switch (Key) { - case GEM_BACKSP: - if (CurPos != 0) { - size_t len = strlen( ( const char * ) Buffer ); - for (size_t i = CurPos; i < len; i++) { - Buffer[i - 1] = Buffer[i]; - } - Buffer[len - 1] = 0; - CurPos--; - } - break; - case GEM_HOME: - CurPos = 0; - break; - case GEM_END: - CurPos = (unsigned short) strlen( (const char * ) Buffer); - break; - case GEM_UP: - HistoryBack(); - break; - case GEM_DOWN: - HistoryForward(); - break; - case GEM_LEFT: - if (CurPos > 0) - CurPos--; - break; - case GEM_RIGHT: - len = strlen( ( const char * ) Buffer ); - if (CurPos < len) { - CurPos++; - } - break; - case GEM_DELETE: - len = strlen( ( const char * ) Buffer ); - if (CurPos < len) { - for (size_t i = CurPos; i < len; i++) { - Buffer[i] = Buffer[i + 1]; - } - } - break; - case GEM_RETURN: - core->GetGUIScriptEngine()->ExecString( ( char* ) Buffer ); - HistoryAdd(false); - Buffer[0] = 0; - CurPos = 0; - HistPos = 0; - Changed = true; - break; - } -} - -//ctrl-up -void Console::HistoryBack() -{ - HistoryAdd(false); - if (HistPos < HistMax-1 && Buffer[0]) { - HistPos++; - } - memcpy(Buffer, History[HistPos], max); - CurPos = (unsigned short) strlen ((const char *) Buffer); -} - -//ctrl-down -void Console::HistoryForward() -{ - HistoryAdd(false); - if (HistPos == 0) { - Buffer[0]=0; - CurPos=0; - return; - } - HistPos--; - memcpy(Buffer, History[HistPos], max); - CurPos = (unsigned short) strlen ((const char *) Buffer); -} - -void Console::HistoryAdd(bool force) -{ - int i; - - if (!force && !Buffer[0]) - return; - for (i=0;i0; i--) { - memcpy(History[i], History[i-1], max); - } - } - memcpy(History[0], Buffer, max); - if (HistMax -#include - -Control::Control() -{ - hasFocus = false; - Changed = true; - InHandler = false; - VarName[0] = 0; - Value = 0; - Flags = 0; - Tooltip = NULL; - Owner = NULL; - XPos = 0; - YPos = 0; - - sb = NULL; - animation = NULL; - AnimPicture = NULL; - ControlType = IE_GUI_INVALID; -} - -Control::~Control() -{ - if (InHandler) { - printMessage("Control","Destroying control inside event handler, crash may occur!\n", LIGHT_RED); - } - core->DisplayTooltip( 0, 0, NULL ); - free (Tooltip); - - delete animation; - - core->GetVideoDriver()->FreeSprite(AnimPicture); -} - -/** Sets the Tooltip text of the current control */ -int Control::SetTooltip(const char* string) -{ - free(Tooltip); - - if ((string == NULL) || (string[0] == 0)) { - Tooltip = NULL; - } else { - Tooltip = strdup (string); - } - Changed = true; - return 0; -} - -/** Sets the tooltip to be displayed on the screen now */ -void Control::DisplayTooltip() -{ - if (Tooltip) - core->DisplayTooltip( Owner->XPos + XPos + Width / 2, Owner->YPos + YPos + Height / 2, this ); - else - core->DisplayTooltip( 0, 0, NULL ); -} - -void Control::ResetEventHandler(EventHandler handler) -{ - handler = NULL; -} - -void Control::SetText(const char* /*string*/) -{ -} - -int Control::RunEventHandler(EventHandler handler) -{ - if (InHandler) { - printMessage("Control","Nested event handlers are not supported!\n", YELLOW); - return -1; - } - if (handler) { - Window *wnd = Owner; - if (!wnd) { - return -1; - } - unsigned short WID = wnd->WindowID; - unsigned short ID = (unsigned short) ControlID; - InHandler = true; - handler->call(); - if (!core->IsValidWindow(WID,wnd) ) { - printMessage ("Control","Owner window destructed!\n", LIGHT_RED); - return -1; - } - if (!wnd->IsValidControl(ID,this) ) { - printMessage ("Control","Control destructed!\n", LIGHT_RED); - return -1; - } - InHandler = false; - } - return 0; -} - -/** Key Press Event */ -void Control::OnKeyPress(unsigned char /*Key*/, unsigned short /*Mod*/) -{ - //print("OnKeyPress: CtrlID = 0x%08X, Key = %c (0x%02hX)\n", (unsigned int) ControlID, Key, Key); -} - -/** Key Release Event */ -void Control::OnKeyRelease(unsigned char /*Key*/, unsigned short /*Mod*/) -{ - //print( "OnKeyRelease: CtrlID = 0x%08X, Key = %c (0x%02hX)\n", (unsigned int) ControlID, Key, Key ); -} - -/** Mouse Enter Event */ -void Control::OnMouseEnter(unsigned short /*x*/, unsigned short /*y*/) -{ -// print("OnMouseEnter: CtrlID = 0x%08X, x = %hd, y = %hd\n", (unsigned int) ControlID, x, y); -} - -/** Mouse Leave Event */ -void Control::OnMouseLeave(unsigned short /*x*/, unsigned short /*y*/) -{ -// print("OnMouseLeave: CtrlID = 0x%08X, x = %hd, y = %hd\n", (unsigned int) ControlID, x, y); -} - -/** Mouse Over Event */ -void Control::OnMouseOver(unsigned short /*x*/, unsigned short /*y*/) -{ - //print("OnMouseOver: CtrlID = 0x%08X, x = %hd, y = %hd\n", (unsigned int) ControlID, x, y); -} - -/** Mouse Button Down */ -void Control::OnMouseDown(unsigned short x, unsigned short y, - unsigned short Button, unsigned short Mod) -{ - if (Button == GEM_MB_SCRLUP || Button == GEM_MB_SCRLDOWN) { - Control *ctrl = Owner->GetScrollControl(); - if (ctrl && (ctrl!=this)) { - ctrl->OnMouseDown(x,y,Button,Mod); - } - } -} - -/** Mouse Button Up */ -void Control::OnMouseUp(unsigned short /*x*/, unsigned short /*y*/, - unsigned short /*Button*/, unsigned short /*Mod*/) -{ - //print("OnMouseUp: CtrlID = 0x%08X, x = %hd, y = %hd, Button = %d, Mos = %hd\n", (unsigned int) ControlID, x, y, Button, Mod); -} - -/** Special Key Press */ -void Control::OnSpecialKeyPress(unsigned char Key) -{ - if (Key == GEM_UP || Key == GEM_DOWN) { - Control *ctrl = Owner->GetScrollControl(); - if (ctrl && (ctrl!=this)) { - ctrl->OnSpecialKeyPress(Key); - } - } -} - -/** Sets the Display Flags */ -int Control::SetFlags(int arg_flags, int opcode) -{ - if ((arg_flags >>24) != ControlType) - return -2; - switch (opcode) { - case BM_SET: - Flags = arg_flags; //set - break; - case BM_AND: - Flags &= arg_flags; - break; - case BM_OR: - Flags |= arg_flags; //turn on - break; - case BM_XOR: - Flags ^= arg_flags; - break; - case BM_NAND: - Flags &= ~arg_flags;//turn off - break; - default: - return -1; - } - Changed = true; - Owner->Invalidate(); - return 0; -} - -void Control::SetAnimPicture(Sprite2D* newpic) -{ - core->GetVideoDriver()->FreeSprite(AnimPicture); - AnimPicture = newpic; - //apparently this is needed too, so the artifacts are not visible - if (Owner->Visible==WINDOW_VISIBLE) { - Changed = true; - Owner->InvalidateForControl(this); - } -} - -/** Sets the Scroll Bar Pointer. If 'ptr' is NULL no Scroll Bar will be linked - to this Control. */ -int Control::SetScrollBar(Control* ptr) -{ - if (ptr && (ptr->ControlType!=IE_GUI_SCROLLBAR)) { - ptr = NULL; - printMessage("Control","Attached control is not a ScrollBar!\n",YELLOW); - return -1; - } - sb = ptr; - Changed = true; - if (ptr) return 1; - return 0; -} diff --git a/project/jni/application/gemrb/gemrb/core/GUI/Control.h b/project/jni/application/gemrb/gemrb/core/GUI/Control.h deleted file mode 100644 index bfd6862d0..000000000 --- a/project/jni/application/gemrb/gemrb/core/GUI/Control.h +++ /dev/null @@ -1,149 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -/** - * @file Control.h - * Declares Control, root class for all widgets except of windows - */ - -#ifndef CONTROL_H -#define CONTROL_H - -#define IE_GUI_BUTTON 0 -#define IE_GUI_PROGRESSBAR 1 //gemrb extension -#define IE_GUI_SLIDER 2 -#define IE_GUI_EDIT 3 -#define IE_GUI_TEXTAREA 5 -#define IE_GUI_LABEL 6 -#define IE_GUI_SCROLLBAR 7 -#define IE_GUI_WORLDMAP 8 // gemrb extension -#define IE_GUI_MAP 9 // gemrb extension -#define IE_GUI_GAMECONTROL 128 -#define IE_GUI_INVALID 255 - -#define IE_GUI_CONTROL_FOCUSED 0x80 - -//this is in the control ID -#define IGNORE_CONTROL 0x10000000 - -#include "RGBAColor.h" -#include "exports.h" -#include "ie_types.h" -#include "win32def.h" - -#include "Callback.h" - -class ControlAnimation; -class Sprite2D; -class Window; - -/** - * @class Control - * Basic Control Object, also called widget or GUI element. Parent class for Labels, Buttons, etc. - * Every GUI element except of a Window is a descendant of this class. - */ - -class GEM_EXPORT Control { -public: - Control(); - virtual ~Control(); - /** Draws the Control on the Output Display */ - virtual void Draw(unsigned short x, unsigned short y) = 0; - /** Sets the Text of the current control */ - virtual void SetText(const char* string); - /** Sets the Tooltip text of the current control */ - int SetTooltip(const char* string); - /** Displays the tooltip text, Worldmap handles this differently */ - virtual void DisplayTooltip(); - /** Variable length is 40-1 (zero terminator) */ - char VarName[MAX_VARIABLE_LENGTH]; - /** the value of the control to add to the variable */ - ieDword Value; - /** various flags based on the control type */ - ieDword Flags; - ControlAnimation* animation; - Sprite2D* AnimPicture; - -public: // Public attributes - /** Defines the Control ID Number used for GUI Scripting */ - ieDword ControlID; - /** X position of control relative to containing window */ - ieWord XPos; - /** Y position of control relative to containing window */ - ieWord YPos; - /** Width of control */ - ieWord Width; - /** Height of control */ - ieWord Height; - /** Type of control */ - ieByte ControlType; - /** Text to display as a tooltip when the mouse cursor hovers - * for some time over the control */ - char* Tooltip; - /** Focused Control */ - bool hasFocus; - /** If true, control is redrawn during next call to gc->DrawWindows. - * Then it's set back to false. */ - bool Changed; - /** True if we are currently in an event handler */ - bool InHandler; - /** Owner Window */ - Window* Owner; - /** Attached Scroll Bar Pointer*/ - Control* sb; -public: //Events - /** Reset/init event handler */ - void ResetEventHandler(EventHandler handler); - /** Returns the Owner */ - Window *GetOwner() const { return Owner; } - /** Set the Flags */ - int SetFlags(int arg_flags, int opcode); - /** Set handler for specified event. Override in child classes */ - virtual bool SetEvent(int eventType, EventHandler handler) = 0; - /** Run specified handler, it may return error code */ - int RunEventHandler(EventHandler handler); - /** Key Press Event */ - virtual void OnKeyPress(unsigned char Key, unsigned short Mod); - /** Key Release Event */ - virtual void OnKeyRelease(unsigned char Key, unsigned short Mod); - /** Mouse Enter Event */ - virtual void OnMouseEnter(unsigned short x, unsigned short y); - /** Mouse Leave Event */ - virtual void OnMouseLeave(unsigned short x, unsigned short y); - /** Mouse Over Event */ - virtual void OnMouseOver(unsigned short x, unsigned short y); - /** Mouse Button Down */ - virtual void OnMouseDown(unsigned short x, unsigned short y, - unsigned short Button, unsigned short Mod); - /** Mouse Button Up */ - virtual void OnMouseUp(unsigned short x, unsigned short y, - unsigned short Button, unsigned short Mod); - /** Special Key Press */ - virtual void OnSpecialKeyPress(unsigned char Key); - virtual bool IsPixelTransparent(unsigned short /*x*/, unsigned short /*y*/) { - return false; - } - /** Sets the animation picture ref */ - void SetAnimPicture(Sprite2D* Picture); - /** Sets the Scroll Bar Pointer */ - int SetScrollBar(Control* ptr); -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/GUI/EventMgr.cpp b/project/jni/application/gemrb/gemrb/core/GUI/EventMgr.cpp deleted file mode 100644 index bae164a47..000000000 --- a/project/jni/application/gemrb/gemrb/core/GUI/EventMgr.cpp +++ /dev/null @@ -1,440 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "GUI/EventMgr.h" - -#include "GUI/GameControl.h" - -#include "win32def.h" - -#include "Interface.h" -#include "Video.h" -#include "GUI/Window.h" - -EventMgr::EventMgr(void) -{ - last_win_focused = NULL; - // Last window focused for mouse events (eg, with a click). Used to determine MouseUp events - last_win_mousefocused = NULL; - // Last window we were over. Used to determine MouseEnter and MouseLeave events - last_win_over = NULL; - MButtons = 0; - dc_x = 0; - dc_y = 0; - dc_time = 0; - dc_delay = 250; - rk_delay = 250; - rk_flags = GEM_RK_DISABLE; -} - -EventMgr::~EventMgr(void) -{ -} - -void EventMgr::SetOnTop(int Index) -{ - std::vector< int>::iterator t; - for (t = topwin.begin(); t != topwin.end(); ++t) { - if (( *t ) == Index) { - topwin.erase( t ); - break; - } - } - if (topwin.size() != 0) { - topwin.insert( topwin.begin(), Index ); - } else { - topwin.push_back( Index ); - } -} - -void EventMgr::SetDefaultFocus(Window *win) -{ - if (!last_win_focused) { - last_win_focused = win; - last_win_focused->SetFocused(last_win_focused->GetControl(0)); - } - last_win_over = NULL; -} - -/** Adds a Window to the Event Manager */ -void EventMgr::AddWindow(Window* win) -{ - unsigned int i; - - if (win == NULL) { - return; - } - bool found = false; - for (i = 0; i < windows.size(); i++) { - if (windows[i] == win) { - goto ok; - } - if(windows[i]==NULL) { - windows[i] = win; -ok: - SetOnTop( i ); - found = true; - break; - } - } - if (!found) { - windows.push_back( win ); - if (windows.size() == 1) - topwin.push_back( 0 ); - else - SetOnTop( ( int ) windows.size() - 1 ); - } - SetDefaultFocus(win); -} -/** Frees and Removes all the Windows in the Array */ -void EventMgr::Clear() -{ - topwin.clear(); - windows.clear(); - last_win_focused = NULL; - last_win_mousefocused = NULL; - last_win_over = NULL; -} - -/** Remove a Window from the array */ -void EventMgr::DelWindow(Window *win) -//unsigned short WindowID, const char *WindowPack) -{ - if (last_win_focused == win) { - last_win_focused = NULL; - } - if (last_win_mousefocused == win) { - last_win_mousefocused = NULL; - } - if (last_win_over == win) { - last_win_over = NULL; - } - - if (windows.size() == 0) { - return; - } - int pos = -1; - std::vector< Window*>::iterator m; - for (m = windows.begin(); m != windows.end(); ++m) { - pos++; - if ( (*m) == win) { - (*m) = NULL; - std::vector< int>::iterator t; - for (t = topwin.begin(); t != topwin.end(); ++t) { - if ( (*t) == pos) { - topwin.erase( t ); - return; - } - } - printMessage("EventManager","Couldn't find window",YELLOW); - } - } -} - -/** BroadCast Mouse Move Event */ -void EventMgr::MouseMove(unsigned short x, unsigned short y) -{ - if (windows.size() == 0) { - return; - } - if (!last_win_focused) { - return; - } - GameControl *gc = core->GetGameControl(); - if (gc) { - // for scrolling - gc->OnGlobalMouseMove(x, y); - } - std::vector< int>::iterator t; - std::vector< Window*>::iterator m; - for (t = topwin.begin(); t != topwin.end(); ++t) { - m = windows.begin(); - m += ( *t ); - Window *win = *m; - if (win == NULL) - continue; - if (!win->Visible) - continue; - if (( win->XPos <= x ) && ( win->YPos <= y )) { - //Maybe we are on the window, let's check - if (( win->XPos + win->Width >= x ) && - ( win->YPos + win->Height >= y )) { - //Yes, we are on the Window - //Let's check if we have a Control under the Mouse Pointer - Control* ctrl = win->GetControl( x, y, true ); - //look for the low priority flagged controls (mostly static labels) - if (ctrl == NULL) { - ctrl = win->GetControl( x, y, false ); - } - if (win != last_win_over || ctrl != win->GetOver()) { - // Remove tooltip if mouse moved to different control - core->DisplayTooltip( 0, 0, NULL ); - if (last_win_over) { - last_win_over->OnMouseLeave( x, y ); - } - last_win_over = win; - win->OnMouseEnter( x, y, ctrl ); - } - if (ctrl != NULL) { - win->OnMouseOver( x, y ); - } - RefreshCursor(win->Cursor); - return; - } - } - //stop going further - if (( *m )->Visible == WINDOW_FRONT) - break; - } - core->DisplayTooltip( 0, 0, NULL ); -} - -void EventMgr::RefreshCursor(int idx) -{ - Video *video = core->GetVideoDriver(); - if (idx&IE_CURSOR_GRAY) { - video->SetMouseGrayed(true); - } else { - video->SetMouseGrayed(false); - } - idx &= IE_CURSOR_MASK; - video->SetCursor( core->Cursors[idx], core->Cursors[idx ^ 1] ); -} - -bool EventMgr::ClickMatch(unsigned short x, unsigned short y, unsigned long thisTime) -{ - if (dc_x+10x+10) return false; - if (dc_y+10y+10) return false; - if (dc_time::iterator t; - std::vector< Window*>::iterator m; - Control *ctrl; - unsigned long thisTime; - - thisTime = GetTickCount(); - if (ClickMatch(x, y, thisTime)) { - Button |= GEM_MB_DOUBLECLICK; - dc_x = 0; - dc_y = 0; - dc_time = 0; - } else { - dc_x = x; - dc_y = y; - dc_time = thisTime+dc_delay; - } - MButtons |= Button; - for (t = topwin.begin(); t != topwin.end(); ++t) { - m = windows.begin(); - m += ( *t ); - if (( *m ) == NULL) - continue; - if (!( *m )->Visible) - continue; - if (( ( *m )->XPos <= x ) && ( ( *m )->YPos <= y )) { - //Maybe we are on the window, let's check - if (( ( *m )->XPos + ( *m )->Width >= x ) && - ( ( *m )->YPos + ( *m )->Height >= y )) { - //Yes, we are on the Window - //Let's check if we have a Control under the Mouse Pointer - ctrl = ( *m )->GetControl( x, y, true ); - if (!ctrl) { - ctrl = ( *m )->GetControl( x, y, false); - } - last_win_mousefocused = *m; - if (ctrl != NULL) { - last_win_mousefocused->SetMouseFocused( ctrl ); - ctrl->OnMouseDown( x - last_win_mousefocused->XPos - ctrl->XPos, y - last_win_mousefocused->YPos - ctrl->YPos, Button, Mod ); - return; - } - } - } - if (( *m )->Visible == WINDOW_FRONT) //stop looking further - break; - } - - if ((Button == GEM_MB_SCRLUP || Button == GEM_MB_SCRLDOWN) && last_win_mousefocused) { - ctrl = last_win_mousefocused->GetScrollControl(); - if (ctrl) { - ctrl->OnMouseDown( x - last_win_mousefocused->XPos - ctrl->XPos, y - last_win_mousefocused->YPos - ctrl->YPos, Button, Mod ); - } - } - - if (last_win_mousefocused) { - last_win_mousefocused->SetMouseFocused(NULL); - } -} -/** BroadCast Mouse Up Event */ -void EventMgr::MouseUp(unsigned short x, unsigned short y, unsigned short Button, - unsigned short Mod) -{ - MButtons &= ~Button; - if (last_win_mousefocused == NULL) return; - Control *last_ctrl_mousefocused = last_win_mousefocused->GetMouseFocus(); - if (last_ctrl_mousefocused == NULL) return; - last_ctrl_mousefocused->OnMouseUp( x - last_win_mousefocused->XPos - last_ctrl_mousefocused->XPos, - y - last_win_mousefocused->YPos - last_ctrl_mousefocused->YPos, Button, Mod ); -} - -/** BroadCast Mouse Idle Event */ -void EventMgr::MouseIdle(unsigned long /*time*/) -{ - if (last_win_over == NULL) return; - Control *ctrl = last_win_over->GetOver(); - if (ctrl == NULL) return; - ctrl->DisplayTooltip(); -} - -/** BroadCast Key Press Event */ -void EventMgr::KeyPress(unsigned char Key, unsigned short Mod) -{ - if (last_win_focused == NULL) return; - Control *ctrl = last_win_focused->GetFocus(); - if (ctrl == NULL) return; - ctrl->OnKeyPress( Key, Mod ); -} -/** BroadCast Key Release Event */ -void EventMgr::KeyRelease(unsigned char Key, unsigned short Mod) -{ - if (last_win_focused == NULL) return; - Control *ctrl = last_win_focused->GetFocus(); - if (Key == GEM_GRAB) { - core->GetVideoDriver()->ToggleGrabInput(); - return; - } - if (ctrl == NULL) return; - ctrl->OnKeyRelease( Key, Mod ); -} - -/** Special Key Press Event */ -void EventMgr::OnSpecialKeyPress(unsigned char Key) -{ - if (!last_win_focused) { - return; - } - Control *ctrl = NULL; - - // tab shows tooltips - if (Key == GEM_TAB) { - if (last_win_over != NULL) { - Control *ctrl = last_win_over->GetOver(); - if (ctrl != NULL) { - ctrl->DisplayTooltip(); - } - } - } - //the default control will get only GEM_RETURN - else if (Key == GEM_RETURN) { - ctrl = last_win_focused->GetDefaultControl(0); - } - //the default cancel control will get only GEM_ESCAPE - else if (Key == GEM_ESCAPE) { - ctrl = last_win_focused->GetDefaultControl(1); - } - - //if there was no default button set, then the current focus will get it - if (!ctrl) { - ctrl = last_win_focused->GetFocus(); - } - //if one is under focus, use the default scroll focus - if (!ctrl) { - if (Key == GEM_UP || Key == GEM_DOWN) { - ctrl = last_win_focused->GetScrollControl(); - } - } - if (ctrl) { - switch (ctrl->ControlType) { - //scrollbars will receive only mousewheel events - case IE_GUI_SCROLLBAR: - if (Key != GEM_UP && Key != GEM_DOWN) { - return; - } - break; - //buttons will receive only GEM_RETURN - case IE_GUI_BUTTON: - if (Key != GEM_RETURN && Key!=GEM_ESCAPE) { - return; - } - break; - case IE_GUI_GAMECONTROL: - //gamecontrols will receive all special keys - break; - case IE_GUI_EDIT: - case IE_GUI_TEXTAREA: - //editboxes and textareas will receive all special keys - break; - default: - //other controls don't receive any - return; - } - ctrl->OnSpecialKeyPress( Key ); - } -} - -void EventMgr::SetFocused(Window *win, Control *ctrl) -{ - last_win_focused = win; - last_win_focused->SetFocused(ctrl); - //this is to refresh changing mouse cursors should the focus change) - int x,y; - core->GetVideoDriver()->GetMousePos(x,y); - MouseMove((unsigned short) x, (unsigned short) y); -} - -void EventMgr::SetDCDelay(unsigned long t) -{ - dc_delay = t; -} - -void EventMgr::SetRKDelay(unsigned long t) -{ - rk_delay = t; -} - -unsigned long EventMgr::GetRKDelay() -{ - if (rk_flags&GEM_RK_DISABLE) return (unsigned long) ~0; - if (rk_flags&GEM_RK_DOUBLESPEED) return rk_delay/2; - if (rk_flags&GEM_RK_QUADRUPLESPEED) return rk_delay/4; - return rk_delay; -} - -unsigned long EventMgr::SetRKFlags(unsigned long arg, unsigned int op) -{ - unsigned long tmp = rk_flags; - switch (op) { - case BM_SET: tmp = arg; break; - case BM_OR: tmp |= arg; break; - case BM_NAND: tmp &= ~arg; break; - case BM_XOR: tmp ^= arg; break; - case BM_AND: tmp &= arg; break; - default: tmp = 0; break; - } - rk_flags=tmp; - return rk_flags; -} diff --git a/project/jni/application/gemrb/gemrb/core/GUI/EventMgr.h b/project/jni/application/gemrb/gemrb/core/GUI/EventMgr.h deleted file mode 100644 index 938525c2e..000000000 --- a/project/jni/application/gemrb/gemrb/core/GUI/EventMgr.h +++ /dev/null @@ -1,141 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -/** - * @file EventMgr.h - * Declares EventMgr, class distributing events from input devices to GUI windows - * @author The GemRB Project - */ - - -#ifndef EVENTMGR_H -#define EVENTMGR_H - -#include "exports.h" - -#include - -class Control; -class Window; - -#define GEM_LEFT 0x81 -#define GEM_RIGHT 0x82 -#define GEM_UP 0x83 -#define GEM_DOWN 0x84 -#define GEM_DELETE 0x85 -#define GEM_RETURN 0x86 -#define GEM_BACKSP 0x87 -#define GEM_TAB 0x88 -#define GEM_ALT 0x89 -#define GEM_HOME 0x8a -#define GEM_END 0x8b -#define GEM_ESCAPE 0x8c -#define GEM_PGUP 0x8d -#define GEM_PGDOWN 0x8e -#define GEM_GRAB 0x8f - - -#define GEM_MOD_SHIFT 1 -#define GEM_MOD_CTRL 2 -#define GEM_MOD_ALT 4 - -#define GEM_MOUSEOUT 128 - -// Mouse buttons -#define GEM_MB_ACTION 1 -#define GEM_MB_MENU 4 -#define GEM_MB_SCRLUP 8 -#define GEM_MB_SCRLDOWN 16 - -#define GEM_MB_NORMAL 255 -#define GEM_MB_DOUBLECLICK 256 - -#define GEM_RK_DOUBLESPEED 1 -#define GEM_RK_DISABLE 2 -#define GEM_RK_QUADRUPLESPEED 4 - -/** - * @class EventMgr - * Class distributing events from input devices to GUI windows. - * The events are pumped into instance of this class from a Video driver plugin - */ - -class GEM_EXPORT EventMgr { -private: - std::vector< Window*> windows; - std::vector< int> topwin; - - unsigned short dc_x, dc_y; - unsigned long dc_time, dc_delay; - unsigned long rk_delay, rk_flags; -public: - EventMgr(void); - ~EventMgr(void); - /** Adds a Window to the Event Manager */ - void AddWindow(Window* win); - /** Removes a Window from the Event chain */ - //void DelWindow(unsigned short WindowID, const char *WindowPack); - void DelWindow(Window* win); - /** Frees and Removes all the Windows in the Array */ - void Clear(); - /** Call this to change the cursor (moving over windows will change it back) */ - void RefreshCursor(int idx); - /** BroadCast Mouse Move Event */ - void MouseMove(unsigned short x, unsigned short y); - /** BroadCast Mouse Move Event */ - void MouseDown(unsigned short x, unsigned short y, unsigned short Button, - unsigned short Mod); - /** BroadCast Mouse Move Event */ - void MouseUp(unsigned short x, unsigned short y, unsigned short Button, - unsigned short Mod); - /** BroadCast Mouse Idle Event */ - void MouseIdle(unsigned long time); - /** BroadCast Key Press Event */ - void KeyPress(unsigned char Key, unsigned short Mod); - /** BroadCast Key Release Event */ - void KeyRelease(unsigned char Key, unsigned short Mod); - /** Special Ket Press Event */ - void OnSpecialKeyPress(unsigned char Key); - /** Sets focus to the control of the window */ - void SetFocused(Window *win, Control *ctrl); - /** Sets mouse event focus to the control of the window */ - void SetMouseFocused(Window *win, Control *ctrl); - /** Sets the maximum accepted doubleclick delay */ - void SetDCDelay(unsigned long t); - void SetRKDelay(unsigned long t); - unsigned long GetRKDelay(); - unsigned long SetRKFlags(unsigned long arg, unsigned int op); - - /** Mask of which Mouse Buttons are pressed */ - unsigned char MButtons; -private: - /** Last Window focused */ - Window* last_win_focused; - /** Last Window mouse event focused */ - Window* last_win_mousefocused; - /** Last Window under Mouse Pointer*/ - Window* last_win_over; - /** Sets a Window on the Top of the Window Queue */ - void SetDefaultFocus(Window *win); - void SetOnTop(int Index); - bool ClickMatch(unsigned short x, unsigned short y, unsigned long thisTime); -}; - -#endif // ! EVENTMGR_H diff --git a/project/jni/application/gemrb/gemrb/core/GUI/GameControl.cpp b/project/jni/application/gemrb/gemrb/core/GUI/GameControl.cpp deleted file mode 100644 index dafdd4b31..000000000 --- a/project/jni/application/gemrb/gemrb/core/GUI/GameControl.cpp +++ /dev/null @@ -1,2841 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "GUI/GameControl.h" - -#include "strrefs.h" -#include "win32def.h" - -#include "DialogHandler.h" -#include "DisplayMessage.h" -#include "Effect.h" -#include "Font.h" -#include "Game.h" -#include "GameData.h" -#include "GlobalTimer.h" -#include "ImageMgr.h" -#include "Interface.h" -#include "Item.h" -#include "KeyMap.h" -#include "PathFinder.h" -#include "SaveGameIterator.h" -#include "ScriptEngine.h" -#include "TableMgr.h" -#include "TextArea.h" -#include "TileMap.h" -#include "Video.h" -#include "damages.h" -#include "GameScript/GSUtils.h" -#include "GUI/EventMgr.h" -#include "GUI/Window.h" -#include "Scriptable/Container.h" -#include "Scriptable/Door.h" -#include "Scriptable/InfoPoint.h" - -#include - -#define DEBUG_SHOW_INFOPOINTS 0x01 -#define DEBUG_SHOW_CONTAINERS 0x02 -#define DEBUG_SHOW_DOORS DEBUG_SHOW_CONTAINERS -#define DEBUG_SHOW_LIGHTMAP 0x08 - -#define SCROLL_BORDER 5 - -static const Color cyan = { - 0x00, 0xff, 0xff, 0xff -}; -static const Color red = { - 0xff, 0x00, 0x00, 0xff -}; -static const Color magenta = { - 0xff, 0x00, 0xff, 0xff -}; -static const Color green = { - 0x00, 0xff, 0x00, 0xff -}; -/* -static Color white = { - 0xff, 0xff, 0xff, 0xff -}; -*/ -static const Color black = { - 0x00, 0x00, 0x00, 0xff -}; -static const Color blue = { - 0x00, 0x00, 0xff, 0x80 -}; -static const Color gray = { - 0x80, 0x80, 0x80, 0xff -}; - -//Animation* effect; - -#define FORMATIONSIZE 10 -typedef Point formation_type[FORMATIONSIZE]; -ieDword formationcount; -static formation_type *formations=NULL; -static bool mqs = false; -static ieResRef TestSpell="SPWI207"; - -//If one of the actors has tracking on, the gamecontrol needs to display -//arrow markers on the edges to point at detected monsters -//tracterID is the tracker actor's global ID -//distance is the detection distance -void GameControl::SetTracker(Actor *actor, ieDword dist) -{ - trackerID = actor->GetGlobalID(); - distance = dist; -} - -//Multiple Quick saves is an experimental GemRB feature. -//multiple quick saves are kept, their age is determined by the slot -//number. There is an algorithm which keeps about log2(n) slots alive. -//The algorithm is implemented in SaveGameIterator -void GameControl::MultipleQuickSaves(int arg) -{ - mqs=arg==1; -} - -GameControl::GameControl(void) -{ - if (!formations) { - ReadFormations(); - } - //this is the default action, individual actors should have one too - //at this moment we use only this - //maybe we don't even need it - Changed = true; - spellCount = 0; - user = NULL; - lastActorID = 0; - trackerID = 0; - distance = 0; - MouseIsDown = false; - DrawSelectionRect = false; - overDoor = NULL; - overContainer = NULL; - overInfoPoint = NULL; - drawPath = NULL; - pfs.null(); - lastCursor = IE_CURSOR_NORMAL; - moveX = moveY = 0; - scrolling = false; - touchScrollAreasEnabled = false; - numScrollCursor = 0; - DebugFlags = 0; - AIUpdateCounter = 1; - EnableRunning = true; //make this a game flag if you wish - ieDword tmp=0; - - ResetTargetMode(); - - core->GetDictionary()->Lookup("Center",tmp); - if (tmp) { - ScreenFlags=SF_ALWAYSCENTER|SF_CENTERONACTOR; - } else { - ScreenFlags = SF_CENTERONACTOR; - } - core->GetDictionary()->Lookup("TouchScrollAreas",tmp); - if (tmp) { - touchScrollAreasEnabled = true; - touched = false; - scrollAreasWidth = 32; - } - LeftCount = 0; - BottomCount = 0; - RightCount = 0; - TopCount = 0; - DialogueFlags = 0; - dialoghandler = new DialogHandler(); - DisplayText = NULL; -} - -//TODO: -//There could be a custom formation which is saved in the save game -//alternatively, all formations could be saved in some compatible way -//so it doesn't cause problems with the original engine -void GameControl::ReadFormations() -{ - unsigned int i,j; - AutoTable tab("formatio"); - if (!tab) { - // fallback - formationcount = 1; - formations = (formation_type *) calloc(1,sizeof(formation_type) ); - return; - } - formationcount = tab->GetRowCount(); - formations = (formation_type *) calloc(formationcount, sizeof(formation_type)); - for(i=0; iQueryField(i,j*2)); - formations[i][j].x=k; - k=(short) atoi(tab->QueryField(i,j*2+1)); - formations[i][j].y=k; - } - } -} - -//returns a single point offset for a formation -//formation: the formation type -//pos: the actor's slot ID -Point GameControl::GetFormationOffset(ieDword formation, ieDword pos) -{ - if (formation>=formationcount) formation = 0; - if (pos>=FORMATIONSIZE) pos=FORMATIONSIZE-1; - return formations[formation][pos]; -} - -//Moves an actor to a new position, keeping the current formation -//WARNING: don't pass p as a reference because it gets modified -void GameControl::MoveToPointFormation(Actor *actor, unsigned int pos, Point src, Point p) -{ - Map* map = actor->GetCurrentArea() ; - - int formation=core->GetGame()->GetFormation(); - if (pos>=FORMATIONSIZE) pos=FORMATIONSIZE-1; - - // calculate angle - double angle; - double xdiff = src.x - p.x; - double ydiff = src.y - p.y; - if (ydiff == 0) { - if (xdiff > 0) { - angle = M_PI_2; - } else { - angle = -M_PI_2; - } - } else { - angle = atan(xdiff/ydiff); - if (ydiff < 0) angle += M_PI; - } - - // calculate new coordinates by rotating formation around (0,0) - double newx = -formations[formation][pos].x * cos(angle) + formations[formation][pos].y * sin(angle); - double newy = formations[formation][pos].x * sin(angle) + formations[formation][pos].y * cos(angle); - p.x += (int)newx; - p.y += (int)newy; - - if (p.x < 0) p.x = 8; - if (p.y < 0) p.y = 8; - if (p.x > map->GetWidth()*16) p.x = map->GetWidth()*16 - 8; - if (p.y > map->GetHeight()*12) p.y = map->GetHeight()*12 - 8; - - if(map->GetCursor(p) == IE_CURSOR_BLOCKED) { - //we can't get there --> adjust position - p.x/=16; - p.y/=12; - map->AdjustPosition(p); - p.x*=16; - p.y*=12; - } - CreateMovement(actor, p); -} - -void GameControl::Center(unsigned short x, unsigned short y) -{ - Video *video = core->GetVideoDriver(); - Region Viewport = video->GetViewport(); - Viewport.x += x - Viewport.w / 2; - Viewport.y += y - Viewport.h / 2; - core->timer->SetMoveViewPort( Viewport.x, Viewport.y, 0, false ); - video->MoveViewportTo( Viewport.x, Viewport.y ); -} - -// generate an action to do the actual movement -// only PST supports RunToPoint -void GameControl::CreateMovement(Actor *actor, const Point &p) -{ - char Tmp[256]; - - Action *action = NULL; - if (DoubleClick && EnableRunning) { - sprintf( Tmp, "RunToPoint([%d.%d])", p.x, p.y ); - 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 ); - } - - actor->AddAction( action ); - // force action so that we get target recticles immediately - // FIXME - actor->ProcessActions(); -} - -GameControl::~GameControl(void) -{ - //releasing the viewport of GameControl - core->GetVideoDriver()->SetViewport( 0,0,0,0 ); - if (formations) { - free( formations ); - formations = NULL; - } - delete dialoghandler; - if (DisplayText) { - core->FreeString(DisplayText); - } -} - -//Autosave was triggered by the GUI -void GameControl::AutoSave() -{ - core->GetSaveGameIterator()->CreateSaveGame(0, false); -} - -//QuickSave was triggered by the GUI -//mqs is the 'multiple quick saves' flag -void GameControl::QuickSave() -{ - core->GetSaveGameIterator()->CreateSaveGame(1, mqs == 1); -} - -// ArrowSprite cycles -// 321 -// 4 0 -// 567 - -#define D_LEFT 1 -#define D_UP 2 -#define D_RIGHT 4 -#define D_BOTTOM 8 -// Direction Bits -// 326 -// 1 4 -// 98c - -static const int arrow_orientations[16]={ -// 0 1 2 3 4 5 6 7 8 9 a b c d e f - -1, 4, 2, 3, 0,-1, 1,-1, 6, 5,-1,-1, 7,-1,-1,-1 -}; - -//Draws arrow markers along the edge of the game window -//WARNING:don't use reference for point, because it is altered -void GameControl::DrawArrowMarker(const Region &screen, Point p, const Region &viewport) -{ - Video* video = core->GetVideoDriver(); - - //p.x-=viewport.x; - //p.y-=viewport.y; - ieDword draw = 0; - if (p.xGetScrollCursorSprite(0,0); - - tmp = spr->Width; - //tmp = core->ArrowSprites[0]->Width; - - if (p.x>viewport.x+viewport.w-tmp) { - p.x=viewport.x+viewport.w;//-tmp; - draw |= D_RIGHT; - } - - tmp = spr->Height; - //tmp = core->ArrowSprites[0]->Height; - - if (p.y>viewport.y+viewport.h-tmp) { - p.y=viewport.y+viewport.h;//-tmp; - draw |= D_BOTTOM; - } - if (arrow_orientations[draw]>=0) { - video->BlitGameSprite( core->GetScrollCursorSprite(arrow_orientations[draw], 0), p.x+screen.x, p.y+screen.y, 0, black, NULL); - } -} - -/** Draws the Control on the Output Display */ -void GameControl::Draw(unsigned short x, unsigned short y) -{ - bool update_scripts = !(DialogueFlags & DF_FREEZE_SCRIPTS); - - Game* game = core->GetGame(); - if (!game) - return; - - if (((short) Width) <=0 || ((short) Height) <= 0) { - return; - } - - if (Owner->Visible!=WINDOW_VISIBLE) { - return; - } - - Region screen( x + XPos, y + YPos, Width, Height ); - Map *area = core->GetGame()->GetCurrentArea(); - Video* video = core->GetVideoDriver(); - if (!area) { - video->DrawRect( screen, blue, true ); - return; - } - - Region viewport = video->GetViewport(); - if (moveX || moveY) { - viewport.x += moveX; - viewport.y += moveY; - Point mapsize = area->TMap->GetMapSize(); - if ( viewport.x < 0 )//if we are at top of the map - viewport.x = 0; - else if ( (viewport.x + viewport.w) >= mapsize.x) //if we are at the bottom - viewport.x = mapsize.x - viewport.w; - - if ( viewport.y < 0 ) //if we are at the left of the map - viewport.y = 0; - else if ( (viewport.y + viewport.h ) >= mapsize.y ) //if we are at the right - viewport.y = mapsize.y - viewport.h; - - // override any existing viewport moves which may be in progress - core->timer->SetMoveViewPort( viewport.x, viewport.y, 0, false ); - // move it directly ourselves, since we might be paused - video->MoveViewportTo( viewport.x, viewport.y ); - } - video->DrawRect( screen, black, true ); - - // setup outlines - InfoPoint *i; - unsigned int idx; - for (idx = 0; (i = area->TMap->GetInfoPoint( idx )); idx++) { - i->Highlight = false; - if (overInfoPoint == i && target_mode) { - if (i->VisibleTrap(0)) { - i->outlineColor = green; - i->Highlight = true; - continue; - } - } - if (i->VisibleTrap(DebugFlags & DEBUG_SHOW_INFOPOINTS)) { - i->outlineColor = red; // traps - } else if (DebugFlags & DEBUG_SHOW_INFOPOINTS) { - i->outlineColor = blue; // debug infopoints - } else { - continue; - } - i->Highlight = true; - } - - Door *d; - for (idx = 0; (d = area->TMap->GetDoor( idx )); idx++) { - d->Highlight = false; - if (overDoor == d) { - if (target_mode) { - if (d->Visible() && (d->VisibleTrap(0) || (d->Flags & DOOR_LOCKED))) { - // only highlight targettable doors - d->outlineColor = green; - d->Highlight = true; - continue; - } - } else if (!(d->Flags & DOOR_SECRET)) { - // mouse over, not in target mode, no secret door - d->outlineColor = cyan; - d->Highlight = true; - continue; - } - } - if (d->VisibleTrap(0)) { - d->outlineColor = red; // traps - } else if (d->Flags & DOOR_SECRET) { - if (DebugFlags & DEBUG_SHOW_DOORS || d->Flags & DOOR_FOUND) { - d->outlineColor = magenta; // found hidden door - } else { - // secret door is invisible - continue; - } - } else if (DebugFlags & DEBUG_SHOW_DOORS) { - d->outlineColor = cyan; // debug doors - } else { - continue; - } - d->Highlight = true; - } - - Container *c; - for (idx = 0; (c = area->TMap->GetContainer( idx )); idx++) { - c->Highlight = false; - if (overContainer == c && target_mode) { - if (c->VisibleTrap(0) || (c->Flags & CONT_LOCKED)) { - // only highlight targettable containers - c->outlineColor = green; - c->Highlight = true; - continue; - } - } else if (overContainer == c) { - // mouse over, not in target mode - c->outlineColor = cyan; - c->Highlight = true; - continue; - } - if (c->VisibleTrap(0)) { - c->outlineColor = red; // traps - } else if (DebugFlags & DEBUG_SHOW_CONTAINERS) { - c->outlineColor = cyan; // debug containers - } else { - continue; - } - c->Highlight = true; - } - - //drawmap should be here so it updates fog of war - area->DrawMap( screen ); - game->DrawWeather(screen, update_scripts); - - if (trackerID) { - Actor *actor = area->GetActorByGlobalID(trackerID); - - if (actor) { - Actor **monsters = area->GetAllActorsInRadius(actor->Pos, GA_NO_DEAD|GA_NO_LOS, distance); - - int i = 0; - while(monsters[i]) { - Actor *target = monsters[i++]; - if (target->InParty) continue; - if (target->GetStat(IE_NOTRACKING)) continue; - DrawArrowMarker(screen, target->Pos, viewport); - } - delete monsters; - } else { - trackerID = 0; - } - } - - if (ScreenFlags & SF_DISABLEMOUSE) - return; - Point p(lastMouseX, lastMouseY); - video->ConvertToGame( p.x, p.y ); - - // Draw selection rect - if (DrawSelectionRect) { - CalculateSelection( p ); - video->DrawRect( SelectionRect, green, false, true ); - } - - // Show wallpolygons - if (DebugFlags & DEBUG_SHOW_INFOPOINTS) { - - unsigned int count = area->GetWallCount(); - for (unsigned int i = 0; i < count; ++i) { - Wall_Polygon* poly = area->GetWallGroup(i); - if (!poly) continue; - // yellow - Color c; - c.r = 0x7F; - c.g = 0x7F; - c.b = 0; - c.a = 0; - //if polygon is disabled, make it grey - if (poly->wall_flag&WF_DISABLED) { - c.b = 0x7F; - } - - video->DrawPolyline( poly, c, true ); - } - } - - // Draw path - if (drawPath) { - PathNode* node = drawPath; - while (true) { - Point p( ( node-> x*16) + 8, ( node->y*12 ) + 6 ); - if (!node->Parent) { - video->DrawCircle( p.x, p.y, 2, red ); - } else { - short oldX = ( node->Parent-> x*16) + 8, oldY = ( node->Parent->y*12 ) + 6; - video->DrawLine( oldX, oldY, p.x, p.y, green ); - } - if (!node->Next) { - video->DrawCircle( p.x, p.y, 2, green ); - break; - } - node = node->Next; - } - } - - // Draw lightmap - if (DebugFlags & DEBUG_SHOW_LIGHTMAP) { - Sprite2D* spr = area->LightMap->GetSprite2D(); - video->BlitSprite( spr, 0, 0, true ); - video->FreeSprite( spr ); - Region point( p.x / 16, p.y / 12, 2, 2 ); - video->DrawRect( point, red ); - } - - if (core->HasFeature(GF_ONSCREEN_TEXT) && DisplayText) { - core->GetFont(1)->Print(screen, (unsigned char *)DisplayText, core->InfoTextPalette, IE_FONT_ALIGN_CENTER | IE_FONT_ALIGN_MIDDLE, true); - if (update_scripts) { - // just replicating original engine behaviour - if (DisplayTextTime == 0) { - SetDisplayText((char *)NULL, 0); - } else { - DisplayTextTime--; - } - } - } - - if (touchScrollAreasEnabled) { - if (moveY < 0 && scrolling) - video->DrawLine(screen.x+4, screen.y+scrollAreasWidth, screen.w+screen.x-4, screen.y+scrollAreasWidth, red); - else - video->DrawLine(screen.x+4, screen.y+scrollAreasWidth, screen.w+screen.x-4, screen.y+scrollAreasWidth, gray); - if (moveY > 0 && scrolling) - video->DrawLine(screen.x+4, screen.h-scrollAreasWidth, screen.w+screen.x-4, screen.h-scrollAreasWidth, red); - else - video->DrawLine(screen.x+4, screen.h-scrollAreasWidth, screen.w+screen.x-4, screen.h-scrollAreasWidth, gray); - if (moveX < 0 && scrolling) - video->DrawLine(screen.x+scrollAreasWidth, screen.y+4, screen.x+scrollAreasWidth, screen.h+screen.y-4, red); - else - video->DrawLine(screen.x+scrollAreasWidth, screen.y+4, screen.x+scrollAreasWidth, screen.h+screen.y-4, gray); - if (moveX > 0 && scrolling) - video->DrawLine(screen.w+screen.x-scrollAreasWidth, screen.y+4, screen.w+screen.x-scrollAreasWidth, screen.h-4, red); - else - video->DrawLine(screen.w+screen.x-scrollAreasWidth, screen.y+4, screen.w+screen.x-scrollAreasWidth, screen.h-4, gray); - } -} - -/** Key Press Event */ -void GameControl::OnKeyPress(unsigned char Key, unsigned short /*Mod*/) -{ - if (DialogueFlags&DF_IN_DIALOG) { - return; - } - unsigned int i, pc; - Game* game = core->GetGame(); - if (!game) return; - - switch (Key) { - case '0': - game->SelectActor( NULL, false, SELECT_NORMAL ); - i = game->GetPartySize(false)/2+1; - while(i--) { - SelectActor(i, true); - } - break; - case '-': - game->SelectActor( NULL, true, SELECT_NORMAL ); - i = game->GetPartySize(false)/2+1; - while(i--) { - SelectActor(i, false); - } - break; - case '=': - SelectActor(-1); - break; - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - SelectActor(Key-'0'); - break; - case '7': // 1 & 2 - case '8': // 3 & 4 - case '9': // 5 & 6 - game->SelectActor( NULL, false, SELECT_NORMAL ); - i = game->GetPartySize(false); - pc = 2*(Key - '6')-1; - if (pc >= i) { - SelectActor(i, true); - break; - } - SelectActor(pc, true); - SelectActor(pc+1, true); - break; -#ifdef ANDROID - case 'c': // show containers in ANDROID, GEM_ALT is not possible to use - DebugFlags |= DEBUG_SHOW_CONTAINERS; - return; -#endif - default: - core->GetGame()->SetHotKey(toupper(Key)); - break; - } -} - -//Select (or deselect) a new actor (or actors) -void GameControl::SelectActor(int whom, int type) -{ - Game* game = core->GetGame(); - if (whom==-1) { - game->SelectActor( NULL, true, SELECT_NORMAL ); - return; - } - - /* doesn't fall through here */ - Actor* actor = game->FindPC( whom ); - if (!actor) - return; - - if (type==0) { - game->SelectActor( actor, false, SELECT_NORMAL ); - return; - } - if (type==1) { - game->SelectActor( actor, true, SELECT_NORMAL ); - return; - } - - bool was_selected = actor->IsSelected(); - if (game->SelectActor( actor, true, SELECT_REPLACE )) - if (was_selected || (ScreenFlags & SF_ALWAYSCENTER)) { - ScreenFlags |= SF_CENTERONACTOR; - } -} - -//Effect for the ctrl-r cheatkey (resurrect) -static EffectRef heal_ref = { "CurrentHPModifier", -1 }; -static EffectRef damage_ref = { "Damage", -1 }; - -/** Key Release Event */ -void GameControl::OnKeyRelease(unsigned char Key, unsigned short Mod) -{ - unsigned int i; - Game* game = core->GetGame(); - - if (!game) - return; - - if (DialogueFlags&DF_IN_DIALOG) { - if (Mod) return; - switch(Key) { - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - TextArea *ta = core->GetMessageTextArea(); - if (ta) { - ta->OnKeyPress(Key,Mod); - } - } - break; - } - return; - } - //cheatkeys with ctrl- - if (Mod & GEM_MOD_CTRL) { - if (!core->CheatEnabled()) { - return; - } - Map* area = game->GetCurrentArea( ); - if (!area) - return; - Actor *lastActor = area->GetActorByGlobalID(lastActorID); - Point p(lastMouseX, lastMouseY); - core->GetVideoDriver()->ConvertToGame( p.x, p.y ); - switch (Key) { - case 'f': //toggle full screen mode - core->GetVideoDriver()->ToggleFullscreenMode(); - break; - case 'd': //disarm a trap - if (overInfoPoint) { - overInfoPoint->DetectTrap(256); - } - if (overContainer) { - if (overContainer->Trapped && - !( overContainer->TrapDetected )) { - overContainer->TrapDetected = 1; - } - } - if (overDoor) { - if (overDoor->Trapped && - !( overDoor->TrapDetected )) { - overDoor->TrapDetected = 1; - } - } - break; - case 'l': //play an animation (vvc/bam) over an actor - //the original engine was able to swap through all animations - if (lastActor) { - lastActor->AddAnimation("S056ICBL", 0, 0, 0); - } - break; - - case 'c': //force cast a hardcoded spell - //caster is the last selected actor - //target is the door/actor currently under the pointer - if (game->selected.size() > 0) { - Actor *src = game->selected[0]; - Scriptable *target = lastActor; - if (overDoor) { - target = overDoor; - } - if (target) { - src->CastSpell( TestSpell, target, false ); - if (src->LastTarget) { - src->CastSpellEnd(0); - } else { - src->CastSpellPointEnd(0); - } - } - } - break; - - case 'b': //draw a path to the target (pathfinder debug) - //You need to select an origin with ctrl-o first - if (drawPath) { - PathNode* nextNode = drawPath->Next; - PathNode* thisNode = drawPath; - while (true) { - delete( thisNode ); - thisNode = nextNode; - if (!thisNode) - break; - nextNode = thisNode->Next; - } - } - drawPath = core->GetGame()->GetCurrentArea()->FindPath( pfs, p, lastActor?lastActor->size:1 ); - - break; - - case 'o': //set up the origin for the pathfinder - // origin - pfs.x = lastMouseX; - pfs.y = lastMouseY; - core->GetVideoDriver()->ConvertToGame( pfs.x, pfs.y ); - break; - case 'a': //switches through the avatar animations - if (lastActor) { - lastActor->GetNextAnimation(); - } - break; - case 's': //switches through the stance animations - if (lastActor) { - lastActor->GetNextStance(); - } - break; - case 'j': //teleports the selected actors - for (i = 0; i < game->selected.size(); i++) { - Actor* actor = game->selected[i]; - MoveBetweenAreasCore(actor, core->GetGame()->CurrentArea, p, -1, true); - } - break; - - case 'm': //prints a debug dump (ctrl-m in the original game too) - if (!lastActor) { - lastActor = area->GetActor( p, GA_DEFAULT); - } - if (!lastActor) { - // ValidTarget never returns immobile targets, making debugging a nightmare - // so if we don't have an actor, we make really really sure by checking manually - unsigned int count = area->GetActorCount(true); - while (count--) { - Actor *actor = area->GetActor(count, true); - if (actor->IsOver(p)) { - actor->DebugDump(); - } - } - } - if (lastActor) { - lastActor->DebugDump(); - break; - } - if (overDoor) { - overDoor->DebugDump(); - break; - } - if (overContainer) { - overContainer->DebugDump(); - break; - } - if (overInfoPoint) { - overInfoPoint->DebugDump(); - break; - } - core->GetGame()->GetCurrentArea()->DebugDump(Mod & GEM_MOD_SHIFT); - break; - case 'v': //marks some of the map visited (random vision distance) - area->ExploreMapChunk( p, rand()%30, 1 ); - break; - case 'w': // consolidates found ground piles under the pointed pc - area->MoveVisibleGroundPiles(p); - break; - case 'x': // shows coordinates on the map - print( "%s [%d.%d]\n", area->GetScriptName(), p.x, p.y ); - break; - case 'g'://shows loaded areas and other game information - game->DebugDump(); - break; - case 'i'://interact trigger (from the original game) - if (!lastActor) { - lastActor = area->GetActor( p, GA_DEFAULT); - } - if (lastActor && !(lastActor->GetStat(IE_MC_FLAGS)&MC_EXPORTABLE)) { - Actor *target; - int i = game->GetPartySize(true); - if(i<2) break; - i=rand()%i; - do - { - target = game->GetPC(i, true); - if(target==lastActor) continue; - if(target->GetStat(IE_MC_FLAGS)&MC_EXPORTABLE) continue; - - char Tmp[40]; - snprintf(Tmp,sizeof(Tmp),"Interact(\"%s\")",target->GetScriptName() ); - lastActor->AddAction(GenerateAction(Tmp)); - break; - } - while(i--); - } - break; - case 'r'://resurrects actor - if (!lastActor) { - lastActor = area->GetActor( p, GA_DEFAULT); - } - if (lastActor) { - Effect *fx = EffectQueue::CreateEffect(heal_ref, lastActor->GetStat(IE_MAXHITPOINTS), 0x30001, FX_DURATION_INSTANT_PERMANENT); - if (fx) { - core->ApplyEffect(fx, lastActor, lastActor); - } - } - break; - case 't'://advances time - // 7200 (one day) /24 (hours) == 300 - game->AdvanceTime(300*AI_UPDATE_TIME); - //refresh gui here once we got it - break; - - case 'q': //joins actor to the party - if (lastActor && !lastActor->InParty) { - lastActor->ClearActions(); - lastActor->ClearPath(); - char Tmp[40]; - strncpy(Tmp,"JoinParty()",sizeof(Tmp) ); - lastActor->AddAction( GenerateAction(Tmp) ); - } - break; - case 'p': //center on actor - ScreenFlags|=SF_CENTERONACTOR; - ScreenFlags^=SF_ALWAYSCENTER; - break; - case 'k': //kicks out actor - if (lastActor && lastActor->InParty) { - lastActor->ClearActions(); - lastActor->ClearPath(); - char Tmp[40]; - strncpy(Tmp,"LeaveParty()",sizeof(Tmp) ); - lastActor->AddAction( GenerateAction(Tmp) ); - } - break; - case 'y': //kills actor or all enemies - if (Mod & GEM_MOD_SHIFT) { - // mwahaha! - Effect *newfx; - newfx = EffectQueue::CreateEffect(damage_ref, 300, DAMAGE_MAGIC<<16, FX_DURATION_INSTANT_PERMANENT); - Actor *victim; - for (int i = area->GetActorCount(0)-1; i >= 0; i--) { - victim = area->GetActor(i, 0); - if (victim->Modified[IE_EA] == EA_ENEMY) { - core->ApplyEffect(newfx, victim, victim); - } - } - delete newfx; - } else { - if (lastActor) { - //using action so the actor is killed - //correctly (synchronisation) - lastActor->ClearActions(); - lastActor->ClearPath(); - - Effect *newfx; - newfx = EffectQueue::CreateEffect(damage_ref, 300, DAMAGE_MAGIC<<16, FX_DURATION_INSTANT_PERMANENT); - core->ApplyEffect(newfx, lastActor, lastActor); - if (! (lastActor->GetInternalFlag() & IF_REALLYDIED)) { - newfx = EffectQueue::CreateEffect(damage_ref, 300, DAMAGE_ACID<<16, FX_DURATION_INSTANT_PERMANENT); - core->ApplyEffect(newfx, lastActor, lastActor); - newfx = EffectQueue::CreateEffect(damage_ref, 300, DAMAGE_CRUSHING<<16, FX_DURATION_INSTANT_PERMANENT); - core->ApplyEffect(newfx, lastActor, lastActor); - } - delete newfx; - } else if (overContainer) { - overContainer->SetContainerLocked(0); - } else if (overDoor) { - overDoor->SetDoorLocked(0,0); - } - } - break; - case 'z': //shift through the avatar animations backward - if (lastActor) { - lastActor->GetPrevAnimation(); - } - break; - case '1': //change paperdoll armour level - if (! lastActor) - break; - lastActor->NewStat(IE_ARMOR_TYPE,1,MOD_ADDITIVE); - break; - case '4': //show all traps and infopoints - DebugFlags ^= DEBUG_SHOW_INFOPOINTS; - print("Show traps and infopoints %s\n", DebugFlags & DEBUG_SHOW_INFOPOINTS ? "ON" : "OFF"); - break; - case '6': //show the lightmap - DebugFlags ^= DEBUG_SHOW_LIGHTMAP; - print("Show lightmap %s\n", DebugFlags & DEBUG_SHOW_LIGHTMAP ? "ON" : "OFF"); - break; - case '7': //toggles fog of war - core->FogOfWar ^= FOG_DRAWFOG; - print("Show Fog-Of-War: %s\n", core->FogOfWar & FOG_DRAWFOG ? "ON" : "OFF"); - break; - case '8': //show searchmap over area - core->FogOfWar ^= FOG_DRAWSEARCHMAP; - print("Show searchmap %s\n", core->FogOfWar & FOG_DRAWSEARCHMAP ? "ON" : "OFF"); - break; - default: - print( "KeyRelease:%d - %d\n", Key, Mod ); - break; - } - return; //return from cheatkeys - } - switch (Key) { - case 'h': //hard pause - if (DialogueFlags & DF_FREEZE_SCRIPTS) break; - //fallthrough - case ' ': //soft pause - DialogueFlags ^= DF_FREEZE_SCRIPTS; - if (DialogueFlags&DF_FREEZE_SCRIPTS) { - displaymsg->DisplayConstantString(STR_PAUSED,0xff0000); - SetDisplayText(STR_PAUSED, 0); // time 0 = removed instantly on unpause - } else { - displaymsg->DisplayConstantString(STR_UNPAUSED,0xff0000); - } - break; -/* - case 'm': - core->GetGUIScriptEngine()->RunFunction("GUIMA","OpenMapWindow"); - break; - case 'j': - core->GetGUIScriptEngine()->RunFunction("GUIJRNL","OpenJournalWindow"); - break; - case 'i': - core->GetGUIScriptEngine()->RunFunction("GUIINV","OpenInventoryWindow"); - break; - case 'r': - core->GetGUIScriptEngine()->RunFunction("GUIREC","OpenRecordsWindow"); - break; - case 'p': - core->GetGUIScriptEngine()->RunFunction("GUIPR","OpenPriestWindow"); - break; - case 'w': - core->GetGUIScriptEngine()->RunFunction("GUIMG","OpenMageWindow"); - break; -*/ - case 'q': //quicksave - QuickSave(); - break; - case GEM_ALT: //alt key (shows containers) -#ifdef ANDROID - case 'c': // show containers in ANDROID, GEM_ALT is not possible to use -#endif - DebugFlags &= ~DEBUG_SHOW_CONTAINERS; - break; - default: - core->GetKeyMap()->ResolveKey(Key,0); - break; - } -} - -void GameControl::DisplayTooltip() { - Game* game = core->GetGame(); - if (game) { - Map* area = game->GetCurrentArea( ); - if (area) { - Actor *actor = area->GetActorByGlobalID(lastActorID); - if (actor && (actor->GetStat(IE_STATE_ID)&STATE_DEAD || actor->GetInternalFlag()&IF_REALLYDIED)) { - // no tooltips for dead actors! - actor->SetOver( false ); - lastActorID = 0; - actor = NULL; - } - - if (actor) { - char *name = actor->GetName(-1); - int hp = actor->GetStat(IE_HITPOINTS); - int maxhp = actor->GetStat(IE_MAXHITPOINTS); - - char buffer[100]; - if (!core->TooltipBack) { - // single-line tooltips without background (PS:T) - if (actor->InParty) { - snprintf(buffer, 100, "%s: %d/%d", name, hp, maxhp); - } else { - snprintf(buffer, 100, "%s", name); - } - } else { - // a guess at a neutral check - bool neutral = actor->GetStat(IE_EA) == EA_NEUTRAL; - // test for an injured string being present for this game - int strindex = displaymsg->GetStringReference(STR_UNINJURED); - // normal tooltips - if (actor->InParty) { - // in party: display hp - snprintf(buffer, 100, "%s\n%d/%d", name, hp, maxhp); - } else if (neutral) { - // neutral: display name only - snprintf(buffer, 100, "%s", name); - } else if (strindex == -1) { - // non-neutral, not in party, no injured strings: display hp - snprintf(buffer, 100, "%s\n%d/%d", name, hp, maxhp); - } else { - // non-neutral, not in party: display injured string - int strindex; - char *injuredstring = NULL; - // these boundaries are just a guess - if (hp == maxhp) { - strindex = STR_UNINJURED; - } else if (hp > (maxhp*3)/4) { - strindex = STR_INJURED1; - } else if (hp > maxhp/2) { - strindex = STR_INJURED2; - } else if (hp > maxhp/3) { - strindex = STR_INJURED3; - } else { - strindex = STR_INJURED4; - } - strindex = displaymsg->GetStringReference(strindex); - if (strindex != -1) { - injuredstring = core->GetString(strindex, 0); - } - - if (!injuredstring) { - // eek, where did the string go? - snprintf(buffer, 100, "%s\n%d/%d", name, hp, maxhp); - } else { - snprintf(buffer, 100, "%s\n%s", name, injuredstring); - free(injuredstring); - } - } - } - - Point p = actor->Pos; - core->GetVideoDriver()->ConvertToScreen( p.x, p.y ); - p.x += Owner->XPos + XPos; - p.y += Owner->YPos + YPos; - - // hack to position text above PS:T actors - if (!core->TooltipBack) p.y -= actor->size*50; - - // we should probably cope better with moving actors - SetTooltip(buffer); - core->DisplayTooltip(p.x, p.y, this); - return; - } - } - } - - SetTooltip(NULL); - core->DisplayTooltip(0, 0, NULL); - return; -} - -//returns the appropriate cursor over an active region (trap, infopoint, travel region) -int GameControl::GetCursorOverInfoPoint(InfoPoint *overInfoPoint) const -{ - if (target_mode == TARGET_MODE_PICK) { - if (overInfoPoint->VisibleTrap(0)) { - return IE_CURSOR_TRAP; - } - - return IE_CURSOR_STEALTH|IE_CURSOR_GRAY; - } - // traps always display a walk cursor? - if (overInfoPoint->Type == ST_PROXIMITY) { - return IE_CURSOR_WALK; - } - return overInfoPoint->Cursor; -} - -//returns the appropriate cursor over a door -int GameControl::GetCursorOverDoor(Door *overDoor) const -{ - if (!overDoor->Visible()) { - if (target_mode == TARGET_MODE_NONE) { - return IE_CURSOR_BLOCKED; - } else { - return lastCursor|IE_CURSOR_GRAY; - } - } - if (target_mode == TARGET_MODE_PICK) { - if (overDoor->VisibleTrap(0)) { - return IE_CURSOR_TRAP; - } - if (overDoor->Flags & DOOR_LOCKED) { - return IE_CURSOR_LOCK; - } - - return IE_CURSOR_STEALTH|IE_CURSOR_GRAY; - } - return overDoor->Cursor; -} - -//returns the appropriate cursor over a container (or pile) -int GameControl::GetCursorOverContainer(Container *overContainer) const -{ - if (target_mode == TARGET_MODE_PICK) { - if (overContainer->VisibleTrap(0)) { - return IE_CURSOR_TRAP; - } - if (overContainer->Flags & CONT_LOCKED) { - return IE_CURSOR_LOCK2; - } - - return IE_CURSOR_STEALTH|IE_CURSOR_GRAY; - } - return IE_CURSOR_TAKE; -} - -int GameControl::GetDefaultCursor() const -{ - switch(target_mode) { - case TARGET_MODE_TALK: - return IE_CURSOR_TALK; - case TARGET_MODE_ATTACK: - return IE_CURSOR_ATTACK; - case TARGET_MODE_CAST: - return IE_CURSOR_CAST; - case TARGET_MODE_DEFEND: - return IE_CURSOR_DEFEND; - case TARGET_MODE_PICK: - return IE_CURSOR_PICK; - } - return IE_CURSOR_NORMAL; -} - -/** Mouse Over Event */ -void GameControl::OnMouseOver(unsigned short x, unsigned short y) -{ - if (ScreenFlags & SF_DISABLEMOUSE) { - return; - } - - if (touchScrollAreasEnabled) { - int mousescrollspd = core->GetMouseScrollSpeed(); - Region region; - Map* map; - Point mapsize; - Region viewport = core->GetVideoDriver()->GetViewport(); - moveX = 0; - moveY = 0; - // Top scroll area - region=Region(XPos, YPos, Width, YPos+scrollAreasWidth); - if (region.PointInside(x, y)) { - // Check for end of map area - if (viewport.y > 0) - moveY = -mousescrollspd; - } - // Bottom scroll area - region=Region(XPos, Height-scrollAreasWidth, Width, Height); - if (region.PointInside(x, y)) { - // Check for end of map area - map = core->GetGame()->GetCurrentArea(); - if (map != NULL) { - mapsize = map->TMap->GetMapSize(); - if((viewport.y + viewport.h) < mapsize.y) - moveY = mousescrollspd; - } - } - // Left scroll area - region=Region(XPos, YPos, XPos+scrollAreasWidth, Height); - if (region.PointInside(x, y)) { - // Check for end of map area - if(viewport.x > 0) - moveX = -mousescrollspd; - } - // Right scroll area - region=Region(Width-scrollAreasWidth, YPos, Width, Height); - if (region.PointInside(x, y)) { - // Check for end of map area - map = core->GetGame()->GetCurrentArea(); - if (map != NULL) { - mapsize = map->TMap->GetMapSize(); - if((viewport.x + viewport.w) < mapsize.x) - moveX = mousescrollspd; - } - } - if ((moveX != 0 || moveY != 0) && touched) { - scrolling = true; - return; - } else { - moveX = 0; - moveY = 0; - scrolling = false; - Video* video = core->GetVideoDriver(); - video->SetDragCursor(NULL); - } - } - - lastMouseX = x; - lastMouseY = y; - Point p( x,y ); - core->GetVideoDriver()->ConvertToGame( p.x, p.y ); - if (MouseIsDown && ( !DrawSelectionRect )) { - if (( abs( p.x - StartX ) > 5 ) || ( abs( p.y - StartY ) > 5 )) { - DrawSelectionRect = true; - } - } - Game* game = core->GetGame(); - if (!game) return; - Map* area = game->GetCurrentArea( ); - if (!area) return; - int nextCursor = area->GetCursor( p ); - //make the invisible area really invisible - if (nextCursor == IE_CURSOR_INVALID) { - Owner->Cursor = IE_CURSOR_BLOCKED; - lastCursor = IE_CURSOR_BLOCKED; - return; - } - - overInfoPoint = area->TMap->GetInfoPoint( p, true ); - if (overInfoPoint) { - //nextCursor = overInfoPoint->Cursor; - nextCursor = GetCursorOverInfoPoint(overInfoPoint); - } - - if (overDoor) { - overDoor->Highlight = false; - } - if (overContainer) { - overContainer->Highlight = false; - } - Actor *lastActor = area->GetActorByGlobalID(lastActorID); - if (lastActor) { - lastActor->SetOver( false ); - } - - overDoor = area->TMap->GetDoor( p ); - overContainer = area->TMap->GetContainer( p ); - - if (!DrawSelectionRect) { - if (overDoor) { - nextCursor = GetCursorOverDoor(overDoor); - } - - if (overContainer) { - nextCursor = GetCursorOverContainer(overContainer); - } - - Actor *prevActor = lastActor; - lastActor = area->GetActor( p, target_types); - if (lastActor != prevActor) { - // we store prevActor so we can remove the tooltip on actor change - // (maybe we should be checking this and actor movements every frame?) - SetTooltip(NULL); - core->DisplayTooltip(0, 0, this); - } - - if ((target_types & GA_NO_SELF) && lastActor ) { - if (lastActor == core->GetFirstSelectedActor()) { - lastActor=NULL; - } - } - - if (lastActor) { - lastActorID = lastActor->GetGlobalID(); - lastActor->SetOver( true ); - ieDword type = lastActor->GetStat(IE_EA); - if (type >= EA_EVILCUTOFF || type == EA_GOODBUTRED) { - nextCursor = IE_CURSOR_ATTACK; - } else if ( type > EA_CHARMED ) { - nextCursor = IE_CURSOR_TALK; - //don't let the pc to talk to frozen/stoned creatures - ieDword state = lastActor->GetStat(IE_STATE_ID); - if (state & STATE_CANTMOVE) { - nextCursor |= IE_CURSOR_GRAY; - } - } else { - nextCursor = IE_CURSOR_NORMAL; - } - } else { - lastActorID = 0; - } - - if (target_mode == TARGET_MODE_TALK) { - nextCursor = IE_CURSOR_TALK; - if (!lastActor) { - nextCursor |= IE_CURSOR_GRAY; - } else { - //don't let the pc to talk to frozen/stoned creatures - ieDword state = lastActor->GetStat(IE_STATE_ID); - if (state & STATE_CANTMOVE) { - nextCursor |= IE_CURSOR_GRAY; - } - } - } else if (target_mode == TARGET_MODE_ATTACK) { - nextCursor = IE_CURSOR_ATTACK; - if (overDoor) { - if (!overDoor->Visible()) { - nextCursor |= IE_CURSOR_GRAY; - } - } else if (!lastActor && !overContainer) { - nextCursor |= IE_CURSOR_GRAY; - } - } else if (target_mode == TARGET_MODE_CAST) { - nextCursor = IE_CURSOR_CAST; - //point is always valid - if (!(target_types & GA_POINT)) { - if(!lastActor) { - nextCursor |= IE_CURSOR_GRAY; - } - } - } else if (target_mode == TARGET_MODE_DEFEND) { - nextCursor = IE_CURSOR_DEFEND; - if(!lastActor) { - nextCursor |= IE_CURSOR_GRAY; - } - } else if (target_mode == TARGET_MODE_PICK) { - if (lastActor) { - nextCursor = IE_CURSOR_PICK; - } else { - if (!overContainer && !overDoor && !overInfoPoint) { - nextCursor = IE_CURSOR_STEALTH|IE_CURSOR_GRAY; - } - } - goto end_function; - } - - if (lastActor) { - switch (lastActor->GetStat(IE_EA)) { - case EA_EVILCUTOFF: - case EA_GOODCUTOFF: - break; - - case EA_PC: - case EA_FAMILIAR: - case EA_ALLY: - case EA_CONTROLLED: - case EA_CHARMED: - case EA_EVILBUTGREEN: - if (target_types & GA_NO_ENEMY) - nextCursor^=1; - break; - - case EA_ENEMY: - case EA_GOODBUTRED: - if (target_types & GA_NO_ALLY) - nextCursor^=1; - break; - default: - if (!(target_types & GA_NO_NEUTRAL)) - nextCursor^=1; - break; - } - } - } -end_function: - if (lastCursor != nextCursor) { - Owner->Cursor = nextCursor; - lastCursor = (unsigned char) nextCursor; - } -} - -/** Global Mouse Move Event */ -void GameControl::OnGlobalMouseMove(unsigned short x, unsigned short y) -{ - if (ScreenFlags & SF_DISABLEMOUSE) { - return; - } - - if (Owner->Visible!=WINDOW_VISIBLE) { - return; - } - - if (!touchScrollAreasEnabled) { - int mousescrollspd = core->GetMouseScrollSpeed(); - - if (x <= SCROLL_BORDER) - moveX = -mousescrollspd; - else { - if (x >= ( core->Width - SCROLL_BORDER )) - moveX = mousescrollspd; - else - moveX = 0; - } - if (y <= SCROLL_BORDER) - moveY = -mousescrollspd; - else { - if (y >= ( core->Height - SCROLL_BORDER )) - moveY = mousescrollspd; - else - moveY = 0; - } - - if (moveX != 0 || moveY != 0) { - scrolling = true; - } else if (scrolling) { - scrolling = false; - - Video* video = core->GetVideoDriver(); - video->SetDragCursor(NULL); - } - } -} - -void GameControl::UpdateScrolling() { - if (!scrolling) return; - - int mousescrollspd = core->GetMouseScrollSpeed(); // TODO: why check against this value and not +/-? - Video* video = core->GetVideoDriver(); - - if (moveX == mousescrollspd && moveY == 0) { // right - video->SetDragCursor(core->GetScrollCursorSprite(0,numScrollCursor)); - } else if (moveX == mousescrollspd && moveY == -mousescrollspd) { // upper right - video->SetDragCursor(core->GetScrollCursorSprite(1,numScrollCursor)); - } else if (moveX == 0 && moveY == -mousescrollspd) { // up - video->SetDragCursor(core->GetScrollCursorSprite(2,numScrollCursor)); - } else if (moveX == -mousescrollspd && moveY == -mousescrollspd) { // upper left - video->SetDragCursor(core->GetScrollCursorSprite(3,numScrollCursor)); - } else if (moveX == -mousescrollspd && moveY == 0) { // left - video->SetDragCursor(core->GetScrollCursorSprite(4,numScrollCursor)); - } else if (moveX == -mousescrollspd && moveY == mousescrollspd) { // bottom left - video->SetDragCursor(core->GetScrollCursorSprite(5,numScrollCursor)); - } else if (moveX == 0 && moveY == mousescrollspd) { // bottom - video->SetDragCursor(core->GetScrollCursorSprite(6,numScrollCursor)); - } else if (moveX == mousescrollspd && moveY == mousescrollspd) { // bottom right - video->SetDragCursor(core->GetScrollCursorSprite(7,numScrollCursor)); - } - - numScrollCursor = (numScrollCursor+1) % 15; -} - -//generate action code for source actor to try to attack a target -void GameControl::TryToAttack(Actor *source, Actor *tgt) -{ - char Tmp[40]; - - source->ClearPath(); - source->ClearActions(); - strncpy(Tmp,"NIDSpecial3()",sizeof(Tmp) ); - source->AddAction( GenerateActionDirect( Tmp, tgt) ); -} - -//generate action code for source actor to try to defend a target -void GameControl::TryToDefend(Actor *source, Actor *tgt) -{ - char Tmp[40]; - - source->ClearPath(); - source->ClearActions(); - source->SetModal(MS_NONE); - strncpy(Tmp,"NIDSpecial4()",sizeof(Tmp) ); - source->AddAction( GenerateActionDirect( Tmp, tgt) ); -} - -//generate action code for source actor to try to pick pockets of a target -//The -1 flag is a placeholder for dynamic target IDs -void GameControl::TryToPick(Actor *source, Actor *tgt) -{ - char Tmp[40]; - - source->ClearPath(); - source->ClearActions(); - source->SetModal(MS_NONE); - strncpy(Tmp,"PickPockets([-1])", sizeof(Tmp) ); - source->AddAction( GenerateActionDirect( Tmp, tgt) ); -} - -//generate action code for source actor to try to pick a lock/disable trap on a door -void GameControl::TryToPick(Actor *source, Door *tgt) -{ - char Tmp[40]; - - source->ClearPath(); - source->ClearActions(); - source->SetModal(MS_NONE); - if (tgt->Trapped && tgt->TrapDetected) { - strncpy(Tmp, "RemoveTraps([-1])", sizeof(Tmp) ); - } else { - strncpy(Tmp, "PickLock([-1])", sizeof(Tmp) ); - } - source->AddAction( GenerateActionDirect( Tmp, tgt ) ); -} - -//generate action code for source actor to try to pick a lock/disable trap on a container -void GameControl::TryToPick(Actor *source, Container *tgt) -{ - char Tmp[40]; - - source->ClearPath(); - source->ClearActions(); - source->SetModal(MS_NONE); - if (tgt->Trapped && tgt->TrapDetected) { - strncpy(Tmp, "RemoveTraps([-1])", sizeof(Tmp) ); - } else { - strncpy(Tmp, "PickLock([-1])", sizeof(Tmp) ); - } - source->AddAction( GenerateActionDirect( Tmp, tgt ) ); -} - -//generate action code for source actor to try to disable trap (only trap type active regions) -void GameControl::TryToDisarm(Actor *source, InfoPoint *tgt) -{ - if (tgt->Type!=ST_PROXIMITY) return; - - char Tmp[40]; - - source->ClearPath(); - source->ClearActions(); - source->SetModal(MS_NONE); - strncpy(Tmp, "RemoveTraps([-1])", sizeof(Tmp) ); - source->AddAction( GenerateActionDirect( Tmp, tgt ) ); -} - -//generate action code for source actor to use item/cast spell on a point -void GameControl::TryToCast(Actor *source, const Point &tgt) -{ - char Tmp[40]; - - if (!spellCount) { - ResetTargetMode(); - return; //not casting or using an own item - } - source->ClearPath(); - source->ClearActions(); - - spellCount--; - if (spellOrItem>=0) { - if (spellIndex<0) { - strncpy(Tmp, "SpellPointNoDec(\"\",[0.0])", sizeof(Tmp) ); - } else { - strncpy(Tmp, "SpellPoint(\"\",[0.0])", sizeof(Tmp) ); - } - } else { - //using item on target - strncpy(Tmp, "UseItemPoint(\"\",[0,0],0)", sizeof(Tmp) ); - } - Action* action = GenerateAction( Tmp ); - action->pointParameter=tgt; - if (spellOrItem>=0) { - if (spellIndex<0) { - sprintf(action->string0Parameter,"%.8s",spellName); - } else { - CREMemorizedSpell *si; - //spell casting at target - si = source->spellbook.GetMemorizedSpell(spellOrItem, spellSlot, spellIndex); - if (!si) { - ResetTargetMode(); - return; - } - sprintf(action->string0Parameter,"%.8s",si->SpellResRef); - } - } else { - action->int0Parameter = spellSlot; - action->int1Parameter = spellIndex; - } - source->AddAction( action ); - if (!spellCount) { - ResetTargetMode(); - } -} - -//generate action code for source actor to use item/cast spell on another actor -void GameControl::TryToCast(Actor *source, Actor *tgt) -{ - char Tmp[40]; - - if (!spellCount) { - ResetTargetMode(); - return; //not casting or using an own item - } - source->ClearPath(); - source->ClearActions(); - - spellCount--; - if (spellOrItem>=0) { - if (spellIndex<0) { - sprintf(Tmp, "NIDSpecial7()"); - } else { - sprintf(Tmp, "NIDSpecial6()"); - } - } else { - //using item on target - sprintf(Tmp, "NIDSpecial5()"); - } - Action* action = GenerateActionDirect( Tmp, tgt); - if (spellOrItem>=0) { - if (spellIndex<0) { - sprintf(action->string0Parameter,"%.8s",spellName); - } else { - CREMemorizedSpell *si; - //spell casting at target - si = source->spellbook.GetMemorizedSpell(spellOrItem, spellSlot, spellIndex); - if (!si) { - ResetTargetMode(); - return; - } - sprintf(action->string0Parameter,"%.8s",si->SpellResRef); - } - } else { - action->int0Parameter = spellSlot; - action->int1Parameter = spellIndex; - } - source->AddAction( action ); - if (!spellCount) { - ResetTargetMode(); - } -} - -//generate action code for source actor to use talk to target actor -void GameControl::TryToTalk(Actor *source, Actor *tgt) -{ - char Tmp[40]; - - //Nidspecial1 is just an unused action existing in all games - //(non interactive demo) - //i found no fitting action which would emulate this kind of - //dialog initation - source->ClearPath(); - source->ClearActions(); - source->SetModal(MS_NONE); - strncpy(Tmp,"NIDSpecial1()",sizeof(Tmp) ); - dialoghandler->targetID = tgt->GetGlobalID(); //this is a hack, but not so deadly - source->AddAction( GenerateActionDirect( Tmp, tgt) ); -} - -//generate action code for actor appropriate for the target mode when the target is a container -void GameControl::HandleContainer(Container *container, Actor *actor) -{ - char Tmp[256]; - - if ((target_mode == TARGET_MODE_CAST) && spellCount) { - //we'll get the container back from the coordinates - TryToCast(actor, container->Pos); - //Do not reset target_mode, TryToCast does it for us!! - 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)); - return; - } - - if (target_mode == TARGET_MODE_PICK) { - TryToPick(actor, container); - return; - } - - actor->ClearPath(); - actor->ClearActions(); - strncpy(Tmp,"UseContainer()",sizeof(Tmp) ); - core->SetCurrentContainer( actor, container); - actor->AddAction( GenerateAction( Tmp) ); -} - -//generate action code for actor appropriate for the target mode when the target is a door -void GameControl::HandleDoor(Door *door, Actor *actor) -{ - char Tmp[256]; - - if ((target_mode == TARGET_MODE_CAST) && spellCount) { - //we'll get the door back from the coordinates - Point *p = door->toOpen; - Point *otherp = door->toOpen+1; - if (Distance(*p,actor)>Distance(*otherp,actor)) { - p=otherp; - } - TryToCast(actor, *p); - 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)); - return; - } - - if (target_mode == TARGET_MODE_PICK) { - TryToPick(actor, door); - return; - } - - actor->ClearPath(); - actor->ClearActions(); - actor->TargetDoor = door->GetGlobalID(); - // internal gemrb toggle door action hack - should we use UseDoor instead? - sprintf( Tmp, "NIDSpecial9()" ); - actor->AddAction( GenerateAction( Tmp) ); -} - -//generate action code for actor appropriate for the target mode when the target is an active region (infopoint, trap or travel) -bool GameControl::HandleActiveRegion(InfoPoint *trap, Actor * actor, Point &p) -{ - if ((target_mode == TARGET_MODE_CAST) && spellCount) { - //we'll get the active region from the coordinates (if needed) - TryToCast(actor, p); - //don't bother with this region further - return true; - } - if (target_mode == TARGET_MODE_PICK) { - TryToDisarm(actor, trap); - return true; - } - - switch(trap->Type) { - case ST_TRAVEL: - trap->AddTrigger(TriggerEntry(trigger_clicked, actor->GetGlobalID())); - // exit usage is handled by caller for now - // actor->UseExit(trap->GetGlobalID()); - return false; - case ST_TRIGGER: - //the importer shouldn't load the script - //if it is unallowed anyway (though - //deactivated scripts could be reactivated) - //only the 'trapped' flag should be honoured - //there. Here we have to check on the - //reset trap and deactivated flags - if (trap->Scripts[0]) { - if (!(trap->Flags&TRAP_DEACTIVATED) ) { - trap->AddTrigger(TriggerEntry(trigger_clicked, actor->GetGlobalID())); - //directly feeding the event, even if there are actions in the queue - //trap->Scripts[0]->Update(); - // FIXME - trap->ExecuteScript(1); - trap->ProcessActions(); - } - } else { - if (trap->overHeadText) { - if (trap->textDisplaying != 1) { - trap->textDisplaying = 1; - trap->timeStartDisplaying = core->GetGame()->Ticks; - DisplayString( trap ); - } - } - } - if (trap->Flags&TRAP_USEPOINT) { - //overriding the target point - p = trap->UsePoint; - return false; - } - return true; - default:; - } - return false; -} -/** Mouse Button Down */ -void GameControl::OnMouseDown(unsigned short x, unsigned short y, unsigned short Button, - unsigned short /*Mod*/) -{ - if (ScreenFlags&SF_DISABLEMOUSE) - return; - - short px=x; - short py=y; - DoubleClick = false; - switch(Button) - { - case GEM_MB_SCRLUP: - OnSpecialKeyPress(GEM_UP); - break; - case GEM_MB_SCRLDOWN: - OnSpecialKeyPress(GEM_DOWN); - break; - case GEM_MB_ACTION|GEM_MB_DOUBLECLICK: - DoubleClick = true; - case GEM_MB_ACTION: - core->GetVideoDriver()->ConvertToGame( px, py ); - MouseIsDown = true; - SelectionRect.x = px; - SelectionRect.y = py; - StartX = px; - StartY = py; - SelectionRect.w = 0; - SelectionRect.h = 0; - if (touchScrollAreasEnabled) touched=true; - } -} - -/** Mouse Button Up */ -void GameControl::OnMouseUp(unsigned short x, unsigned short y, unsigned short Button, - unsigned short /*Mod*/) -{ - unsigned int i; - char Tmp[256]; - - if (ScreenFlags & SF_DISABLEMOUSE) { - return; - } - //heh, i found no better place - core->CloseCurrentContainer(); - - MouseIsDown = false; - Point p(x,y); - core->GetVideoDriver()->ConvertToGame( p.x, p.y ); - Game* game = core->GetGame(); - if (!game) return; - Map* area = game->GetCurrentArea( ); - if (!area) return; - - if (touchScrollAreasEnabled) { - touched=false; - if (scrolling) { - moveX = 0; - moveY = 0; - scrolling=false; - Video* video = core->GetVideoDriver(); - video->SetDragCursor(NULL); - if (DrawSelectionRect) { - Actor** ab; - unsigned int count = area->GetActorInRect( ab, SelectionRect,true ); - if (count != 0) { - for (i = 0; i < highlighted.size(); i++) - highlighted[i]->SetOver( false ); - highlighted.clear(); - game->SelectActor( NULL, false, SELECT_NORMAL ); - for (i = 0; i < count; i++) { - // FIXME: should call handler only once - game->SelectActor( ab[i], true, SELECT_NORMAL ); - } - } - free( ab ); - DrawSelectionRect = false; - } - return; - } - } - if (DrawSelectionRect) { - Actor** ab; - unsigned int count = area->GetActorInRect( ab, SelectionRect,true ); - if (count != 0) { - for (i = 0; i < highlighted.size(); i++) - highlighted[i]->SetOver( false ); - highlighted.clear(); - game->SelectActor( NULL, false, SELECT_NORMAL ); - for (i = 0; i < count; i++) { - // FIXME: should call handler only once - game->SelectActor( ab[i], true, SELECT_NORMAL ); - } - } - free( ab ); - DrawSelectionRect = false; - return; - } - - //hidden actors are not selectable by clicking on them - Actor* actor = area->GetActor( p, GA_DEFAULT /*| GA_NO_DEAD */| GA_NO_HIDDEN | target_types); - if (Button == GEM_MB_MENU) { - if (actor) { - //from GSUtils - DisplayStringCore(actor, VB_SELECT+core->Roll(1,3,-1), DS_CONST|DS_CONSOLE); - return; - } - core->GetDictionary()->SetAt( "MenuX", x ); - core->GetDictionary()->SetAt( "MenuY", y ); - core->GetGUIScriptEngine()->RunFunction( "GUICommon", "OpenFloatMenuWindow" ); - return; - } - - if (Button != GEM_MB_ACTION) { - return; - } - - if (!game->selected.size()) { - //TODO: this is a hack, we need some restructuring here - //handling the special case when no one was selected, and - //the player clicks on a partymember - if (actor && (actor->GetStat(IE_EA)GetFirstSelectedPC(false); - if (!pc) { - //this could be a non-PC - pc = game->selected[0]; - } - if (!actor) { - //add a check if you don't want some random monster handle doors and such - if (overDoor) { - HandleDoor(overDoor, pc); - return; - } - if (overContainer) { - HandleContainer(overContainer, pc); - return; - } - if (overInfoPoint) { - if (overInfoPoint->Type==ST_TRAVEL) { - int i = game->selected.size(); - ieDword exitID = overInfoPoint->GetGlobalID(); - while(i--) { - game->selected[i]->UseExit(exitID); - } - } - if (HandleActiveRegion(overInfoPoint, pc, p)) { - core->SetEventFlag(EF_RESETTARGET); - return; - } - } - - //just a single actor, no formation - if (game->selected.size()==1) { - //the player is using an item or spell on the ground - if ((target_mode == TARGET_MODE_CAST) && spellCount) { - if (target_types & GA_POINT) { - TryToCast(pc, p); - } - return; - } - - pc->ClearPath(); - pc->ClearActions(); - CreateMovement(pc, p); - if (DoubleClick) Center(x,y); - //p is a searchmap travel region - if ( pc->GetCurrentArea()->GetCursor(p) == IE_CURSOR_TRAVEL) { - sprintf( Tmp, "NIDSpecial2()" ); - pc->AddAction( GenerateAction( Tmp) ); - } - return; - } - - // construct a sorted party - // TODO: this is still ugly, help? - std::vector party; - // first, from the actual party - int max = game->GetPartySize(false); - for(int idx = 1; idx<=max; idx++) { - Actor *act = game->FindPC(idx); - if(act->IsSelected()) { - party.push_back(act); - } - } - for (i = 0; i < game->selected.size(); i++) { - Actor *act = game->selected[i]; - if (!act->InParty) { - party.push_back(act); - } - } - - //party formation movement - Point src = party[0]->Pos; - for(i = 0; i < party.size(); i++) { - actor = party[i]; - actor->ClearPath(); - actor->ClearActions(); - MoveToPointFormation(actor, i, src, p); - } - if (DoubleClick) Center(x,y); - - //p is a searchmap travel region - if ( party[0]->GetCurrentArea()->GetCursor(p) == IE_CURSOR_TRAVEL) { - sprintf( Tmp, "NIDSpecial2()" ); - party[0]->AddAction( GenerateAction( Tmp) ); - } - return; - } - if (!actor) return; - - //we got an actor past this point - if (target_mode == TARGET_MODE_NONE) { - DisplayStringCore(actor, VB_SELECT+core->Roll(1,3,-1), DS_CONST|DS_CONSOLE); - } - - PerformActionOn(actor); -} - -void GameControl::PerformActionOn(Actor *actor) -{ - Game* game = core->GetGame(); - unsigned int i; - - //determining the type of the clicked actor - ieDword type; - - type = actor->GetStat(IE_EA); - if ( type >= EA_EVILCUTOFF || type == EA_GOODBUTRED ) { - type = ACT_ATTACK; //hostile - } else if ( type > EA_CHARMED ) { - type = ACT_TALK; //neutral - } else { - type = ACT_NONE; //party - } - - if (target_mode == TARGET_MODE_ATTACK) { - type = ACT_ATTACK; - } else if (target_mode == TARGET_MODE_TALK) { - type = ACT_TALK; - } else if (target_mode == TARGET_MODE_CAST) { - type = ACT_CAST; - } else if (target_mode == TARGET_MODE_DEFEND) { - type = ACT_DEFEND; - } else if (target_mode == TARGET_MODE_PICK) { - type = ACT_THIEVING; - } - - if (type != ACT_NONE) { - if(!actor->ValidTarget(target_types)) { - return; - } - } - - //we shouldn't zero this for two reasons in case of spell or item - //1. there could be multiple targets - //2. the target mode is important - if (!(target_mode == TARGET_MODE_CAST) || !spellCount) { - ResetTargetMode(); - } - - switch (type) { - case ACT_NONE: //none - if (!actor->ValidTarget(GA_SELECT)) { - return; - } - - if (actor->InParty) - SelectActor( actor->InParty ); - else if (actor->GetStat(IE_EA) <= EA_CHARMED) { - /*let's select charmed/summoned creatures - EA_CHARMED is the maximum value known atm*/ - core->GetGame()->SelectActor(actor, true, SELECT_REPLACE); - } - break; - case ACT_TALK: - if (!actor->ValidTarget(GA_TALK)) { - return; - } - - //talk (first selected talks) - if (game->selected.size()) { - //if we are in PST modify this to NO! - Actor *source; - if (core->HasFeature(GF_PROTAGONIST_TALKS) ) { - source = game->GetPC(0, false); //protagonist - } else { - source = core->GetFirstSelectedPC(false); - } - // only party members can start conversations - if (source) { - TryToTalk(source, actor); - } - } - break; - case ACT_ATTACK: - //all of them attacks the red circled actor - for(i=0;iselected.size();i++) { - TryToAttack(game->selected[i], actor); - } - break; - case ACT_CAST: //cast on target or use item on target - if (game->selected.size()==1) { - Actor *source; - source = core->GetFirstSelectedActor(); - if(source) { - TryToCast(source, actor); - } - } - break; - case ACT_DEFEND: - for(i=0;iselected.size();i++) { - TryToDefend(game->selected[i], actor); - } - break; - case ACT_THIEVING: - if (game->selected.size()==1) { - Actor *source; - source = core->GetFirstSelectedActor(); - if(source) { - TryToPick(source, actor); - } - } - break; - } -} - -//sets target mode, and resets the cursor -void GameControl::SetTargetMode(int mode) { - int x,y; - - target_mode = mode; - //This hack is to refresh the mouse cursor - core->GetVideoDriver()->GetMousePos(x,y); - //calling into the videodriver to set the mouseposition won't work - core->GetEventMgr()->MouseMove(x,y); -} - -void GameControl::ResetTargetMode() { - target_types = GA_NO_DEAD|GA_NO_HIDDEN; - SetTargetMode(TARGET_MODE_NONE); -} - -void GameControl::UpdateTargetMode() { - SetTargetMode(target_mode); -} - -/** Special Key Press */ -void GameControl::OnSpecialKeyPress(unsigned char Key) -{ - if (DialogueFlags&DF_IN_DIALOG) { - switch(Key) { - case GEM_RETURN: - //simulating the continue/end button pressed - core->GetGUIScriptEngine()->RunFunction("GUIWORLD", "CloseContinueWindow"); - break; - } - return; //don't accept keys in dialog - } - Region Viewport = core->GetVideoDriver()->GetViewport(); - Game *game = core->GetGame(); - if (!game) return; - Map *map = game->GetCurrentArea(); - if (!map) return; - - Point mapsize = map->TMap->GetMapSize(); - int partysize = game->GetPartySize(false); - int pm; - char tmpstr[10]; - - switch (Key) { - case GEM_LEFT: - if (Viewport.x > 63) - Viewport.x -= 64; - else - Viewport.x = 0; - break; - case GEM_UP: - if (Viewport.y > 63) - Viewport.y -= 64; - else - Viewport.y = 0; - break; - case GEM_DOWN: - if (Viewport.y + Viewport.h + 64 < mapsize.y) - Viewport.y += 64; - else { - Viewport.y = mapsize.y - Viewport.h; - if (Viewport.y<0) Viewport.y=0; - } - break; - case GEM_RIGHT: - if (Viewport.x + Viewport.w + 64 < mapsize.x) - Viewport.x += 64; - else { - Viewport.x = mapsize.x - Viewport.w; - if (Viewport.x<0) Viewport.x=0; - } - break; - case GEM_ALT: - DebugFlags |= DEBUG_SHOW_CONTAINERS; - return; - case GEM_TAB: - // show partymember hp/maxhp as overhead text - for (pm=0; pm < partysize; pm++) { - Actor *pc = game->GetPC(pm, true); - if (!pc) continue; - //sucks but this is set in different places - if (pc->GetStat(IE_MC_FLAGS) & MC_HIDE_HP) continue; - if (pc->GetStat(IE_EXTSTATE_ID) & EXTSTATE_NO_HP) continue; - memset(tmpstr, 0, 10); - snprintf(tmpstr, 10, "%d/%d", pc->Modified[IE_HITPOINTS], pc->Modified[IE_MAXHITPOINTS]); - pc->DisplayHeadText(strdup(tmpstr)); - } - return; - case GEM_MOUSEOUT: - moveX = 0; - moveY = 0; - return; - case GEM_ESCAPE: - core->GetGUIScriptEngine()->RunFunction("GUICommonWindows", "EmptyControls"); - core->SetEventFlag(EF_ACTION); - return; - case GEM_PGUP: - core->GetGUIScriptEngine()->RunFunction("CommonWindow","OnIncreaseSize"); - return; - case GEM_PGDOWN: - core->GetGUIScriptEngine()->RunFunction("CommonWindow","OnDecreaseSize"); - return; - default: - return; - } - if (ScreenFlags & SF_LOCKSCROLL) { - moveX = 0; - moveY = 0; - } else { - // override any existing viewport moves which may be in progress - core->timer->SetMoveViewPort( Viewport.x, Viewport.y, 0, false ); - // move it directly ourselves, since we might be paused - core->GetVideoDriver()->MoveViewportTo( Viewport.x, Viewport.y ); - } -} - -void GameControl::CalculateSelection(const Point &p) -{ - unsigned int i; - - Game* game = core->GetGame(); - Map* area = game->GetCurrentArea( ); - if (DrawSelectionRect) { - if (p.x < StartX) { - SelectionRect.w = StartX - p.x; - SelectionRect.x = p.x; - } else { - SelectionRect.x = StartX; - SelectionRect.w = p.x - StartX; - } - if (p.y < StartY) { - SelectionRect.h = StartY - p.y; - SelectionRect.y = p.y; - } else { - SelectionRect.y = StartY; - SelectionRect.h = p.y - StartY; - } - Actor** ab; - unsigned int count = area->GetActorInRect( ab, SelectionRect,true ); - for (i = 0; i < highlighted.size(); i++) - highlighted[i]->SetOver( false ); - highlighted.clear(); - if (count != 0) { - for (i = 0; i < count; i++) { - ab[i]->SetOver( true ); - highlighted.push_back( ab[i] ); - } - } - free( ab ); - } else { - Actor* actor = area->GetActor( p, GA_DEFAULT | GA_SELECT | GA_NO_DEAD | GA_NO_ENEMY); - SetLastActor( actor, area->GetActorByGlobalID(lastActorID) ); -/* - Actor *lastActor = area->GetActorByGlobalID(lastActorID); - if (lastActor) - lastActor->SetOver( false ); - if (!actor) { - lastActorID = 0; - } else { - lastActorID = actor->globalID; - actor->SetOver( true ); - } -*/ - } -} - -void GameControl::SetLastActor(Actor *actor, Actor *prevActor) -{ - if (prevActor) - prevActor->SetOver( false ); - if (!actor) { - lastActorID = 0; - } else { - lastActorID = actor->GetGlobalID(); - actor->SetOver( true ); - } -} - -void GameControl::SetCutSceneMode(bool active) -{ - if (active) { - ScreenFlags |= (SF_DISABLEMOUSE | SF_LOCKSCROLL | SF_CUTSCENE); - moveX = 0; - moveY = 0; - } else { - ScreenFlags &= ~(SF_DISABLEMOUSE | SF_LOCKSCROLL | SF_CUTSCENE); - } -} - -//Change game window geometries when a new window gets deactivated -void GameControl::HandleWindowHide(const char *WindowName, const char *WindowPosition) -{ - Variables* dict = core->GetDictionary(); - ieDword index; - - if (dict->Lookup( WindowName, index )) { - if (index != (ieDword) -1) { - Window* w = core->GetWindow( (unsigned short) index ); - if (w) { - core->SetVisible( (unsigned short) index, WINDOW_INVISIBLE ); - if (dict->Lookup( WindowPosition, index )) { - ResizeDel( w, index ); - } - return; - } - printMessage("GameControl", "Invalid Window Index: %s:%u\n", LIGHT_RED, - WindowName, index); - } - } -} - -//Hide all other windows on the GUI (gamecontrol is not hidden by this) -int GameControl::HideGUI() -{ - //hidegui is in effect - if (!(ScreenFlags&SF_GUIENABLED) ) { - return 0; - } - //no gamecontrol visible - if (Owner->Visible == WINDOW_INVISIBLE ) { - return 0; - } - ScreenFlags &=~SF_GUIENABLED; - HandleWindowHide("PortraitWindow", "PortraitPosition"); - HandleWindowHide("OtherWindow", "OtherPosition"); - HandleWindowHide("TopWindow", "TopPosition"); - HandleWindowHide("OptionsWindow", "OptionsPosition"); - HandleWindowHide("MessageWindow", "MessagePosition"); - HandleWindowHide("ActionsWindow", "ActionsPosition"); - //FloatWindow doesn't affect gamecontrol, so it is special - Variables* dict = core->GetDictionary(); - ieDword index; - - if (dict->Lookup( "FloatWindow", index )) { - if (index != (ieDword) -1) { - core->SetVisible( (unsigned short) index, WINDOW_INVISIBLE ); - } - } - core->GetVideoDriver()->SetViewport( Owner->XPos, Owner->YPos, Width, Height ); - return 1; -} - -//Change game window geometries when a new window gets activated -void GameControl::HandleWindowReveal(const char *WindowName, const char *WindowPosition) -{ - Variables* dict = core->GetDictionary(); - ieDword index; - - if (dict->Lookup( WindowName, index )) { - if (index != (ieDword) -1) { - Window* w = core->GetWindow( (unsigned short) index ); - if (w) { - core->SetVisible( (unsigned short) index, WINDOW_VISIBLE ); - if (dict->Lookup( WindowPosition, index )) { - ResizeAdd( w, index ); - } - return; - } - printMessage("GameControl", "Invalid Window Index %s:%u\n", LIGHT_RED, - WindowName, index); - } - } -} - -//Reveal all windows on the GUI (including this one) -int GameControl::UnhideGUI() -{ - if (ScreenFlags&SF_GUIENABLED) { - return 0; - } - - ScreenFlags |= SF_GUIENABLED; - // Unhide the gamecontrol window - core->SetVisible( 0, WINDOW_VISIBLE ); - - HandleWindowReveal("ActionsWindow", "ActionsPosition"); - HandleWindowReveal("MessageWindow", "MessagePosition"); - HandleWindowReveal("OptionsWindow", "OptionsPosition"); - HandleWindowReveal("TopWindow", "TopPosition"); - HandleWindowReveal("OtherWindow", "OtherPosition"); - HandleWindowReveal("PortraitWindow", "PortraitPosition"); - //the floatwindow is a special case - Variables* dict = core->GetDictionary(); - ieDword index; - - if (dict->Lookup( "FloatWindow", index )) { - if (index != (ieDword) -1) { - Window* fw = core->GetWindow( (unsigned short) index ); - if (fw) { - core->SetVisible( (unsigned short) index, WINDOW_VISIBLE ); - fw->Flags |=WF_FLOAT; - core->SetOnTop( index ); - } - } - } - core->GetVideoDriver()->SetViewport( Owner->XPos, Owner->YPos, Width, Height ); - return 1; -} - -//a window got removed, so the GameControl gets enlarged -void GameControl::ResizeDel(Window* win, int type) -{ - switch (type) { - case 0: //Left - if (LeftCount!=1) { - printMessage("GameControl","More than one left window!\n",LIGHT_RED); - } - LeftCount--; - if (!LeftCount) { - Owner->XPos -= win->Width; - Owner->Width += win->Width; - Width = Owner->Width; - } - break; - - case 1: //Bottom - if (BottomCount!=1) { - printMessage("GameControl","More than one bottom window!\n",LIGHT_RED); - } - BottomCount--; - if (!BottomCount) { - Owner->Height += win->Height; - Height = Owner->Height; - } - break; - - case 2: //Right - if (RightCount!=1) { - printMessage("GameControl","More than one right window!\n",LIGHT_RED); - } - RightCount--; - if (!RightCount) { - Owner->Width += win->Width; - Width = Owner->Width; - } - break; - - case 3: //Top - if (TopCount!=1) { - printMessage("GameControl","More than one top window!\n",LIGHT_RED); - } - TopCount--; - if (!TopCount) { - Owner->YPos -= win->Height; - Owner->Height += win->Height; - Height = Owner->Height; - } - break; - - case 4: //BottomAdded - BottomCount--; - Owner->Height += win->Height; - Height = Owner->Height; - break; - case 5: //Inactivating - BottomCount--; - Owner->Height += win->Height; - Height = Owner->Height; - break; - } -} - -//a window got added, so the GameControl gets shrunk -//Owner is the GameControl's window -//GameControl is the only control on that window -void GameControl::ResizeAdd(Window* win, int type) -{ - switch (type) { - case 0: //Left - LeftCount++; - if (LeftCount == 1) { - Owner->XPos += win->Width; - Owner->Width -= win->Width; - Width = Owner->Width; - } - break; - - case 1: //Bottom - BottomCount++; - if (BottomCount == 1) { - Owner->Height -= win->Height; - Height = Owner->Height; - } - break; - - case 2: //Right - RightCount++; - if (RightCount == 1) { - Owner->Width -= win->Width; - Width = Owner->Width; - } - break; - - case 3: //Top - TopCount++; - if (TopCount == 1) { - Owner->YPos += win->Height; - Owner->Height -= win->Height; - Height = Owner->Height; - } - break; - - case 4: //BottomAdded - BottomCount++; - Owner->Height -= win->Height; - Height = Owner->Height; - break; - - case 5: //Inactivating - BottomCount++; - Owner->Height -= win->Height; - Height = 0; - } -} - -//Create an overhead text over an arbitrary point -void GameControl::DisplayString(const Point &p, const char *Text) -{ - Scriptable* scr = new Scriptable( ST_TRIGGER ); - scr->overHeadText = (char *) Text; - scr->textDisplaying = 1; - scr->timeStartDisplaying = 0; - scr->Pos = p; -} - -//Create an overhead text over a scriptable target -//Multiple texts are possible, as this code copies the text to a new object -void GameControl::DisplayString(Scriptable* target) -{ - Scriptable* scr = new Scriptable( ST_TRIGGER ); - scr->overHeadText = strdup( target->overHeadText ); -/* strdup should work here, we use it elsewhere - size_t len = strlen( target->overHeadText ) + 1; - scr->overHeadText = ( char * ) malloc( len ); - strcpy( scr->overHeadText, target->overHeadText ); -*/ - scr->textDisplaying = 1; - scr->timeStartDisplaying = target->timeStartDisplaying; - scr->Pos = target->Pos; -} - -/** changes displayed map to the currently selected PC */ -void GameControl::ChangeMap(Actor *pc, bool forced) -{ - //swap in the area of the actor - Game* game = core->GetGame(); - if (forced || (pc && stricmp( pc->Area, game->CurrentArea) != 0) ) { - dialoghandler->EndDialog(); - overInfoPoint = NULL; - overContainer = NULL; - overDoor = NULL; - /*this is loadmap, because we need the index, not the pointer*/ - char *areaname = game->CurrentArea; - if (pc) { - areaname = pc->Area; - } - game->GetMap( areaname, true ); - ScreenFlags|=SF_CENTERONACTOR; - } - //center on first selected actor - Video *video = core->GetVideoDriver(); - Region vp = video->GetViewport(); - if (ScreenFlags&SF_CENTERONACTOR) { - core->timer->SetMoveViewPort( pc->Pos.x, pc->Pos.y, 0, true ); - video->MoveViewportTo( pc->Pos.x-vp.w/2, pc->Pos.y-vp.h/2 ); - ScreenFlags&=~SF_CENTERONACTOR; - } -} - -void GameControl::SetScreenFlags(int value, int mode) -{ - switch(mode) { - case BM_OR: ScreenFlags|=value; break; - case BM_NAND: ScreenFlags&=~value; break; - case BM_SET: ScreenFlags=value; break; - case BM_AND: ScreenFlags&=value; break; - case BM_XOR: ScreenFlags^=value; break; - } -} - -void GameControl::SetDialogueFlags(int value, int mode) -{ - switch(mode) { - case BM_OR: DialogueFlags|=value; break; - case BM_NAND: DialogueFlags&=~value; break; - case BM_SET: DialogueFlags=value; break; - case BM_AND: DialogueFlags&=value; break; - case BM_XOR: DialogueFlags^=value; break; - } -} - -//copies a screenshot into a sprite -Sprite2D* GameControl::GetScreenshot(bool show_gui) -{ - Sprite2D* screenshot; - if (show_gui) { - screenshot = core->GetVideoDriver()->GetScreenshot( Region( 0, 0, 0, 0) ); - } else { - int hf = HideGUI (); - Draw (0, 0); - screenshot = core->GetVideoDriver()->GetScreenshot( Region( 0, 0, 0, 0 ) ); - if (hf) { - UnhideGUI (); - } - core->DrawWindows (); - } - - return screenshot; -} - -//copies a downscaled screenshot into a sprite for save game preview -Sprite2D* GameControl::GetPreview() -{ - // We get preview by first taking a screenshot of quintuple size of the preview control size (a few pixels bigger only in pst), - // centered in the display. This is to get a decent picture for - // higher screen resolutions. - // FIXME: how do orig games solve that? - Video* video = core->GetVideoDriver(); - int w = video->GetWidth(); - int h = video->GetHeight(); - int x = (w - 640) / 2; - int y = (h - 405) / 2; - - if (x < 0) { - x = 0; - } else { - w = 515; - } - - if (y < 0) { - y = 0; - } else { - h = 385; - } - - if (!x) - y = 0; - - Draw (0, 0); - Sprite2D *screenshot = video->GetScreenshot( Region(x, y, w, h) ); - core->DrawWindows(); - - Sprite2D* preview = video->SpriteScaleDown ( screenshot, 5 ); - video->FreeSprite( screenshot ); - return preview; -} - - -/** - * Returns PC portrait for a currently running game - */ -Sprite2D* GameControl::GetPortraitPreview(int pcslot) -{ - /** Portrait shrink ratio */ - // FIXME: this is just a random PST specific trait - // you can make it less random with a new feature bit - int ratio = (core->HasFeature( GF_ONE_BYTE_ANIMID )) ? 1 : 2; - - Video *video = core->GetVideoDriver(); - - Actor *actor = core->GetGame()->GetPC( pcslot, false ); - if (! actor) { - return NULL; - } - ResourceHolder im(actor->GetPortrait(true)); - if (! im) { - return NULL; - } - - Sprite2D* img = im->GetSprite2D(); - - if (ratio == 1) - return img; - - Sprite2D* img_scaled = video->SpriteScaleDown( img, ratio ); - video->FreeSprite( img ); - - return img_scaled; -} - -Actor *GameControl::GetActorByGlobalID(ieDword globalID) -{ - if (!globalID) - return NULL; - Game* game = core->GetGame(); - if (!game) - return NULL; - - Map* area = game->GetCurrentArea( ); - if (!area) - return NULL; - return - area->GetActorByGlobalID(globalID); -} - -Actor *GameControl::GetLastActor() -{ - return GetActorByGlobalID(lastActorID); -} - -//Set up an item use which needs targeting -//Slot is an inventory slot -//header is the used item extended header -//u is the user -//target type is a bunch of GetActor flags that alter valid targets -//cnt is the number of different targets (usually 1) -void GameControl::SetupItemUse(int slot, int header, Actor *u, int targettype, int cnt) -{ - memset(spellName, 0, sizeof(ieResRef)); - spellOrItem = -1; - spellUser = u; - spellSlot = slot; - spellIndex = header; - //item use also uses the casting icon, this might be changed in some custom game? - SetTargetMode(TARGET_MODE_CAST); - target_types = targettype; - spellCount = cnt; -} - -//Set up spell casting which needs targeting -//type is the spell's type -//level is the caster level -//idx is the spell's number -//u is the caster -//target type is a bunch of GetActor flags that alter valid targets -//cnt is the number of different targets (usually 1) -void GameControl::SetupCasting(ieResRef spellname, int type, int level, int idx, Actor *u, int targettype, int cnt) -{ - memcpy(spellName, spellname, sizeof(ieResRef)); - spellOrItem = type; - spellUser = u; - spellSlot = level; - spellIndex = idx; - SetTargetMode(TARGET_MODE_CAST); - target_types = targettype; - spellCount = cnt; -} - -//another method inherited from Control which has no use here -bool GameControl::SetEvent(int /*eventType*/, EventHandler /*handler*/) -{ - return false; -} - -void GameControl::SetDisplayText(char *text, unsigned int time) -{ - if (DisplayText) { - core->FreeString(DisplayText); - } - DisplayTextTime = time; - DisplayText = text; -} - -void GameControl::SetDisplayText(ieStrRef text, unsigned int time) -{ - SetDisplayText(core->GetString(displaymsg->GetStringReference(text), 0), time); -} - diff --git a/project/jni/application/gemrb/gemrb/core/GUI/GameControl.h b/project/jni/application/gemrb/gemrb/core/GUI/GameControl.h deleted file mode 100644 index 8e5bf14cc..000000000 --- a/project/jni/application/gemrb/gemrb/core/GUI/GameControl.h +++ /dev/null @@ -1,258 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -/** - * @file GameControl.h - * Declares GameControl widget which is responsible for displaying areas, - * interacting with PCs, NPCs and the rest of the game world. - * @author The GemRB Project - */ - -#ifndef GAMECONTROL_H -#define GAMECONTROL_H - -#include "GUI/Control.h" - -#include "exports.h" - -#include "Dialog.h" -#include "Interface.h" -#include "Map.h" - -class GameControl; -class Window; -class DialogHandler; - -//dialog flags -#define DF_IN_DIALOG 1 -#define DF_TALKCOUNT 2 -#define DF_UNBREAKABLE 4 -#define DF_FREEZE_SCRIPTS 8 -#define DF_INTERACT 16 -#define DF_IN_CONTAINER 32 -#define DF_OPENCONTINUEWINDOW 64 -#define DF_OPENENDWINDOW 128 - -//screen flags -// !!! Keep these synchronized with GUIDefines.py !!! -#define SF_DISABLEMOUSE 1 //no mouse cursor -#define SF_CENTERONACTOR 2 // -#define SF_ALWAYSCENTER 4 -#define SF_GUIENABLED 8 // -#define SF_LOCKSCROLL 16 //don't scroll -#define SF_CUTSCENE 32 //don't push new actions onto the action queue -#define SF_TRACKING 64 //draw blue arrows on the edge for creatures - -// target modes and types -// !!! Keep these synchronized with GUIDefines.py !!! -#define TARGET_MODE_NONE 0 -#define TARGET_MODE_TALK 1 -#define TARGET_MODE_ATTACK 2 -#define TARGET_MODE_CAST 3 -#define TARGET_MODE_DEFEND 4 -#define TARGET_MODE_PICK 5 - -/* -#define TARGET_SELECT 16 -#define TARGET_NO_DEAD 32 -#define TARGET_POINT 64 -#define TARGET_NO_HIDDEN 128 -#define TARGET_TYPE_NONE 0x000 -#define TARGET_NO_ALLY 0x100 //0x100 -#define TARGET_NO_ENEMY 0x200 //0x200 -#define TARGET_NO_NEUTRAL 0x400 -#define TARGET_NO_SELF 0x800 -#define TARGET_TYPE_ALL 0 //(TARGET_TYPE_ALLY | TARGET_TYPE_ENEMY | TARGET_TYPE_NEUTRAL) -*/ - -/** - * @class GameControl - * Widget displaying areas, where most of the game 'happens'. - * It allows for interacting with PCs, NPCs and the rest of the world. - * It's also a very core part of GemRB, as some processes are driven from it. - * It's always assigned Control index 0. - */ - -class GEM_EXPORT GameControl : public Control { -public: - GameControl(void); - ~GameControl(void); -public: - /** Draws the Control on the Output Display */ - void Draw(unsigned short x, unsigned short y); - /** Sets multiple quicksaves flag*/ - static void MultipleQuickSaves(int arg); - void SetTracker(Actor *actor, ieDword dist); -private: - ieDword lastActorID; - ieDword trackerID; - ieDword distance; //tracking distance - std::vector< Actor*> highlighted; - bool DrawSelectionRect; - bool MouseIsDown; - bool DoubleClick; - Region SelectionRect; - short StartX, StartY; - //int action; - - // following variables used for touch scroll areas - bool touchScrollAreasEnabled; // true, if scroll areas enabled - bool touched; // true, if player touched screen (left button down and hold) - unsigned int scrollAreasWidth; // scroll areas width - -public: - Door* overDoor; - Container* overContainer; - InfoPoint* overInfoPoint; - - // allow targetting allies, enemies and/or neutrals (bitmask) - int target_types; -private: - // currently selected targetting type, such as talk, attack, cast, ... - // private to enforce proper cursor changes - int target_mode; - unsigned char lastCursor; - short moveX, moveY; - int numScrollCursor; - bool scrolling; - unsigned short lastMouseX, lastMouseY; - int DebugFlags; - Point pfs; - PathNode* drawPath; - unsigned long AIUpdateCounter; - int ScreenFlags; - int DialogueFlags; - char *DisplayText; - unsigned int DisplayTextTime; - bool EnableRunning; -public: //Events - /** Key Press Event */ - void OnKeyPress(unsigned char Key, unsigned short Mod); - /** Key Release Event */ - void OnKeyRelease(unsigned char Key, unsigned short Mod); - /** Mouse Over Event */ - void OnMouseOver(unsigned short x, unsigned short y); - /** Global Mouse Move Event */ - void OnGlobalMouseMove(unsigned short x, unsigned short y); - /** Mouse Button Down */ - void OnMouseDown(unsigned short x, unsigned short y, unsigned short Button, - unsigned short Mod); - /** Mouse Button Up */ - void OnMouseUp(unsigned short x, unsigned short y, unsigned short Button, - unsigned short Mod); - /** Special Key Press */ - void OnSpecialKeyPress(unsigned char Key); - void DisplayTooltip(); - void UpdateScrolling(); - void SetTargetMode(int mode); - int GetTargetMode() { return target_mode; } - void SetScreenFlags(int value, int mode); - void SetDialogueFlags(int value, int mode); - int GetScreenFlags() { return ScreenFlags; } - int GetDialogueFlags() { return DialogueFlags; } - /** this function is called from the area when autosave is needed */ - void AutoSave(); - void SetDisplayText(char *text, unsigned int time); - void SetDisplayText(ieStrRef text, unsigned int time); - /* centers viewport to the points specified */ - void Center(unsigned short x, unsigned short y); -private: - /** this function is called when the user presses 'q' (or equivalent) */ - void QuickSave(); - /** this function safely retrieves an Actor by ID */ - Actor *GetActorByGlobalID(ieDword ID); - void CalculateSelection(const Point &p); - void ResizeDel(Window* win, int type); - void ResizeAdd(Window* win, int type); - void HandleWindowHide(const char *WindowName, const char *WindowPosition); - void HandleWindowReveal(const char *WindowName, const char *WindowPosition); - void ReadFormations(); - /** Draws an arrow on the edge of the screen based on the point (points at offscreen actors) */ - void DrawArrowMarker(const Region &screen, Point p, const Region &viewport); - -private: - unsigned char LeftCount, BottomCount, RightCount, TopCount; - Actor *user; //the user of item or spell -public: - DialogHandler *dialoghandler; - //the name of the spell to cast - ieResRef spellName; - //using spell or item - int spellOrItem; // -1 = item, otherwise the spell type - //the user of spell or item - Actor *spellUser; - int spellSlot, spellIndex; //or inventorySlot/itemHeader - int spellCount; //multiple targeting -public: - /** Selects one or all PC */ - void SelectActor(int whom, int type = -1); - void SetLastActor(Actor *actor, Actor *prevActor); - void SetCutSceneMode(bool active); - int HideGUI(); - int UnhideGUI(); - void TryToAttack(Actor *source, Actor *target); - void TryToCast(Actor *source, const Point &p); - void TryToCast(Actor *source, Actor *target); - void TryToDefend(Actor *source, Actor *target); - void TryToTalk(Actor *source, Actor *target); - void TryToPick(Actor *source, Actor *tgt); - void TryToPick(Actor *source, Door *tgt); - void TryToPick(Actor *source, Container *tgt); - 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; - //containers - int GetCursorOverContainer(Container *overContainer) const; - void HandleContainer(Container *container, Actor *actor); - //doors - int GetCursorOverDoor(Door *overDoor) const; - void HandleDoor(Door *door, Actor *actor); - //infopoints - int GetCursorOverInfoPoint(InfoPoint *overInfoPoint) const; - bool HandleActiveRegion(InfoPoint *trap, Actor *actor, Point &p); - - Point GetFormationOffset(ieDword formation, ieDword pos); - void MoveToPointFormation(Actor *actor, unsigned int pos, Point src, Point p); - /** calls MoveToPoint or RunToPoint */ - void CreateMovement(Actor *actor, const Point &p); - /** Displays a string over an object */ - void DisplayString(Scriptable* target); - /** Displays a string on screen */ - void DisplayString(const Point &p, const char *Text); - Actor *GetLastActor(); - /** changes map to the current PC */ - void ChangeMap(Actor *pc, bool forced); - /** Returns game screenshot, with or without GUI controls */ - Sprite2D* GetScreenshot( bool show_gui = 0 ); - /** Returns current area preview for saving a game */ - Sprite2D* GetPreview(); - /** Returns PC portrait for a currently running game */ - Sprite2D* GetPortraitPreview(int pcslot); - /** Sets up targeting with spells or items */ - void SetupItemUse(int slot, int header, Actor *actor, int targettype, int cnt); - /** Page is the spell type + spell level info */ - void SetupCasting(ieResRef spellname, int type, int level, int slot, Actor *actor, int targettype, int cnt); - bool SetEvent(int eventType, EventHandler handler); -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/GUI/Label.cpp b/project/jni/application/gemrb/gemrb/core/GUI/Label.cpp deleted file mode 100644 index 6579e61f3..000000000 --- a/project/jni/application/gemrb/gemrb/core/GUI/Label.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "GUI/Label.h" - -#include "win32def.h" - -#include "GameData.h" -#include "Interface.h" -#include "Palette.h" -#include "Sprite2D.h" -#include "Variables.h" -#include "Video.h" -#include "GUI/Window.h" - -Label::Label(Font* font) -{ - this->font = font; - Buffer = NULL; - useRGB = false; - ResetEventHandler( LabelOnPress ); - - Alignment = IE_FONT_ALIGN_CENTER|IE_FONT_ALIGN_MIDDLE; - palette = NULL; -} -Label::~Label() -{ - gamedata->FreePalette( palette ); - if (Buffer) { - free( Buffer ); - } -} -/** Draws the Control on the Output Display */ -void Label::Draw(unsigned short x, unsigned short y) -{ - if (!Changed && !(Owner->Flags&WF_FLOAT)) { - return; - } - Changed = false; - if (XPos == 65535) { - return; - } - if (font && Buffer) { - font->Print( Region( this->XPos + x, this->YPos + y, - this->Width, this->Height ), ( unsigned char * ) Buffer, - useRGB?palette:NULL, - Alignment | IE_FONT_SINGLE_LINE, true ); - } - - if (AnimPicture) { - int xOffs = ( Width / 2 ) - ( AnimPicture->Width / 2 ); - int yOffs = ( Height / 2 ) - ( AnimPicture->Height / 2 ); - Region r( x + XPos + xOffs, y + YPos + yOffs, (int)(AnimPicture->Width), AnimPicture->Height ); - core->GetVideoDriver()->BlitSprite( AnimPicture, x + XPos + xOffs, y + YPos + yOffs, true, &r ); - } - -} -/** This function sets the actual Label Text */ -void Label::SetText(const char* string) -{ - if (Buffer ) - free( Buffer ); - if (Alignment == IE_FONT_ALIGN_CENTER) { - if (core->HasFeature( GF_LOWER_LABEL_TEXT )) { - int len = strlen(string); - Buffer = (char *) malloc( len+1 ); - strnlwrcpy( Buffer, string, len ); - } - else { - Buffer = strdup( string ); - } - } - else { - Buffer = strdup( string ); - } - if (!palette) { - Color white = {0xff, 0xff, 0xff, 0x00}, black = {0x00, 0x00, 0x00, 0x00}; - SetColor(white, black); - } - if (Owner) { - Owner->Invalidate(); - } -} -/** Sets the Foreground Font Color */ -void Label::SetColor(Color col, Color bac) -{ - gamedata->FreePalette( palette ); - palette = core->CreatePalette( col, bac ); - Changed = true; -} - -void Label::SetAlignment(unsigned char Alignment) -{ - this->Alignment = Alignment; - if (Alignment == IE_FONT_ALIGN_CENTER) { - if (core->HasFeature( GF_LOWER_LABEL_TEXT )) { - strlwr( Buffer ); - } - } - Changed = true; -} - -void Label::OnMouseUp(unsigned short x, unsigned short y, - unsigned short /*Button*/, unsigned short /*Mod*/) -{ - //print( "Label::OnMouseUp\n" ); - if (( x <= Width ) && ( y <= Height )) { - if (VarName[0] != 0) { - core->GetDictionary()->SetAt( VarName, Value ); - } - if (LabelOnPress) { - RunEventHandler( LabelOnPress ); - } - } -} - -bool Label::SetEvent(int eventType, EventHandler handler) -{ - Changed = true; - - switch (eventType) { - case IE_GUI_LABEL_ON_PRESS: - LabelOnPress = handler; - break; - default: - return false; - } - - return true; -} - -/** Simply returns the pointer to the text, don't modify it! */ -const char* Label::QueryText() const -{ - return ( const char * ) Buffer; -} diff --git a/project/jni/application/gemrb/gemrb/core/GUI/Label.h b/project/jni/application/gemrb/gemrb/core/GUI/Label.h deleted file mode 100644 index 20ef5f9fc..000000000 --- a/project/jni/application/gemrb/gemrb/core/GUI/Label.h +++ /dev/null @@ -1,83 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -/** - * @file Label.h - * Declares Label widget for displaying static texts - * @author GemRB Developement Team - */ - -#ifndef LABEL_H -#define LABEL_H - -#include "GUI/Control.h" - -#include "RGBAColor.h" -#include "exports.h" - -#include "Font.h" - -class Palette; - -// !!! Keep these synchronized with GUIDefines.py !!! -#define IE_GUI_LABEL_ON_PRESS 0x06000000 - -/** - * @class Label - * Label widget for displaying static texts in the GUI - */ - -class GEM_EXPORT Label : public Control { -public: - Label(Font* font); - ~Label(); - /** Draws the Control on the Output Display */ - void Draw(unsigned short x, unsigned short y); - /** This function sets the actual Label Text */ - void SetText(const char* string); - /** Sets the Foreground Font Color */ - void SetColor(Color col, Color bac); - /** Sets the Alignment of Text */ - void SetAlignment(unsigned char Alignment); - /** Simply returns the pointer to the text, don't modify it! */ - const char* QueryText() const; - - /** Mouse Button Down */ - void OnMouseUp(unsigned short x, unsigned short y, unsigned short Button, - unsigned short Mod); - /** Set handler for specified event */ - bool SetEvent(int eventType, EventHandler handler); - /** Use the RGB Color for the Font */ - bool useRGB; - /** OnPress Scripted Event Function Name */ - EventHandler LabelOnPress; -private: // Private attributes - /** Text String Buffer */ - char* Buffer; - /** Font for Text Writing */ - Font* font; - /** Foreground & Background Colors */ - Palette* palette; - - /** Alignment Variable */ - unsigned char Alignment; -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/GUI/MapControl.cpp b/project/jni/application/gemrb/gemrb/core/GUI/MapControl.cpp deleted file mode 100644 index 459c438e4..000000000 --- a/project/jni/application/gemrb/gemrb/core/GUI/MapControl.cpp +++ /dev/null @@ -1,540 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "GUI/MapControl.h" - -#include "win32def.h" - -#include "Game.h" -#include "GlobalTimer.h" -#include "Interface.h" -#include "Map.h" -#include "Sprite2D.h" -#include "Video.h" -#include "GUI/EventMgr.h" -#include "GUI/Window.h" -#include "Scriptable/Actor.h" - -#define MAP_NO_NOTES 0 -#define MAP_VIEW_NOTES 1 -#define MAP_SET_NOTE 2 -#define MAP_REVEAL 3 - -// Ratio between pixel sizes of an Area (Big map) and a Small map - -static int MAP_DIV = 3; -static int MAP_MULT = 32; - -typedef enum {black=0, gray, violet, green, orange, red, blue, darkblue, darkgreen} colorcode; - -Color colors[]={ - { 0x00, 0x00, 0x00, 0xff }, //black - { 0x60, 0x60, 0x60, 0xff }, //gray - { 0xa0, 0x00, 0xa0, 0xff }, //violet - { 0x00, 0xff, 0x00, 0xff }, //green - { 0xff, 0xff, 0x00, 0xff }, //orange - { 0xff, 0x00, 0x00, 0xff }, //red - { 0x00, 0x00, 0xff, 0xff }, //blue - { 0x00, 0x00, 0x80, 0xff }, //darkblue - { 0x00, 0x80, 0x00, 0xff } //darkgreen -}; - -#define MAP_TO_SCREENX(x) (XWin + XPos + XCenter - ScrollX + (x)) -#define MAP_TO_SCREENY(y) (YWin + YPos + YCenter - ScrollY + (y)) -// Omit [XY]Pos, since these macros are used in OnMouseDown(x, y), and x, y is -// already relative to control [XY]Pos there -#define SCREEN_TO_MAPX(x) ((x) - XCenter + ScrollX) -#define SCREEN_TO_MAPY(y) ((y) - YCenter + ScrollY) - -#define GAME_TO_SCREENX(x) MAP_TO_SCREENX((int)((x) * MAP_DIV / MAP_MULT)) -#define GAME_TO_SCREENY(y) MAP_TO_SCREENY((int)((y) * MAP_DIV / MAP_MULT)) - -#define SCREEN_TO_GAMEX(x) (SCREEN_TO_MAPX(x) * MAP_MULT / MAP_DIV) -#define SCREEN_TO_GAMEY(y) (SCREEN_TO_MAPY(y) * MAP_MULT / MAP_DIV) - -MapControl::MapControl(void) -{ - if (core->HasFeature(GF_IWD_MAP_DIMENSIONS) ) { - MAP_DIV=4; - MAP_MULT=32; - } else { - MAP_DIV=3; - MAP_MULT=32; - } - - LinkedLabel = NULL; - ScrollX = 0; - ScrollY = 0; - NotePosX = 0; - NotePosY = 0; - mouseIsDown = false; - mouseIsDragging = false; - Changed = true; - convertToGame = true; - memset(Flag,0,sizeof(Flag) ); - - // initialize var and event callback to no-ops - VarName[0] = 0; - ResetEventHandler( MapControlOnPress ); - ResetEventHandler( MapControlOnRightPress ); - ResetEventHandler( MapControlOnDoublePress ); - - MyMap = core->GetGame()->GetCurrentArea(); - if (MyMap->SmallMap) { - MapMOS = MyMap->SmallMap; - MapMOS->acquire(); - } else - MapMOS = NULL; -} - -MapControl::~MapControl(void) -{ - Video *video = core->GetVideoDriver(); - - if (MapMOS) { - video->FreeSprite(MapMOS); - } - for(int i=0;i<8;i++) { - if (Flag[i]) { - video->FreeSprite(Flag[i]); - } - } -} - -// Draw fog on the small bitmap -void MapControl::DrawFog(unsigned short XWin, unsigned short YWin) -{ - Video *video = core->GetVideoDriver(); - - Region old_clip; - video->GetClipRect(old_clip); - - Region r( XWin + XPos, YWin + YPos, Width, Height ); - video->SetClipRect(&r); - - // FIXME: this is ugly, the knowledge of Map and ExploredMask - // sizes should be in Map.cpp - int w = MyMap->GetWidth() / 2; - int h = MyMap->GetHeight() / 2; - - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - Point p( (short) (MAP_MULT * x), (short) (MAP_MULT * y) ); - bool visible = MyMap->IsVisible( p, true ); - if (! visible) { - Region rgn = Region ( MAP_TO_SCREENX(MAP_DIV * x), MAP_TO_SCREENY(MAP_DIV * y), MAP_DIV, MAP_DIV ); - video->DrawRect( rgn, colors[black] ); - } - } - } - - video->SetClipRect(&old_clip); -} - -// To be called after changes in control's or screen geometry -void MapControl::Realize() -{ - // FIXME: ugly!! How to get area size in pixels? - //Map *map = core->GetGame()->GetCurrentMap(); - //MapWidth = map->GetWidth(); - //MapHeight = map->GetHeight(); - - if (MapMOS) { - MapWidth = (short) MapMOS->Width; - MapHeight = (short) MapMOS->Height; - } else { - MapWidth = 0; - MapHeight = 0; - } - - // FIXME: ugly hack! What is the actual viewport size? - ViewWidth = (short) (core->Width * MAP_DIV / MAP_MULT); - ViewHeight = (short) (core->Height * MAP_DIV / MAP_MULT); - - XCenter = (short) (Width - MapWidth ) / 2; - YCenter = (short) (Height - MapHeight ) / 2; - if (XCenter < 0) XCenter = 0; - if (YCenter < 0) YCenter = 0; -} - -void MapControl::RedrawMapControl(const char *VariableName, unsigned int Sum) -{ - if (strnicmp( VarName, VariableName, MAX_VARIABLE_LENGTH )) { - return; - } - Value = Sum; - Changed = true; -} - -/** Draws the Control on the Output Display */ -void MapControl::Draw(unsigned short XWin, unsigned short YWin) -{ - if (!Width || !Height) { - return; - } - if (Owner->Visible!=WINDOW_VISIBLE) { - return; - } - - if (Changed) { - Realize(); - Changed = false; - } - - // we're going to paint over labels/etc, so they need to repaint! - bool seen_this = false; - unsigned int i; - for (i = 0; i < Owner->GetControlCount(); i++) { - Control *ctrl = Owner->GetControl(i); - if (!ctrl) continue; - - // we could try working out which controls overlap, - // but the later controls are cheap to paint.. - if (ctrl == this) { seen_this = true; continue; } - if (!seen_this) continue; - - ctrl->Changed = true; - } - - Video* video = core->GetVideoDriver(); - Region r( XWin + XPos, YWin + YPos, Width, Height ); - - if (MapMOS) { - video->BlitSprite( MapMOS, MAP_TO_SCREENX(0), MAP_TO_SCREENY(0), true, &r ); - } - - if (core->FogOfWar&FOG_DRAWFOG) - DrawFog(XWin, YWin); - - Region vp = video->GetViewport(); - - vp.x = GAME_TO_SCREENX(vp.x); - vp.y = GAME_TO_SCREENY(vp.y); - vp.w = ViewWidth; - vp.h = ViewHeight; - - if ((vp.x + vp.w) >= MAP_TO_SCREENX( Width )) - vp.w = MAP_TO_SCREENX( Width ) - vp.x; - if ((vp.y + vp.h) >= MAP_TO_SCREENY( Height )) - vp.h = MAP_TO_SCREENY( Height ) - vp.y; - - video->DrawRect( vp, colors[green], false, false ); - - // Draw PCs' ellipses - Game *game = core->GetGame(); - i = game->GetPartySize(true); - while (i--) { - Actor* actor = game->GetPC( i, true ); - if (MyMap->HasActor(actor) ) { - video->DrawEllipse( (short) GAME_TO_SCREENX(actor->Pos.x), (short) GAME_TO_SCREENY(actor->Pos.y), 3, 2, actor->Selected ? colors[green] : colors[darkgreen], false ); - } - } - // Draw Map notes, could be turned off in bg2 - // we use the common control value to handle it, because then we - // don't need another interface - if (Value!=MAP_NO_NOTES) { - i = MyMap -> GetMapNoteCount(); - while (i--) { - MapNote * mn = MyMap -> GetMapNote(i); - Sprite2D *anim = Flag[mn->color&7]; - Point pos = mn->Pos; - if (convertToGame) { - vp.x = GAME_TO_SCREENX(mn->Pos.x); - vp.y = GAME_TO_SCREENY(mn->Pos.y); - } else { //pst style - vp.x = MAP_TO_SCREENX(mn->Pos.x); - vp.y = MAP_TO_SCREENY(mn->Pos.y); - pos.x = pos.x * MAP_MULT / MAP_DIV; - pos.y = pos.y * MAP_MULT / MAP_DIV; - } - - //Skip unexplored map notes - bool visible = MyMap->IsVisible( pos, true ); - if (!visible) - continue; - - if (anim) { - video->BlitSprite( anim, vp.x - anim->Width/2, vp.y - anim->Height/2, true, &r ); - } else { - video->DrawEllipse( (short) vp.x, (short) vp.y, 6, 5, colors[mn->color&7], false ); - } - } - } -} - -/** Key Press Event */ -void MapControl::OnKeyPress(unsigned char /*Key*/, unsigned short /*Mod*/) -{ -} - -/** Key Release Event */ -void MapControl::OnKeyRelease(unsigned char Key, unsigned short Mod) -{ - switch (Key) { - case '\t': - //not GEM_TAB - print( "TAB released\n" ); - return; - case 'f': - if (Mod & GEM_MOD_CTRL) - core->GetVideoDriver()->ToggleFullscreenMode(); - break; - default: - break; - } - if (!core->CheatEnabled()) { - return; - } -} -/** Mouse Over Event */ -void MapControl::OnMouseOver(unsigned short x, unsigned short y) -{ - if (mouseIsDown) { - ScrollX -= x - lastMouseX; - ScrollY -= y - lastMouseY; - - if (ScrollX > MapWidth - Width) - ScrollX = MapWidth - Width; - if (ScrollY > MapHeight - Height) - ScrollY = MapHeight - Height; - if (ScrollX < 0) - ScrollX = 0; - if (ScrollY < 0) - ScrollY = 0; - } - - if (mouseIsDragging) { - ViewHandle(x,y); - } - - lastMouseX = x; - lastMouseY = y; - - switch (Value) { - case MAP_REVEAL: //for farsee effect - Owner->Cursor = IE_CURSOR_CAST; - break; - case MAP_SET_NOTE: - Owner->Cursor = IE_CURSOR_GRAB; - break; - default: - Owner->Cursor = IE_CURSOR_NORMAL; - break; - } - - if (Value == MAP_VIEW_NOTES || Value == MAP_SET_NOTE || Value == MAP_REVEAL) { - Point mp; - unsigned int dist; - - if (convertToGame) { - mp.x = (short) SCREEN_TO_GAMEX(x); - mp.y = (short) SCREEN_TO_GAMEY(y); - dist = 100; - } else { - mp.x = (short) SCREEN_TO_MAPX(x); - mp.y = (short) SCREEN_TO_MAPY(y); - dist = 16; - } - int i = MyMap -> GetMapNoteCount(); - while (i--) { - MapNote * mn = MyMap -> GetMapNote(i); - if (Distance(mp, mn->Pos)SetText( mn->text ); - } - NotePosX = mn->Pos.x; - NotePosY = mn->Pos.y; - return; - } - } - NotePosX = mp.x; - NotePosY = mp.y; - } - if (LinkedLabel) { - LinkedLabel->SetText( "" ); - } -} - -/** Mouse Leave Event */ -void MapControl::OnMouseLeave(unsigned short /*x*/, unsigned short /*y*/) -{ - Owner->Cursor = IE_CURSOR_NORMAL; -} - -void MapControl::ClickHandle(unsigned short Button) -{ - core->GetDictionary()->SetAt( "MapControlX", NotePosX ); - core->GetDictionary()->SetAt( "MapControlY", NotePosY ); - switch(Button&GEM_MB_NORMAL) { - case GEM_MB_ACTION: - if (Button&GEM_MB_DOUBLECLICK) { - RunEventHandler( MapControlOnDoublePress ); - } else { - RunEventHandler( MapControlOnPress ); - } - break; - case GEM_MB_MENU: - RunEventHandler( MapControlOnRightPress ); - break; - default: - break; - } -} - -void MapControl::ViewHandle(unsigned short x, unsigned short y) -{ - short xp = (short) (SCREEN_TO_MAPX(x) - ViewWidth / 2); - short yp = (short) (SCREEN_TO_MAPY(y) - ViewHeight / 2); - - if (xp + ViewWidth > MapWidth) xp = MapWidth - ViewWidth; - if (yp + ViewHeight > MapHeight) yp = MapHeight - ViewHeight; - if (xp < 0) xp = 0; - if (yp < 0) yp = 0; - - // clear any previously scheduled moves and then do it asap, so it works while paused - unsigned int vpx = xp * MAP_MULT / MAP_DIV; - unsigned int vpy = yp * MAP_MULT / MAP_DIV; - core->timer->SetMoveViewPort( vpx, vpy, 0, false ); - core->GetVideoDriver()->MoveViewportTo( vpx, vpy ); -} - -/** Mouse Button Down */ -void MapControl::OnMouseDown(unsigned short x, unsigned short y, unsigned short Button, - unsigned short /*Mod*/) -{ - switch((unsigned char) Button) { - case GEM_MB_SCRLUP: - OnSpecialKeyPress(GEM_UP); - return; - case GEM_MB_SCRLDOWN: - OnSpecialKeyPress(GEM_DOWN); - return; - case GEM_MB_ACTION: - if (Button & GEM_MB_DOUBLECLICK) { - ClickHandle(Button); - } - break; - default: - break; - } - - mouseIsDown = true; - short xp = (short) (SCREEN_TO_GAMEX(x)); - short yp = (short) (SCREEN_TO_GAMEY(y)); - Region vp = core->GetVideoDriver()->GetViewport(); - vp.w = vp.x+ViewWidth*MAP_MULT/MAP_DIV; - vp.h = vp.y+ViewHeight*MAP_MULT/MAP_DIV; - if ((xp>vp.x) && (xpvp.y) && (yp MapWidth - Width) - ScrollX = MapWidth - Width; - if (ScrollY > MapHeight - Height) - ScrollY = MapHeight - Height; - if (ScrollX < 0) - ScrollX = 0; - if (ScrollY < 0) - ScrollY = 0; -} - -bool MapControl::SetEvent(int eventType, EventHandler handler) -{ - Changed = true; - - switch (eventType) { - case IE_GUI_MAP_ON_PRESS: - MapControlOnPress = handler; - break; - case IE_GUI_MAP_ON_RIGHT_PRESS: - MapControlOnRightPress = handler; - break; - case IE_GUI_MAP_ON_DOUBLE_PRESS: - MapControlOnDoublePress = handler; - break; - default: - return false; - } - - return true; -} diff --git a/project/jni/application/gemrb/gemrb/core/GUI/MapControl.h b/project/jni/application/gemrb/gemrb/core/GUI/MapControl.h deleted file mode 100644 index 44ecec887..000000000 --- a/project/jni/application/gemrb/gemrb/core/GUI/MapControl.h +++ /dev/null @@ -1,108 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -/** - * @file MapControl.h - * Declares MapControl, widget for displaying current area map - */ - -class MapControl; - -#ifndef MAPCONTROL_H -#define MAPCONTROL_H - -#include "GUI/Control.h" - -#include "exports.h" -#include "Interface.h" - -// !!! Keep these synchronized with GUIDefines.py !!! -#define IE_GUI_MAP_ON_PRESS 0x09000000 -#define IE_GUI_MAP_ON_RIGHT_PRESS 0x09000005 -#define IE_GUI_MAP_ON_DOUBLE_PRESS 0x09000008 - - -/** - * @class MapControl - * Widget displaying current area map, with a viewport rectangle - * and PCs' ground circles - */ - -class GEM_EXPORT MapControl : public Control { -public: - int ScrollX, ScrollY; - int NotePosX, NotePosY; - unsigned short lastMouseX, lastMouseY; - bool mouseIsDown; - bool mouseIsDragging; - bool convertToGame; - // Small map bitmap - Sprite2D* MapMOS; - // current map - Map *MyMap; - // map flags - Sprite2D *Flag[8]; - // The MapControl can set the text of this label directly - Control *LinkedLabel; - // Size of big map (area) in pixels - short MapWidth, MapHeight; - // Size of area viewport. FIXME: hack! - short ViewWidth, ViewHeight; - short XCenter, YCenter; - EventHandler MapControlOnPress; - EventHandler MapControlOnRightPress; - EventHandler MapControlOnDoublePress; - - MapControl(void); - ~MapControl(void); - /** redraws the control after its associated variable has changed */ - void RedrawMapControl(const char *VariableName, unsigned int Sum); - /** Draws the Control on the Output Display */ - void Draw(unsigned short XWin, unsigned short YWin); - void DrawFog(unsigned short XWin, unsigned short YWin); - /** Compute parameters after changes in control's or screen geometry */ - void Realize(); - - /** Key Press Event */ - void OnKeyPress(unsigned char Key, unsigned short Mod); - /** Mouse Over Event */ - void OnMouseOver(unsigned short x, unsigned short y); - /** Mouse Leave Event */ - void OnMouseLeave(unsigned short x, unsigned short y); - /** Mouse Button Down */ - void OnMouseDown(unsigned short x, unsigned short y, unsigned short Button, - unsigned short Mod); - /** Mouse Button Up */ - void OnMouseUp(unsigned short x, unsigned short y, unsigned short Button, - unsigned short Mod); - /** Key Release Event */ - void OnKeyRelease(unsigned char Key, unsigned short Mod); - /** Special Key Press */ - void OnSpecialKeyPress(unsigned char Key); - /** Set handler for specified event */ - bool SetEvent(int eventType, EventHandler handler); -private: - /** Call event handler on click */ - void ClickHandle(unsigned short Button); - /** Move viewport */ - void ViewHandle(unsigned short x, unsigned short y); -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/GUI/Progressbar.cpp b/project/jni/application/gemrb/gemrb/core/GUI/Progressbar.cpp deleted file mode 100644 index 1c09586d1..000000000 --- a/project/jni/application/gemrb/gemrb/core/GUI/Progressbar.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "GUI/Progressbar.h" - -#include "win32def.h" - -#include "Interface.h" -#include "Video.h" -#include "GUI/Window.h" - -#include - -Progressbar::Progressbar( unsigned short KnobStepsCount, bool Clear) -{ - BackGround = NULL; - BackGround2 = NULL; - this->Clear = Clear; - this->KnobStepsCount = KnobStepsCount; - PBarAnim = NULL; - PBarCap = NULL; - KnobXPos = KnobYPos = 0; - CapXPos = CapYPos = 0; - ResetEventHandler( EndReached ); -} - -Progressbar::~Progressbar() -{ - if (!Clear) { - return; - } - core->GetVideoDriver()->FreeSprite( BackGround ); - core->GetVideoDriver()->FreeSprite( BackGround2 ); - delete PBarAnim; - core->GetVideoDriver()->FreeSprite( PBarCap ); -} - -/** Draws the Control on the Output Display */ -void Progressbar::Draw(unsigned short x, unsigned short y) -{ - //it is unlikely that a floating window is above us, but... - if (!Changed && !(Owner->Flags&WF_FLOAT) ) { - return; - } - Changed = false; - if (XPos == 65535) { - return; - } - Sprite2D *bcksprite; - - if((Value >= 100) && KnobStepsCount && BackGround2) { - bcksprite=BackGround2; //animated progbar end stage - } - else { - bcksprite=BackGround; - } - if (bcksprite) { - Region r( x + XPos, y + YPos, Width, Height ); - core->GetVideoDriver()->BlitSprite( bcksprite, - x + XPos, y + YPos, true, &r ); - if( bcksprite==BackGround2) { - return; //done for animated progbar - } - } - - unsigned int Count; - - if(!KnobStepsCount) { - //linear progressbar (pst, iwd) - int w = BackGround2->Width; - int h = BackGround2->Height; - //this is the PST/IWD specific part - Count = Value*w/100; - Region r( x + XPos + KnobXPos, y + YPos + KnobYPos, Count, h ); - core->GetVideoDriver()->BlitSprite( BackGround2, - r.x, r.y, true, &r ); - - core->GetVideoDriver()->BlitSprite( PBarCap, - x+XPos+CapXPos+Count-PBarCap->Width, y+YPos+CapYPos, true ); - return; - } - - //animated progressbar (bg2) - Count=Value*KnobStepsCount/100; - for(unsigned int i=0; iGetFrame(i); - core->GetVideoDriver()->BlitSprite( Knob, x , y , true ); - } -} - -/** Returns the actual Progressbar Position */ -unsigned int Progressbar::GetPosition() -{ - return Value; -} - -/** Sets the actual Progressbar Position trimming to the Max and Min Values */ -void Progressbar::SetPosition(unsigned int pos) -{ - if(pos>100) pos=100; - if (Value == pos) - return; - Value = pos; - Changed = true; -} - -void Progressbar::RedrawProgressbar(const char* VariableName, int Sum) -{ - if (strnicmp( VarName, VariableName, MAX_VARIABLE_LENGTH )) { - return; - } - SetPosition((unsigned int) Sum); - if((Value==100) && Changed) - RunEventHandler( EndReached ); -} - -/** Sets the selected image */ -void Progressbar::SetImage(Sprite2D* img, Sprite2D* img2) -{ - if (BackGround && Clear) - core->GetVideoDriver()->FreeSprite( BackGround ); - BackGround = img; - if (BackGround2 && Clear) - core->GetVideoDriver()->FreeSprite( BackGround2 ); - BackGround2 = img2; - Changed = true; -} - -void Progressbar::SetBarCap(Sprite2D* img3) -{ - core->GetVideoDriver()->FreeSprite( PBarCap ); - PBarCap = img3; -} - -void Progressbar::SetAnimation(Animation *arg) -{ - delete PBarAnim; - PBarAnim = arg; -} - -void Progressbar::SetSliderPos(int x, int y, int x2, int y2) -{ - KnobXPos=x; - KnobYPos=y; - CapXPos=x2; - CapYPos=y2; -} - -bool Progressbar::SetEvent(int eventType, EventHandler handler) -{ - Changed = true; - - switch (eventType) { - case IE_GUI_PROGRESS_END_REACHED: - EndReached = handler; - break; - default: - return false; - } - - return true; -} diff --git a/project/jni/application/gemrb/gemrb/core/GUI/Progressbar.h b/project/jni/application/gemrb/gemrb/core/GUI/Progressbar.h deleted file mode 100644 index 6a777c42f..000000000 --- a/project/jni/application/gemrb/gemrb/core/GUI/Progressbar.h +++ /dev/null @@ -1,87 +0,0 @@ -/* 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. - * - * - */ - -/** - * @file Progressbar.h - * Declares Progressbar widget for displaying progress of loading and saving games - */ - -#ifndef PROGRESSBAR_H -#define PROGRESSBAR_H - -#include "GUI/Control.h" - -#include "exports.h" - -#include "Animation.h" -#include "Sprite2D.h" - -// !!! Keep in sync with GUIDefines.py !!! -#define IE_GUI_PROGRESS_END_REACHED 0x01000000 - - -/** - * @class Progressbar - * Widget for displaying progressbars, mainly on loading/saving screens - */ - -class GEM_EXPORT Progressbar : public Control { -public: - Progressbar(unsigned short KnobStepsCount, bool Clear = false); - ~Progressbar(); - /** Draws the Control on the Output Display */ - void Draw(unsigned short x, unsigned short y); - /** Returns the actual Progressbar Position */ - unsigned int GetPosition(); - /** Sets the actual Progressbar Position trimming to the Max and Min Values */ - void SetPosition(unsigned int pos); - /** Sets the background images */ - void SetImage(Sprite2D * img, Sprite2D * img2); - /** Sets a bam resource for progressbar */ - void SetAnimation(Animation *arg); - /** Sets a mos resource for progressbar cap */ - void SetBarCap(Sprite2D *img3); - /** Sets the mos coordinates for the progressbar filler mos/cap */ - void SetSliderPos(int x, int y, int x2, int y2); - /** Redraws a progressbar which is associated with VariableName */ - void RedrawProgressbar(const char *VariableName, int Sum); - /** Set handler for specified event */ - bool SetEvent(int eventType, EventHandler handler); - -private: // Private attributes - /** BackGround Images. If smaller than the Control Size, the image will be tiled. */ - Sprite2D * BackGround; - Sprite2D * BackGround2; //mos resource for the filling of the bar - /** Knob Steps Count */ - unsigned int KnobStepsCount; - int KnobXPos, KnobYPos; //relative coordinates for Background2 - int CapXPos, CapYPos; //relative coordinates for PBarCap - /** If true, on deletion the Progressbar will destroy the associated images */ - bool Clear; - /** The bam cycle whose frames work as a progressbar (animated progressbar) */ - Animation *PBarAnim; - /** The most for the progressbar cap (linear progressbar) */ - Sprite2D *PBarCap; -public: - /** EndReached Scripted Event Function Name */ - EventHandler EndReached; -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/GUI/ScrollBar.cpp b/project/jni/application/gemrb/gemrb/core/GUI/ScrollBar.cpp deleted file mode 100644 index 3893c684f..000000000 --- a/project/jni/application/gemrb/gemrb/core/GUI/ScrollBar.cpp +++ /dev/null @@ -1,293 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "GUI/ScrollBar.h" - -#include "win32def.h" - -#include "Interface.h" -#include "Variables.h" -#include "Video.h" -#include "GUI/EventMgr.h" -#include "GUI/Window.h" - -ScrollBar::ScrollBar(void) -{ - Pos = 0; - Value = 10; - State = 0; - ResetEventHandler( ScrollBarOnChange ); - ta = NULL; - for(int i=0;iGetVideoDriver(); - for(int i=0;iFreeSprite(Frames[i]); - } - } -} - -/** Sets a new position, relays the change to an associated textarea and calls - any existing GUI OnChange callback */ -void ScrollBar::SetPos(int NewPos) -{ - if (Pos && ( Pos == NewPos )) { - return; - } - Changed = true; - Pos = (ieWord) NewPos; - if (ta) { - TextArea* t = ( TextArea* ) ta; - t->SetRow( Pos ); - } - if (VarName[0] != 0) { - core->GetDictionary()->SetAt( VarName, Pos ); - } - RunEventHandler( ScrollBarOnChange ); -} - -/** Refreshes the ScrollBar according to a guiscript variable */ -void ScrollBar::RedrawScrollBar(const char* Variable, int Sum) -{ - if (strnicmp( VarName, Variable, MAX_VARIABLE_LENGTH )) { - return; - } - SetPos( Sum ); -} - -/** Mousewheel support */ -void ScrollBar::ScrollUp() -{ - if (Pos > 0) { - SetPos( Pos - 1 ); - } -} - -/** Mousewheel support */ -void ScrollBar::ScrollDown() -{ - if ( (ieDword) Pos + 1 < Value ) { - SetPos( Pos + 1 ); - } -} - -/** Draws the ScrollBar control */ -void ScrollBar::Draw(unsigned short x, unsigned short y) -{ - if (!Changed && !(Owner->Flags&WF_FLOAT) ) { - return; - } - Changed = false; - if (XPos == 65535) { - return; - } - int upMy = Frames[IE_GUI_SCROLLBAR_UP_UNPRESSED]->Height; - int doMy = Frames[IE_GUI_SCROLLBAR_DOWN_UNPRESSED]->Height; - unsigned int domy = (Height - doMy); - - unsigned short slmy = ( unsigned short ) - ( upMy + - ( Pos * ( ( domy - Frames[IE_GUI_SCROLLBAR_SLIDER]->Height - upMy ) / - ( double ) ( Value < 2 ? 1 : Value - 1 ) ) ) ); - unsigned short slx = ( unsigned short ) ((Width - Frames[IE_GUI_SCROLLBAR_SLIDER]->Width) / 2 ); - - if (( State & UP_PRESS ) != 0) { - core->GetVideoDriver()->BlitSprite( Frames[IE_GUI_SCROLLBAR_UP_PRESSED], - x + XPos, y + YPos, true ); - } else { - core->GetVideoDriver()->BlitSprite( Frames[IE_GUI_SCROLLBAR_UP_UNPRESSED], - x + XPos, y + YPos, true ); - } - int maxy = y + YPos + Height - - Frames[IE_GUI_SCROLLBAR_DOWN_UNPRESSED]->Height; - int stepy = Frames[IE_GUI_SCROLLBAR_TROUGH]->Height; - Region rgn( x + XPos, y + YPos + upMy, Width, domy - upMy); - for (int dy = y + YPos + upMy; dy < maxy; dy += stepy) { - core->GetVideoDriver()->BlitSprite( Frames[IE_GUI_SCROLLBAR_TROUGH], - x + XPos + ( ( Width / 2 ) - - Frames[IE_GUI_SCROLLBAR_TROUGH]->Width / 2 ), - dy, true, &rgn ); - } - if (( State & DOWN_PRESS ) != 0) { - core->GetVideoDriver()->BlitSprite( Frames[IE_GUI_SCROLLBAR_DOWN_PRESSED], - x + XPos, maxy, true ); - } else { - core->GetVideoDriver()->BlitSprite( Frames[IE_GUI_SCROLLBAR_DOWN_UNPRESSED], - x + XPos, maxy, true ); - } - core->GetVideoDriver()->BlitSprite( Frames[IE_GUI_SCROLLBAR_SLIDER], - x + XPos + slx + Frames[IE_GUI_SCROLLBAR_SLIDER]->XPos, - y + YPos + slmy + Frames[IE_GUI_SCROLLBAR_SLIDER]->YPos, - true ); -} - -/** Sets a ScrollBar GUI resource */ -void ScrollBar::SetImage(unsigned char type, Sprite2D* img) -{ - if (type >= SB_RES_COUNT) { - return; - } - if (Frames[type]) { - core->GetVideoDriver()->FreeSprite(Frames[type]); - } - Frames[type] = img; - Changed = true; -} - -/** Mouse Button Down */ -void ScrollBar::OnMouseDown(unsigned short x, unsigned short y, - unsigned short Button, unsigned short /*Mod*/) -{ - //removing the double click flag, use a more sophisticated method - //if it is needed later - Button&=GEM_MB_NORMAL; - if (Button==GEM_MB_SCRLUP) { - ScrollUp(); - return; - } - if (Button==GEM_MB_SCRLDOWN) { - ScrollDown(); - return; - } - - core->RedrawAll(); - - unsigned short upMx = (unsigned short) Frames[IE_GUI_SCROLLBAR_UP_UNPRESSED]->Width; - unsigned short upMy = (unsigned short) Frames[IE_GUI_SCROLLBAR_UP_UNPRESSED]->Height; - unsigned short domy = (unsigned short) (Height - Frames[IE_GUI_SCROLLBAR_DOWN_UNPRESSED]->Height); - unsigned short slheight = domy - upMy; - unsigned short refheight = (unsigned short) (slheight - Frames[IE_GUI_SCROLLBAR_SLIDER]->Height); - double step = refheight / (double) ( Value < 2 ? 1 : Value - 1 ); - unsigned short ymax = upMy + refheight; - unsigned short ymy = y - upMy; - unsigned short doMx = (unsigned short) Frames[IE_GUI_SCROLLBAR_DOWN_UNPRESSED]->Width; - unsigned short slMx = (unsigned short) Frames[IE_GUI_SCROLLBAR_SLIDER]->Width; - unsigned short slmy = (unsigned short) (upMy + Pos * step); - unsigned short slMy = (unsigned short) (slmy + Frames[IE_GUI_SCROLLBAR_SLIDER]->Height); - if (( x <= upMx ) && ( y <= upMy )) { - if (Pos > 0) - SetPos( Pos - 1 ); - State |= UP_PRESS; - return; - } - if (y >= domy) { - if (( x <= doMx ) && ( y <= Height )) { - if ( (ieDword) Pos + 1 < Value ) - SetPos( Pos + 1 ); - State |= DOWN_PRESS; - return; - } - } - if (y >= slmy) { - if (( x <= slMx ) && ( y <= slMy )) { - State |= SLIDER_GRAB; - return; - } - } - if (y <= upMy) { - SetPos( 0 ); - return; - } - if (y >= ymax) { - SetPos( Value - 1 ); - return; - } - unsigned short befst = ( unsigned short ) ( ymy / step ); - unsigned short aftst = befst + 1; - if (( ymy - ( befst * step ) ) < ( ( aftst * step ) - ymy )) { - SetPos( befst ); - } else { - SetPos( aftst ); - } -} - -/** Mouse Button Up */ -void ScrollBar::OnMouseUp(unsigned short /*x*/, unsigned short /*y*/, - unsigned short /*Button*/, unsigned short /*Mod*/) -{ - Changed = true; - State = 0; -} - -/** Mouse Over Event */ -void ScrollBar::OnMouseOver(unsigned short /*x*/, unsigned short y) -{ - if (( State & SLIDER_GRAB ) != 0) { - core->RedrawAll(); - unsigned short upMy =(unsigned short) Frames[IE_GUI_SCROLLBAR_UP_UNPRESSED]->Height; - unsigned short domy = (unsigned short) (Height - Frames[IE_GUI_SCROLLBAR_DOWN_UNPRESSED]->Height); - unsigned short slheight = domy - upMy; - unsigned short refheight = (unsigned short) (slheight - Frames[IE_GUI_SCROLLBAR_SLIDER]->Height); - double step = refheight / ( double ) ( Value < 2 ? 1 : Value - 1 ); - unsigned short yzero = (unsigned short) (upMy + Frames[IE_GUI_SCROLLBAR_SLIDER]->Height / 2 ); - unsigned short ymax = yzero + refheight; - unsigned short ymy = y - yzero; - if (y <= yzero) { - SetPos( 0 ); - return; - } - if (y >= ymax) { - SetPos( Value - 1 ); - return; - } - unsigned short befst = ( unsigned short ) ( ymy / step ); - unsigned short aftst = befst + 1; - if (( ymy - ( befst * step ) ) < ( ( aftst * step ) - ymy )) { - if (befst > Value ) - SetPos( befst ); - } else { - if (aftst < Value ) - SetPos( aftst ); - } - } -} - -/** Sets the Maximum Value of the ScrollBar */ -void ScrollBar::SetMax(unsigned short Max) -{ - Value = Max; - if (Max == 0) { - SetPos( 0 ); - } else if (Pos >= Max) { - SetPos( Max - 1 ); - } -} - -/** Sets the ScrollBarOnChange event (guiscript callback) */ -bool ScrollBar::SetEvent(int eventType, EventHandler handler) -{ - Changed = true; - - switch (eventType) { - case IE_GUI_SCROLLBAR_ON_CHANGE: - ScrollBarOnChange = handler; - break; - default: - return false; - } - - return true; -} diff --git a/project/jni/application/gemrb/gemrb/core/GUI/ScrollBar.h b/project/jni/application/gemrb/gemrb/core/GUI/ScrollBar.h deleted file mode 100644 index 3effd49c2..000000000 --- a/project/jni/application/gemrb/gemrb/core/GUI/ScrollBar.h +++ /dev/null @@ -1,101 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -/** - * @file ScrollBar.h - * Declares ScrollBar widget for paging in long text windows. - * This does not include scales and sliders, which are of Slider class. - * @author The GemRB Project - */ - -#ifndef SCROLLBAR_H -#define SCROLLBAR_H - -#include "GUI/Control.h" -#include "GUI/TextArea.h" - -#include "exports.h" - -#include "Sprite2D.h" - -// !!! Keep these synchronized with GUIDefines.py !!! -#define IE_GUI_SCROLLBAR_ON_CHANGE 0x07000000 - -#define IE_GUI_SCROLLBAR_DEFAULT 0x00000040 // mousewheel triggers it - -#define IE_GUI_SCROLLBAR_UP_UNPRESSED 0 -#define IE_GUI_SCROLLBAR_UP_PRESSED 1 -#define IE_GUI_SCROLLBAR_DOWN_UNPRESSED 2 -#define IE_GUI_SCROLLBAR_DOWN_PRESSED 3 -#define IE_GUI_SCROLLBAR_TROUGH 4 -#define IE_GUI_SCROLLBAR_SLIDER 5 - -#define UP_PRESS 0x0001 -#define DOWN_PRESS 0x0010 -#define SLIDER_GRAB 0x0100 - -/** - * @class ScrollBar - * Widget displaying scrollbars for paging in long text windows - */ - -#define SB_RES_COUNT 6 - -class GEM_EXPORT ScrollBar : public Control { -public: - ScrollBar(void); - ~ScrollBar(void); - /**sets position, updates associated stuff */ - void SetPos(int NewPos); - void ScrollUp(); - void ScrollDown(); - /**redraws scrollbar if associated with VarName */ - void RedrawScrollBar(const char* VarName, int Sum); - /**/ - void Draw(unsigned short x, unsigned short y); -private: //Private attributes - /** Images for drawing the Scroll Bar */ - Sprite2D* Frames[SB_RES_COUNT]; - /** Cursor Position */ - unsigned short Pos; - /** Scroll Bar Status */ - unsigned short State; -public: - void SetImage(unsigned char type, Sprite2D* img); - /** Sets the Maximum Value of the ScrollBar */ - void SetMax(unsigned short Max); - /** TextArea Associated Control */ - Control* ta; -public: // Public Events - /** Mouse Button Down */ - void OnMouseDown(unsigned short x, unsigned short y, unsigned short Button, - unsigned short Mod); - /** Mouse Button Up */ - void OnMouseUp(unsigned short x, unsigned short y, unsigned short Button, - unsigned short Mod); - /** Mouse Over Event */ - void OnMouseOver(unsigned short x, unsigned short y); - /** Set handler for specified event */ - bool SetEvent(int eventType, EventHandler handler); - /** OnChange Scripted Event Function Name */ - EventHandler ScrollBarOnChange; -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/GUI/Slider.cpp b/project/jni/application/gemrb/gemrb/core/GUI/Slider.cpp deleted file mode 100644 index d9e24e2dd..000000000 --- a/project/jni/application/gemrb/gemrb/core/GUI/Slider.cpp +++ /dev/null @@ -1,291 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "GUI/Slider.h" - -#include "win32def.h" - -#include "Interface.h" -#include "Variables.h" -#include "Video.h" -#include "GUI/Window.h" - -#include - -Slider::Slider(short KnobXPos, short KnobYPos, short KnobStep, - unsigned short KnobStepsCount, bool Clear) -{ - this->KnobXPos = KnobXPos; - this->KnobYPos = KnobYPos; - this->KnobStep = KnobStep; - this->KnobStepsCount = KnobStepsCount; - Knob = NULL; - GrabbedKnob = NULL; - BackGround = NULL; - this->Clear = Clear; - ResetEventHandler( SliderOnChange ); - State = IE_GUI_SLIDER_KNOB; - Pos = 0; - Value = 1; -} - -Slider::~Slider() -{ - if (!Clear) { - return; - } - if (Knob) { - core->GetVideoDriver()->FreeSprite( Knob ); - } - if (GrabbedKnob) { - core->GetVideoDriver()->FreeSprite( GrabbedKnob ); - } - if (BackGround) { - core->GetVideoDriver()->FreeSprite( BackGround ); - } -} - -/** Draws the Control on the Output Display */ -void Slider::Draw(unsigned short x, unsigned short y) -{ - if (!Changed && !(Owner->Flags&WF_FLOAT) ) { - return; - } - Changed = false; - if (XPos == 65535) { - return; - } - Region r( x + XPos, y + YPos, Width, Height ); - if (BackGround) { - if (( BackGround->Width < Width ) || ( BackGround->Height < Height )) { - core->GetVideoDriver()->BlitTiled( r, BackGround, true ); - } else { - core->GetVideoDriver()->BlitSprite( BackGround, x + XPos, y + YPos, true, &r ); - } - } - switch (State) { - case IE_GUI_SLIDER_KNOB: - core->GetVideoDriver()->BlitSprite( Knob, - x + XPos + KnobXPos + ( Pos * KnobStep ), - y + YPos + KnobYPos, true ); - break; - - case IE_GUI_SLIDER_GRABBEDKNOB: - core->GetVideoDriver()->BlitSprite( GrabbedKnob, - x + XPos + KnobXPos + ( Pos * KnobStep ), - y + YPos + KnobYPos, true ); - break; - } -} - -/** Returns the actual Slider Position */ -unsigned int Slider::GetPosition() -{ - return Pos; -} - -/** Sets the actual Slider Position trimming to the Max and Min Values */ -void Slider::SetPosition(unsigned int pos) -{ - if (pos <= KnobStepsCount) { - Pos = pos; - } - if (VarName[0] != 0) { - if (!Value) - Value = 1; - core->GetDictionary()->SetAt( VarName, pos * Value ); - } - Changed = true; -} - -/** Redraws a slider which is associated with VariableName */ -void Slider::RedrawSlider(const char* VariableName, int Sum) -{ - if (strnicmp( VarName, VariableName, MAX_VARIABLE_LENGTH )) { - return; - } - if (!Value) { - Value = 1; - } - Sum /= Value; - if (Sum <= KnobStepsCount) { - Pos = Sum; - } - Changed = true; -} - -/** Sets the selected image */ -void Slider::SetImage(unsigned char type, Sprite2D* img) -{ - switch (type) { - case IE_GUI_SLIDER_KNOB: - if (Knob && Clear) - core->GetVideoDriver()->FreeSprite( Knob ); - Knob = img; - break; - - case IE_GUI_SLIDER_GRABBEDKNOB: - if (GrabbedKnob && Clear) - core->GetVideoDriver()->FreeSprite( GrabbedKnob ); - GrabbedKnob = img; - break; - - case IE_GUI_SLIDER_BACKGROUND: - if (BackGround && Clear) - core->GetVideoDriver()->FreeSprite( BackGround ); - BackGround = img; - break; - } - Changed = true; -} - -/** Mouse Button Down */ -void Slider::OnMouseDown(unsigned short x, unsigned short y, unsigned short /*Button*/, - unsigned short /*Mod*/) -{ - Changed = true; - unsigned int oldPos = Pos; - int mx = (KnobXPos + ( Pos * KnobStep ) - Knob->XPos); - int my = (KnobYPos - Knob->YPos); - int Mx = (mx + Knob->Width); - int My = (my + Knob->Height); - - if (( x >= mx ) && ( y >= my )) { - if (( x <= Mx ) && ( y <= My )) { - State = IE_GUI_SLIDER_GRABBEDKNOB; - } else { - int mx = KnobXPos; - int xmx = x - mx; - if (x < mx) { - SetPosition( 0 ); - if (oldPos != Pos) { - RunEventHandler( SliderOnChange ); - } - return; - } - int befst = xmx / KnobStep; - if (befst >= KnobStepsCount) { - SetPosition( KnobStepsCount - 1 ); - if (oldPos != Pos) { - RunEventHandler( SliderOnChange ); - } - return; - } - int aftst = befst + KnobStep; - if (( xmx - ( befst * KnobStep ) ) < - ( ( aftst * KnobStep ) - xmx )) { - SetPosition( befst ); - } else { - SetPosition( aftst ); - } - if (oldPos != Pos) { - RunEventHandler( SliderOnChange ); - } - } - } else { - int mx = KnobXPos; - int xmx = x - mx; - if (x < mx) { - SetPosition( 0 ); - if (oldPos != Pos) { - RunEventHandler( SliderOnChange ); - } - return; - } - int befst = xmx / KnobStep; - if (befst >= KnobStepsCount) { - SetPosition( KnobStepsCount - 1 ); - if (oldPos != Pos) { - RunEventHandler( SliderOnChange ); - } - return; - } - int aftst = befst + KnobStep; - if (( xmx - ( befst * KnobStep ) ) < ( ( aftst * KnobStep ) - xmx )) { - SetPosition( befst ); - } else { - SetPosition( aftst ); - } - if (oldPos != Pos) { - RunEventHandler( SliderOnChange ); - } - } -} - -/** Mouse Button Up */ -void Slider::OnMouseUp(unsigned short /*x*/, unsigned short /*y*/, unsigned short /*Button*/, - unsigned short /*Mod*/) -{ - if (State != IE_GUI_SLIDER_KNOB) { - Changed = true; - } - State = IE_GUI_SLIDER_KNOB; -} - -/** Mouse Over Event */ -void Slider::OnMouseOver(unsigned short x, unsigned short /*y*/) -{ - Changed = true; - unsigned int oldPos = Pos; - if (State == IE_GUI_SLIDER_GRABBEDKNOB) { - int mx = KnobXPos; - int xmx = x - mx; - if (x < mx) { - SetPosition( 0 ); - if (oldPos != Pos) { - RunEventHandler( SliderOnChange ); - } - return; - } - int befst = xmx / KnobStep; - if (befst >= KnobStepsCount) { - SetPosition( KnobStepsCount - 1 ); - if (oldPos != Pos) { - RunEventHandler( SliderOnChange ); - } - return; - } - short aftst = befst + KnobStep; - if (( xmx - ( befst * KnobStep ) ) < ( ( aftst * KnobStep ) - xmx )) { - SetPosition( befst ); - } else { - SetPosition( aftst ); - } - if (oldPos != Pos) { - RunEventHandler( SliderOnChange ); - } - } -} - -/** Sets the slider change event */ -bool Slider::SetEvent(int eventType, EventHandler handler) -{ - Changed = true; - - switch (eventType) { - case IE_GUI_SLIDER_ON_CHANGE: - SliderOnChange = handler; - break; - default: - return false; - } - - return true; -} diff --git a/project/jni/application/gemrb/gemrb/core/GUI/Slider.h b/project/jni/application/gemrb/gemrb/core/GUI/Slider.h deleted file mode 100644 index 30636082a..000000000 --- a/project/jni/application/gemrb/gemrb/core/GUI/Slider.h +++ /dev/null @@ -1,104 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -/** - * @file Slider.h - * Declares Slider widget for displaying scales and sliders for setting - * numerical values - * @author The GemRB Project - */ - -#ifndef SLIDER_H -#define SLIDER_H - -#include "GUI/Control.h" - -#include "exports.h" - -#include "Sprite2D.h" - -// !!! Keep these synchronized with GUIDefines.py !!! -#define IE_GUI_SLIDER_ON_CHANGE 0x02000000 - - -#define IE_GUI_SLIDER_KNOB 0 -#define IE_GUI_SLIDER_GRABBEDKNOB 1 -#define IE_GUI_SLIDER_BACKGROUND 2 - -/** - * @class Slider - * Widget displaying sliders or scales for inputting numerical values - * with a limited range - */ - -class GEM_EXPORT Slider : public Control { -public: - Slider(short KnobXPos, short KnobYPos, short KnobStep, unsigned short KnobStepsCount, bool Clear = false); - ~Slider(); - /** Draws the Control on the Output Display */ - void Draw(unsigned short x, unsigned short y); - /** Returns the actual Slider Position */ - unsigned int GetPosition(); - /** Sets the actual Slider Position trimming to the Max and Min Values */ - void SetPosition(unsigned int pos); - /** Sets the selected image */ - void SetImage(unsigned char type, Sprite2D * img); - /** Sets the State of the Slider */ - void SetState(int arg) { State=(unsigned char) arg; } - /** Redraws a slider which is associated with VariableName */ - void RedrawSlider(const char *VariableName, int Sum); - -private: // Private attributes - /** BackGround Image. If smaller than the Control Size, the image will be tiled. */ - Sprite2D * BackGround; - /** Knob Image */ - Sprite2D * Knob; - /** Grabbed Knob Image */ - Sprite2D * GrabbedKnob; - /** Knob Starting X Position */ - short KnobXPos; - /** Knob Starting Y Position */ - short KnobYPos; - /** Knob Step Size */ - short KnobStep; - /** Knob Steps Count */ - unsigned short KnobStepsCount; - /** If true, on deletion the Slider will destroy the associated images */ - bool Clear; - /** Actual Knob Status */ - unsigned char State; - /** Slider Position Value */ - unsigned int Pos; -public: // Public Events - /** Mouse Button Down */ - void OnMouseDown(unsigned short x, unsigned short y, unsigned short Button, - unsigned short Mod); - /** Mouse Button Up */ - void OnMouseUp(unsigned short x, unsigned short y, unsigned short Button, - unsigned short Mod); - /** Mouse Over Event */ - void OnMouseOver(unsigned short x, unsigned short y); - /** Set handler for specified event */ - bool SetEvent(int eventType, EventHandler handler); - /** OnChange Scripted Event Function Name */ - EventHandler SliderOnChange; -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/GUI/TextArea.cpp b/project/jni/application/gemrb/gemrb/core/GUI/TextArea.cpp deleted file mode 100644 index 9f97eef79..000000000 --- a/project/jni/application/gemrb/gemrb/core/GUI/TextArea.cpp +++ /dev/null @@ -1,983 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "GUI/TextArea.h" - -#include "GUI/GameControl.h" - -#include "win32def.h" - -#include "Audio.h" -#include "DialogHandler.h" -#include "GameData.h" -#include "ImageMgr.h" -#include "Interface.h" -#include "Palette.h" -#include "Variables.h" -#include "Video.h" -#include "GUI/EventMgr.h" -#include "GUI/Window.h" -#include "Scriptable/Actor.h" - -#include -#include - -TextArea::TextArea(Color hitextcolor, Color initcolor, Color lowtextcolor) -{ - keeplines = 100; - rows = 0; - startrow = 0; - minrow = 0; - Cursor = NULL; - CurPos = 0; - CurLine = 0; - seltext = -1; - Value = 0xffffffff; - ResetEventHandler( TextAreaOnChange ); - ResetEventHandler( TextAreaOutOfText ); - PortraitResRef[0]=0; - palette = core->CreatePalette( hitextcolor, lowtextcolor ); - initpalette = core->CreatePalette( initcolor, lowtextcolor ); - Color tmp = { - hitextcolor.b, hitextcolor.g, hitextcolor.r, 0 - }; - selected = core->CreatePalette( tmp, lowtextcolor ); - tmp.r = 255; - tmp.g = 152; - tmp.b = 102; - lineselpal = core->CreatePalette( tmp, lowtextcolor ); - InternalFlags = 1; - //Drop Capitals means initials on! - core->GetDictionary()->Lookup("Drop Capitals", InternalFlags); - if (InternalFlags) { - InternalFlags = TA_INITIALS; - } -} - -TextArea::~TextArea(void) -{ - gamedata->FreePalette( palette ); - gamedata->FreePalette( initpalette ); - gamedata->FreePalette( selected ); - gamedata->FreePalette( lineselpal ); - core->GetVideoDriver()->FreeSprite( Cursor ); - for (size_t i = 0; i < lines.size(); i++) { - free( lines[i] ); - } -} - -void TextArea::RefreshSprite(const char *portrait) -{ - if (AnimPicture) { - if (!strnicmp(PortraitResRef, portrait, 8) ) { - return; - } - SetAnimPicture(NULL); - } - strnlwrcpy(PortraitResRef, portrait, 8); - if (!strnicmp(PortraitResRef, "none", 8) ) { - return; - } - ResourceHolder im(PortraitResRef); - if (im == NULL) { - return; - } - - SetAnimPicture ( im->GetSprite2D() ); -} - -void TextArea::Draw(unsigned short x, unsigned short y) -{ - /** Don't come back recursively */ - if (InternalFlags&TA_BITEMYTAIL) { - return; - } - int tx=x+XPos; - int ty=y+YPos; - Region clip( tx, ty, Width, Height ); - Video *video = core->GetVideoDriver(); - - if (Flags&IE_GUI_TEXTAREA_SPEAKER) { - if (AnimPicture) { - video->BlitSprite(AnimPicture, tx,ty, true, &clip); - clip.x+=AnimPicture->Width; - clip.w-=AnimPicture->Width; - } - } - - //this might look better in GlobalTimer - //or you might want to change the animated button to work like this - if (Flags &IE_GUI_TEXTAREA_SMOOTHSCROLL) - { - unsigned long thisTime; - - thisTime = GetTickCount(); - if (thisTime>starttime) { - starttime = thisTime+ticks; - smooth--; - while (smooth<=0) { - smooth+=ftext->maxHeight; - if (startrowInvalidate(); - InternalFlags |= TA_BITEMYTAIL; - Owner->DrawWindow(); - InternalFlags &= ~TA_BITEMYTAIL; - } - } - - if (!Changed && !(Owner->Flags&WF_FLOAT) ) { - return; - } - Changed = false; - - if (XPos == 65535) { - return; - } - size_t linesize = lines.size(); - if (linesize == 0) { - return; - } - - //smooth vertical scrolling up - if (Flags & IE_GUI_TEXTAREA_SMOOTHSCROLL) { - clip.y+=smooth; - clip.h-=smooth; - } - - //if textarea is 'selectable' it actually means, it is a listbox - //in this case the selected value equals the line number - //if it is 'not selectable' it can still have selectable lines - //but then it is like the dialog window in the main game screen: - //the selected value is encoded into the line - if (!(Flags & IE_GUI_TEXTAREA_SELECTABLE) ) { - char* Buffer = (char *) malloc( 1 ); - Buffer[0] = 0; - int len = 0; - int lastlen = 0; - for (size_t i = 0; i < linesize; i++) { - if (strnicmp( "[s=", lines[i], 3 ) == 0) { - int tlen; - unsigned long idx, acolor, bcolor; - char* rest; - idx = strtoul( lines[i] + 3, &rest, 0 ); - if (*rest != ',') - goto notmatched; - acolor = strtoul( rest + 1, &rest, 16 ); - if (*rest != ',') - goto notmatched; - bcolor = strtoul( rest + 1, &rest, 16 ); - if (*rest != ']') - goto notmatched; - tlen = (int)(strstr( rest + 1, "[/s]" ) - rest - 1); - if (tlen < 0) - goto notmatched; - len += tlen + 23; - Buffer = (char *) realloc( Buffer, len + 2 ); - if (seltext == (int) i) { - sprintf( Buffer + lastlen, "[color=%6.6lX]%.*s[/color]", - acolor, tlen, rest + 1 ); - } else { - sprintf( Buffer + lastlen, "[color=%6.6lX]%.*s[/color]", - bcolor, tlen, rest + 1 ); - } - } else { - notmatched: - len += ( int ) strlen( lines[i] ) + 1; - Buffer = (char *) realloc( Buffer, len + 2 ); - memcpy( &Buffer[lastlen], lines[i], len - lastlen ); - } - lastlen = len; - if (i != linesize - 1) { - Buffer[lastlen - 1] = '\n'; - Buffer[lastlen] = 0; - } - } - video->SetClipRect( &clip ); - - int pos; - - if (startrow==CurLine) { - pos = CurPos; - } else { - pos = -1; - } - ftext->PrintFromLine( startrow, clip, - ( unsigned char * ) Buffer, palette, - IE_FONT_ALIGN_LEFT, finit, Cursor, pos ); - free( Buffer ); - video->SetClipRect( NULL ); - //streaming text - if (linesize>50) { - //the buffer is filled enough - return; - } - if (core->GetAudioDrv()->IsSpeaking() ) { - //the narrator is still talking - return; - } - if (RunEventHandler( TextAreaOutOfText )) { - return; - } - if (linesize==lines.size()) { - ResetEventHandler( TextAreaOutOfText ); - return; - } - AppendText("\n",-1); - return; - } - // normal scrolling textarea - int rc = 0; - int sr = startrow; - unsigned int i; - int yl; - for (i = 0; i < linesize; i++) { - if (rc + lrows[i] <= sr) { - rc += lrows[i]; - continue; - } - sr -= rc; - Palette* pal = NULL; - if (seltext == (int) i) - pal = selected; - else if (Value == i) - pal = lineselpal; - else - pal = palette; - ftext->PrintFromLine( sr, clip, - ( unsigned char * ) lines[i], pal, - IE_FONT_ALIGN_LEFT, finit, NULL ); - yl = ftext->size[1].h*(lrows[i]-sr); - clip.y+=yl; - clip.h-=yl; - break; - } - for (i++; i < linesize; i++) { - Palette* pal = NULL; - if (seltext == (int) i) - pal = selected; - else if (Value == i) - pal = lineselpal; - else - pal = palette; - ftext->Print( clip, ( unsigned char * ) lines[i], pal, - IE_FONT_ALIGN_LEFT, true ); - yl = ftext->size[1].h*lrows[i]; - clip.y+=yl; - clip.h-=yl; - - } -} -/** Sets the Scroll Bar Pointer. If 'ptr' is NULL no Scroll Bar will be linked - to this Text Area Control. */ -int TextArea::SetScrollBar(Control* ptr) -{ - int ret = Control::SetScrollBar(ptr); - CalcRowCount(); - return ret; -} - -/** Sets the Actual Text */ -void TextArea::SetText(const char* text) -{ - if (!text[0]) { - Clear(); - } - - int newlen = ( int ) strlen( text ); - - if (lines.size() == 0) { - char* str = (char *) malloc( newlen + 1 ); - memcpy( str, text, newlen + 1 ); - lines.push_back( str ); - lrows.push_back( 0 ); - } else { - lines[0] = (char *) realloc( lines[0], newlen + 1 ); - memcpy( lines[0], text, newlen + 1 ); - } - CurPos = newlen; - CurLine = lines.size()-1; - UpdateControls(); -} - -void TextArea::SetMinRow(bool enable) -{ - if (enable) { - minrow = (int) lines.size(); - } else { - minrow = 0; - } - Changed = true; -} - -//drop lines scrolled out at the top. -//keeplines is the number of lines that should still be -//preserved (for scrollback history) -void TextArea::DiscardLines() -{ - if (rows<=keeplines) { - return; - } - int drop = rows-keeplines; - PopLines(drop, true); -} - -static char *note_const = NULL; -static const char inserted_crap[]="[/color][color=ffffff]"; -#define CRAPLENGTH sizeof(inserted_crap)-1 - -void TextArea::SetNoteString(const char *s) -{ - free(note_const); - if (s) { - note_const = (char *) malloc(strlen(s)+5); - sprintf(note_const, "\r\n\r\n%s", s); - } -} - -/** Appends a String to the current Text */ -int TextArea::AppendText(const char* text, int pos) -{ - int ret = 0; - if (pos >= ( int ) lines.size()) { - return -1; - } - int newlen = ( int ) strlen( text ); - - if (pos == -1) { - const char *note = NULL; - if (note_const) { - note = strstr(text,note_const); - } - char *str; - if (NULL == note) { - str = (char *) malloc( newlen +1 ); - memcpy(str, text, newlen+1); - } - else { - unsigned int notepos = (unsigned int) (note - text); - str = (char *) malloc( newlen + CRAPLENGTH+1 ); - memcpy(str,text,notepos); - memcpy(str+notepos,inserted_crap,CRAPLENGTH); - memcpy(str+notepos+CRAPLENGTH, text+notepos, newlen-notepos+1); - } - lines.push_back( str ); - lrows.push_back( 0 ); - ret =(int) (lines.size() - 1); - } else { - int mylen = ( int ) strlen( lines[pos] ); - - lines[pos] = (char *) realloc( lines[pos], mylen + newlen + 1 ); - memcpy( lines[pos]+mylen, text, newlen + 1 ); - ret = pos; - } - - //if the textarea is not a listbox, then discard scrolled out - //lines - if (Flags&IE_GUI_TEXTAREA_HISTORY) { - DiscardLines(); - } - - UpdateControls(); - return ret; -} - -/** Deletes last or first `count' lines */ -/** Probably not too optimal for many lines, but it isn't used */ -/** for many lines */ -void TextArea::PopLines(unsigned int count, bool top) -{ - if (count > lines.size()) { - count = (unsigned int) lines.size(); - } - - while (count > 0 ) { - if (top) { - int tmp = lrows.front(); - if (minrow || (startrowmaxHeight ); - else - pos = 0; - if (pos < 0) - pos = 0; - bar->SetPos( pos ); - } else { - if (Flags & IE_GUI_TEXTAREA_AUTOSCROLL) { - pos = rows - ( ( Height - 5 ) / ftext->maxHeight ); - SetRow(pos); - } - } - core->RedrawAll(); -} - -/** Sets the Fonts */ -void TextArea::SetFonts(Font* init, Font* text) -{ - finit = init; - ftext = text; - Changed = true; -} - -/** Key Press Event */ -void TextArea::OnKeyPress(unsigned char Key, unsigned short /*Mod*/) -{ - if (Flags & IE_GUI_TEXTAREA_EDITABLE) { - if (Key >= 0x20) { - Owner->Invalidate(); - Changed = true; - int len = GetRowLength(CurLine); - //print("len: %d Before: %s\n",len, lines[CurLine]); - lines[CurLine] = (char *) realloc( lines[CurLine], len + 2 ); - for (int i = len; i > CurPos; i--) { - lines[CurLine][i] = lines[CurLine][i - 1]; - } - lines[CurLine][CurPos] = Key; - lines[CurLine][len + 1] = 0; - CurPos++; - //print("pos: %d After: %s\n",CurPos, lines[CurLine]); - CalcRowCount(); - RunEventHandler( TextAreaOnChange ); - } - return; - } - - //Selectable=false for dialogs, rather unintuitive, but fact - if ((Flags & IE_GUI_TEXTAREA_SELECTABLE) || ( Key < '1' ) || ( Key > '9' )) - return; - GameControl *gc = core->GetGameControl(); - if (gc && (gc->GetDialogueFlags()&DF_IN_DIALOG) ) { - Changed = true; - seltext=minrow-1; - if ((unsigned int) seltext>=lines.size()) { - return; - } - for(int i=0;i=lines.size()) { - return; - } - } - while (strnicmp( lines[seltext], "[s=", 3 ) != 0 ); - } - int idx=-1; - sscanf( lines[seltext], "[s=%d,", &idx); - if (idx==-1) { - //this kills this object, don't use any more data! - gc->dialoghandler->EndDialog(); - return; - } - gc->dialoghandler->DialogChoose( idx ); - } -} - -/** Special Key Press */ -void TextArea::OnSpecialKeyPress(unsigned char Key) -{ - int len; - int i; - - if (!(Flags&IE_GUI_TEXTAREA_EDITABLE)) { - return; - } - Owner->Invalidate(); - Changed = true; - switch (Key) { - case GEM_HOME: - CurPos = 0; - CurLine = 0; - break; - case GEM_UP: - if (CurLine) { - CurLine--; - } - break; - case GEM_DOWN: - if (CurLine 0) { - CurPos--; - } else { - if (CurLine) { - CurLine--; - CurPos = GetRowLength(CurLine); - } - } - break; - case GEM_RIGHT: - len = GetRowLength(CurLine); - if (CurPos < len) { - CurPos++; - } else { - if(CurLine=len) { - //TODO: merge next line - break; - } - lines[CurLine] = (char *) realloc( lines[CurLine], len ); - for (i = CurPos; i < len; i++) { - lines[CurLine][i] = lines[CurLine][i + 1]; - } - //print("pos: %d After: %s\n",CurPos, lines[CurLine]); - break; - case GEM_BACKSP: - len = GetRowLength(CurLine); - if (CurPos != 0) { - //print("len: %d Before: %s\n",len, lines[CurLine]); - if (len<1) { - break; - } - lines[CurLine] = (char *) realloc( lines[CurLine], len ); - for (i = CurPos; i < len; i++) { - lines[CurLine][i - 1] = lines[CurLine][i]; - } - lines[CurLine][len - 1] = 0; - CurPos--; - //print("pos: %d After: %s\n",CurPos, lines[CurLine]); - } else { - if (CurLine) { - //TODO: merge lines - int oldline = CurLine; - CurLine--; - int old = GetRowLength(CurLine); - //print("len: %d Before: %s\n",old, lines[CurLine]); - //print("len: %d Before: %s\n",len, lines[oldline]); - lines[CurLine] = (char *) realloc (lines[CurLine], len+old); - memcpy(lines[CurLine]+old, lines[oldline],len); - free(lines[oldline]); - lines[CurLine][old+len]=0; - lines.erase(lines.begin()+oldline); - lrows.erase(lrows.begin()+oldline); - CurPos = old; - //print("pos: %d len: %d After: %s\n",CurPos, GetRowLength(CurLine), lines[CurLine]); - } - } - break; - case GEM_RETURN: - //add an empty line after CurLine - //print("pos: %d Before: %s\n",CurPos, lines[CurLine]); - lrows.insert(lrows.begin()+CurLine, 0); - len = GetRowLength(CurLine); - //copy the text after the cursor into the new line - char *str = (char *) malloc(len-CurPos+2); - memcpy(str, lines[CurLine]+CurPos, len-CurPos+1); - str[len-CurPos+1] = 0; - lines.insert(lines.begin()+CurLine+1, str); - //truncate the current line - lines[CurLine] = (char *) realloc (lines[CurLine], CurPos+1); - lines[CurLine][CurPos]=0; - //move cursor to next line beginning - CurLine++; - CurPos=0; - //print("len: %d After: %s\n",GetRowLength(CurLine-1), lines[CurLine-1]); - //print("len: %d After: %s\n",GetRowLength(CurLine), lines[CurLine]); - break; - } - CalcRowCount(); - RunEventHandler( TextAreaOnChange ); -} - -/** Returns Row count */ -int TextArea::GetRowCount() -{ - return ( int ) lines.size(); -} - -int TextArea::GetRowLength(unsigned int row) -{ - if (lines.size()<=row) { - return 0; - } - //this is just roughly the line size, escape sequences need to be removed - return strlen( lines[row] ); -} - -int TextArea::GetVisibleRowCount() -{ - return (Height-5) / ftext->maxHeight; -} - -/** Returns top index */ -int TextArea::GetTopIndex() -{ - return startrow; -} - -/** Set Starting Row */ -void TextArea::SetRow(int row) -{ - if (row < rows) { - startrow = row; - } - Changed = true; -} - -void TextArea::CalcRowCount() -{ - int tr; - int w = Width; - - if (Flags&IE_GUI_TEXTAREA_SPEAKER) { - const char *portrait = NULL; - Actor *actor = NULL; - GameControl *gc = core->GetGameControl(); - if (gc) { - Scriptable *target = gc->dialoghandler->GetTarget(); - if (target && target->Type == ST_ACTOR) { - actor = (Actor *)target; - } - } - if (actor) { - portrait = actor->GetPortrait(1); - } - if (portrait) { - RefreshSprite(portrait); - } - if (AnimPicture) { - w-=AnimPicture->Width; - } - } - - rows = 0; - if (lines.size() != 0) { - for (size_t i = 0; i < lines.size(); i++) { -// rows++; - tr = 0; - int len = ( int ) strlen( lines[i] ); - char* tmp = (char *) malloc( len + 1 ); - memcpy( tmp, lines[i], len + 1 ); - ftext->SetupString( tmp, w ); - for (int p = 0; p <= len; p++) { - if (( ( unsigned char ) tmp[p] ) == '[') { - p++; - //char tag[256]; - int k = 0; - for (k = 0; k < 256; k++) { - if (tmp[p] == ']') { - //tag[k] = 0; - break; - } - p++; - //tag[k] = tmp[p++]; - } - - continue; - } - if (tmp[p] == 0) { -// if (p != len) -// rows++; - tr++; - } - } - lrows[i] = tr; - rows += tr; - free( tmp ); - } - } - - if (lines.size()) - { - if (CurLine>=lines.size()) { - CurLine=lines.size()-1; - } - w = strlen(lines[CurLine]); - if (CurPos>w) { - CurPos = w; - } - } else { - CurLine=0; - CurPos=0; - } - - if (!sb) { - return; - } - ScrollBar* bar = ( ScrollBar* ) sb; - tr = rows - Height/ftext->size[1].h + 1; - if (tr<0) { - tr = 0; - } - bar->SetMax( (ieWord) tr ); -} -/** Mouse Over Event */ -void TextArea::OnMouseOver(unsigned short /*x*/, unsigned short y) -{ - int height = ftext->maxHeight; //size[1].h; - int r = y / height; - int row = 0; - - for (size_t i = 0; i < lines.size(); i++) { - row += lrows[i]; - if (r < ( row - startrow )) { - if (seltext != (int) i) - core->RedrawAll(); - seltext = ( int ) i; - //print("CtrlId = 0x%08lx, seltext = %d, rows = %d, row = %d, r = %d\n", ControlID, i, rows, row, r); - return; - } - } - if (seltext != -1) { - core->RedrawAll(); - } - seltext = -1; - //print("CtrlId = 0x%08lx, seltext = %d, rows %d, row %d, r = %d\n", ControlID, seltext, rows, row, r); -} - -/** Mouse Button Up */ -void TextArea::OnMouseUp(unsigned short x, unsigned short y, unsigned short /*Button*/, - unsigned short /*Mod*/) -{ - if (( x <= Width ) && ( y <= ( Height - 5 ) ) && ( seltext != -1 )) { - Value = (unsigned int) seltext; - Changed = true; - if (strnicmp( lines[seltext], "[s=", 3 ) == 0) { - if (minrow > seltext) - return; - int idx; - sscanf( lines[seltext], "[s=%d,", &idx ); - GameControl* gc = core->GetGameControl(); - if (gc && (gc->GetDialogueFlags()&DF_IN_DIALOG) ) { - if (idx==-1) { - //this kills this object, don't use any more data! - gc->dialoghandler->EndDialog(); - return; - } - gc->dialoghandler->DialogChoose( idx ); - return; - } - } - } - - if (VarName[0] != 0) { - core->GetDictionary()->SetAt( VarName, Value ); - } - RunEventHandler( TextAreaOnChange ); -} - -void TextArea::SetText(const std::vector& text) -{ - Clear(); - for (size_t i = 0; i < text.size(); i++) { - int newlen = strlen(text[i]); - char* str = (char *) malloc(newlen + 1); - memcpy(str, text[i], newlen + 1); - lines.push_back(str); - lrows.push_back(0); - CurPos = newlen; - } - CurLine = lines.size() - 1; - UpdateControls(); -} - -/** Copies the current TextArea content to another TextArea control */ -void TextArea::CopyTo(TextArea *ta) -{ - ta->SetText(lines); -} - -void TextArea::RedrawTextArea(const char* VariableName, unsigned int Sum) -{ - if (strnicmp( VarName, VariableName, MAX_VARIABLE_LENGTH )) { - return; - } - Value = Sum; - Changed = true; -} - -void TextArea::SelectText(const char *select) -{ - int i = lines.size(); - while(i--) { - if (!stricmp(lines[i], select) ) { - CurLine = i; - if (sb) { - ScrollBar* bar = ( ScrollBar* ) sb; - bar->SetPos( i ); - } else { - SetRow( i ); - } - RedrawTextArea( VarName, i); - CalcRowCount(); - Owner->Invalidate(); - core->RedrawAll(); - break; - } - } -} - -const char* TextArea::QueryText() -{ - if ( Valuegap - //minrow -2 ->npc text - while (i>=minrow-2 && i>=0) { - row+=lrows[i]; - i--; - } - row = GetVisibleRowCount()-row; - while (row>0) { - AppendText("",-1); - row--; - } -} - -void TextArea::SetPreservedRow(int arg) -{ - keeplines=arg; - Flags |= IE_GUI_TEXTAREA_HISTORY; -} - -void TextArea::Clear() -{ - for (size_t i = 0; i < lines.size(); i++) { - free( lines[i] ); - } - lines.clear(); - lrows.clear(); - rows = 0; -} - -//setting up the textarea for smooth scrolling, the first -//TEXTAREA_OUTOFTEXT callback is called automatically -void TextArea::SetupScroll(unsigned long tck) -{ - SetPreservedRow(0); - smooth = ftext->maxHeight; - startrow = 0; - ticks = tck; - //clearing the textarea - Clear(); - unsigned int i = (unsigned int) (Height/smooth); - while (i--) { - char *str = (char *) malloc(1); - str[0]=0; - lines.push_back(str); - lrows.push_back(0); - } - i = (unsigned int) lines.size(); - Flags |= IE_GUI_TEXTAREA_SMOOTHSCROLL; - starttime = GetTickCount(); - if (RunEventHandler( TextAreaOutOfText )) { - //event handler destructed this object? - return; - } - if (i==lines.size()) { - ResetEventHandler( TextAreaOutOfText ); - return; - } - //recalculates rows - AppendText("\n",-1); -} - -void TextArea::OnMouseDown(unsigned short /*x*/, unsigned short /*y*/, unsigned short Button, - unsigned short /*Mod*/) -{ - - ScrollBar* scrlbr = (ScrollBar*) sb; - - if (!scrlbr) { - Control *ctrl = Owner->GetScrollControl(); - if (ctrl && (ctrl->ControlType == IE_GUI_SCROLLBAR)) { - scrlbr = (ScrollBar *) ctrl; - } - } - if (scrlbr) { - switch(Button) { - case GEM_MB_SCRLUP: - scrlbr->ScrollUp(); - core->RedrawAll(); - break; - case GEM_MB_SCRLDOWN: - scrlbr->ScrollDown(); - core->RedrawAll(); - break; - } - } -} diff --git a/project/jni/application/gemrb/gemrb/core/GUI/TextArea.h b/project/jni/application/gemrb/gemrb/core/GUI/TextArea.h deleted file mode 100644 index fe42f3d2c..000000000 --- a/project/jni/application/gemrb/gemrb/core/GUI/TextArea.h +++ /dev/null @@ -1,179 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -/** - * @file TextArea.h - * Declares TextArea widget for displaying long paragraphs of text - * @author The GemRB Project - */ - -#ifndef TEXTAREA_H -#define TEXTAREA_H - -#include "GUI/Control.h" -#include "GUI/ScrollBar.h" - -#include "RGBAColor.h" -#include "exports.h" - -#include "Font.h" - -// Keep these synchronized with GUIDefines.py -// 0x05 is the control type of TextArea -#define IE_GUI_TEXTAREA_ON_CHANGE 0x05000000 -#define IE_GUI_TEXTAREA_OUT_OF_TEXT 0x05000001 - -// TextArea flags, keep these in sync too -// the control type is intentionally left out -#define IE_GUI_TEXTAREA_SELECTABLE 1 -#define IE_GUI_TEXTAREA_AUTOSCROLL 2 -#define IE_GUI_TEXTAREA_SMOOTHSCROLL 4 -#define IE_GUI_TEXTAREA_HISTORY 8 -#define IE_GUI_TEXTAREA_SPEAKER 16 -#define IE_GUI_TEXTAREA_ALT_FONT 32 //this one disables drop capitals -#define IE_GUI_TEXTAREA_EDITABLE 64 - -// internal flags -#define TA_INITIALS 1 -#define TA_BITEMYTAIL 2 - -/** - * @class TextArea - * Widget capable of displaying long paragraphs of text. - * It is usually scrolled with a ScrollBar widget - */ - -class GEM_EXPORT TextArea : public Control { -public: - TextArea(Color hitextcolor, Color initcolor, Color lowtextcolor); - ~TextArea(void); - /** global configuration */ - static void SetNoteString(const char *s); - /** Draws the Control on the Output Display */ - void Draw(unsigned short x, unsigned short y); - /** Set the TextArea value to the line number containing the string parameter */ - void SelectText(const char *select); - /** Sets the Actual Text */ - void SetText(const char* text); - /** Sets text */ - void SetText(const std::vector& text); - /** Clears the textarea */ - void Clear(); - /** Discards scrolled out lines from the textarea */ - /** preserving 'keeplines' lines for scroll back history */ - void DiscardLines(); - /** Appends a String to the current Text */ - int AppendText(const char* text, int pos = 0); - /** Deletes `count' lines (either last or top lines)*/ - void PopLines(unsigned int count, bool top = false); - /** Deletes last lines up to current 'minrow' */ - void PopMinRow() - { - PopLines((unsigned int) (lines.size()-minrow)); - } - /** adds empty lines so minrow will be the uppermost visible row */ - void PadMinRow(); - /** Sets up scrolling, tck is the scrolling speed */ - void SetupScroll(unsigned long tck); - /** Sets the Fonts */ - void SetFonts(Font* init, Font* text); - /** Returns Number of Rows */ - int GetRowCount(); - /** Returns the length of a Row */ - int GetRowLength(unsigned int row); - /** Returns Number of Visible Rows */ - int GetVisibleRowCount(); - /** Returns Starting Row */ - int GetTopIndex(); - /** Set Starting Row */ - void SetRow(int row); - /** Sets preserved lines */ - void SetPreservedRow(int arg); - /** Set Selectable */ - void SetSelectable(bool val); - /** Set Minimum Selectable Row (to the current ceiling) */ - void SetMinRow(bool enable); - /** Copies the current TextArea content to another TextArea control */ - void CopyTo(TextArea* ta); - /** Returns the selected text */ - const char* QueryText(); - /** Marks textarea for redraw with a new value */ - void RedrawTextArea(const char* VariableName, unsigned int Sum); - int SetScrollBar(Control *ptr); -private: // Private attributes - std::vector< char*> lines; - std::vector< int> lrows; - int seltext; - /** minimum selectable row */ - int minrow; - /** lines to be kept even if scrolled out */ - int keeplines; - /** vertical offset for smooth scrolling */ - int smooth; - /** timer for scrolling */ - unsigned long starttime; - /** timer ticks for scrolling (speed) */ - unsigned long ticks; - /** Number of Text Rows */ - int rows; - /** Starting Row */ - int startrow; - /** Text Colors */ - Palette* palette; - Palette* initpalette; - Palette* selected; - Palette* lineselpal; - /** a hack for smooth windows, drop capitals */ - ieDword InternalFlags; - /** Fonts */ - Font* finit, * ftext; - ieResRef PortraitResRef; - - /** Text Editing Cursor Sprite */ - Sprite2D* Cursor; - unsigned short CurPos, CurLine; - -private: //internal functions - void CalcRowCount(); - void UpdateControls(); - void RefreshSprite(const char *portrait); - -public: //Events - /** Key Press Event */ - void OnKeyPress(unsigned char Key, unsigned short Mod); - /** Special Key Press */ - void OnSpecialKeyPress(unsigned char Key); - /** Mouse Over Event */ - void OnMouseOver(unsigned short x, unsigned short y); - /** Mouse Button Up */ - void OnMouseUp(unsigned short x, unsigned short y, unsigned short Button, - unsigned short Mod); - /** Mouse button down*/ - void OnMouseDown(unsigned short x, unsigned short y, unsigned short Button, - unsigned short Mod); - /** Set handler for specified event */ - bool SetEvent(int eventType, EventHandler handler); - /** OnChange Scripted Event Function Name */ - EventHandler TextAreaOnChange; - /** OutOfText Scripted Event Function Name */ - EventHandler TextAreaOutOfText; -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/GUI/TextEdit.cpp b/project/jni/application/gemrb/gemrb/core/GUI/TextEdit.cpp deleted file mode 100644 index 00a884dcc..000000000 --- a/project/jni/application/gemrb/gemrb/core/GUI/TextEdit.cpp +++ /dev/null @@ -1,241 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - - -#include "GUI/TextEdit.h" - -#include "GameData.h" -#include "Interface.h" -#include "Palette.h" -#include "Video.h" -#include "GUI/EventMgr.h" -#include "GUI/Window.h" - -#if TARGET_OS_IPHONE -# include "SDL_uikitkeyboard.h" -#endif - -TextEdit::TextEdit(unsigned short maxLength, unsigned short px, unsigned short py) -{ - max = maxLength; - FontPosX = px; - FontPosY = py; - Buffer = ( unsigned char * ) malloc( max + 1 ); - font = NULL; - Cursor = NULL; - Back = NULL; - CurPos = 0; - Buffer[0] = 0; - ResetEventHandler( EditOnChange ); - ResetEventHandler( EditOnDone ); - ResetEventHandler( EditOnCancel ); - Color white = {0xff, 0xff, 0xff, 0x00}, black = {0x00, 0x00, 0x00, 0x00}; - //Original engine values - //Color white = {0xc8, 0xc8, 0xc8, 0x00}, black = {0x3c, 0x3c, 0x3c, 0x00}; - palette = core->CreatePalette( white, black ); -} - -TextEdit::~TextEdit(void) -{ - Video *video = core->GetVideoDriver(); - gamedata->FreePalette( palette ); - free( Buffer ); - video->FreeSprite( Back ); - video->FreeSprite( Cursor ); -} - -/** Draws the Control on the Output Display */ -void TextEdit::Draw(unsigned short x, unsigned short y) -{ - if (!Changed && !(Owner->Flags&WF_FLOAT)) { - return; - } - Changed = false; - if (Back) { - core->GetVideoDriver()->BlitSprite( Back, x + XPos, y + YPos, true ); - - } - if (!font) - return; - - //The aligning of textedit fields is done by absolute positioning (FontPosX, FontPosY) - if (hasFocus) { -#if TARGET_OS_IPHONE - SDL_iPhoneKeyboardShow(SDL_GetWindowFromID(1)); -#endif - font->Print( Region( x + XPos + FontPosX, y + YPos + FontPosY, Width, Height ), Buffer, - palette, IE_FONT_ALIGN_LEFT | IE_FONT_ALIGN_TOP, - true, NULL, Cursor, CurPos ); - } else { - font->Print( Region( x + XPos + FontPosX, y + YPos + FontPosY, Width, Height ), Buffer, - palette, IE_FONT_ALIGN_LEFT | IE_FONT_ALIGN_TOP, true ); - } -} - -/** Set Font */ -void TextEdit::SetFont(Font* f) -{ - if (f != NULL) { - font = f; - Changed = true; - return; - } - printMessage("TextEdit","Invalid font set!\n", LIGHT_RED); -} - -Font *TextEdit::GetFont() { return font; } - -/** Set Cursor */ -void TextEdit::SetCursor(Sprite2D* cur) -{ - core->GetVideoDriver()->FreeSprite( Cursor ); - if (cur != NULL) { - Cursor = cur; - } - Changed = true; -} - -/** Set BackGround */ -void TextEdit::SetBackGround(Sprite2D* back) -{ - //if 'back' is NULL then no BackGround will be drawn - if (Back) - core->GetVideoDriver()->FreeSprite(Back); - Back = back; - Changed = true; -} - -/** Key Press Event */ -void TextEdit::OnKeyPress(unsigned char Key, unsigned short /*Mod*/) -{ - if (Key >= 0x20) { - if (Value && ( (Key<'0') || (Key>'9') ) ) - return; - Owner->Invalidate(); - Changed = true; - int len = ( int ) strlen( ( char* ) Buffer ); - if (len + 1 < max) { - for (int i = len; i > CurPos; i--) { - Buffer[i] = Buffer[i - 1]; - } - Buffer[CurPos] = Key; - Buffer[len + 1] = 0; - CurPos++; - } - RunEventHandler( EditOnChange ); - } -} -/** Special Key Press */ -void TextEdit::OnSpecialKeyPress(unsigned char Key) -{ - int len; - - Owner->Invalidate(); - Changed = true; - switch (Key) { - case GEM_HOME: - CurPos = 0; - break; - case GEM_END: - CurPos = (ieWord) strlen( (char * ) Buffer); - break; - case GEM_LEFT: - if (CurPos > 0) - CurPos--; - break; - case GEM_RIGHT: - len = ( int ) strlen( ( char * ) Buffer ); - if (CurPos < len) { - CurPos++; - } - break; - case GEM_DELETE: - len = ( int ) strlen( ( char * ) Buffer ); - if (CurPos < len) { - for (int i = CurPos; i < len; i++) { - Buffer[i] = Buffer[i + 1]; - } - } - break; - case GEM_BACKSP: - if (CurPos != 0) { - int len = ( int ) strlen( ( char* ) Buffer ); - for (int i = CurPos; i < len; i++) { - Buffer[i - 1] = Buffer[i]; - } - Buffer[len - 1] = 0; - CurPos--; - } - break; - case GEM_RETURN: - RunEventHandler( EditOnDone ); - return; - - } - RunEventHandler( EditOnChange ); -} - -/** Sets the Text of the current control */ -void TextEdit::SetText(const char* string) -{ - strncpy( ( char * ) Buffer, string, max ); - Buffer[max]=0; - CurPos = (ieWord) strlen((char *) Buffer); - if (Owner) { - Owner->Invalidate(); - } -} - -void TextEdit::SetBufferLength(ieWord buflen) -{ - if(buflen<1) return; - if(buflen!=max) { - Buffer = (unsigned char *) realloc(Buffer, buflen+1); - max=(ieWord) buflen; - Buffer[max]=0; - } -} - -/** Simply returns the pointer to the text, don't modify it! */ -const char* TextEdit::QueryText() -{ - return ( const char * ) Buffer; -} - -bool TextEdit::SetEvent(int eventType, EventHandler handler) -{ - Changed = true; - - switch (eventType) { - case IE_GUI_EDIT_ON_CHANGE: - EditOnChange = handler; - break; - case IE_GUI_EDIT_ON_DONE: - EditOnDone = handler; - break; - case IE_GUI_EDIT_ON_CANCEL: - EditOnCancel = handler; - break; - default: - return false; - } - - return true; -} diff --git a/project/jni/application/gemrb/gemrb/core/GUI/TextEdit.h b/project/jni/application/gemrb/gemrb/core/GUI/TextEdit.h deleted file mode 100644 index 697b3062c..000000000 --- a/project/jni/application/gemrb/gemrb/core/GUI/TextEdit.h +++ /dev/null @@ -1,101 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -/** - * @file TextEdit.h - * Declares TextEdit widget for displaying single line text input field - * @author The GemRB Project - */ - -#ifndef TEXTEDIT_H -#define TEXTEDIT_H - -#include "GUI/Control.h" - -#include "RGBAColor.h" -#include "exports.h" - -#include "Font.h" - -class Palette; - -// !!! Keep these synchronized with GUIDefines.py -#define IE_GUI_EDIT_ON_CHANGE 0x03000000 -#define IE_GUI_EDIT_ON_DONE 0x03000001 -#define IE_GUI_EDIT_ON_CANCEL 0x03000002 - -//this is stored in 'Value' of Control class -#define IE_GUI_EDIT_NUMBER 1 - -/** - * @class TextEdit - * Widget displaying single line text input field - */ - -class GEM_EXPORT TextEdit : public Control { -public: - TextEdit(unsigned short maxLength, unsigned short x, unsigned short y); - ~TextEdit(void); - /** Draws the Control on the Output Display */ - void Draw(unsigned short x, unsigned short y); - /** Set Font */ - void SetFont(Font* f); - Font *GetFont(); - /** Set Cursor */ - void SetCursor(Sprite2D* cur); - /** Set BackGround */ - void SetBackGround(Sprite2D* back); - /** Sets the Text of the current control */ - void SetText(const char* string); - /** Sets the Text of the current control */ - const char* QueryText(); - /** Sets the buffer length */ - void SetBufferLength(ieWord buflen); -private: - /** Text Editing Cursor Sprite */ - Sprite2D* Cursor; - /** Text Font */ - Font* font; - /** Background */ - Sprite2D* Back; - /** Max Edit Text Length */ - unsigned short max; - /** Client area position */ - unsigned short FontPosX, FontPosY; - /** Text Buffer */ - unsigned char* Buffer; - /** Cursor Position */ - unsigned short CurPos; - /** Color Palette */ - Palette* palette; -public: //Events - /** Key Press Event */ - void OnKeyPress(unsigned char Key, unsigned short Mod); - /** Special Key Press */ - void OnSpecialKeyPress(unsigned char Key); - /** Set handler for specified event */ - bool SetEvent(int eventType, EventHandler handler); - /** OnChange Scripted Event Function Name */ - EventHandler EditOnChange; - EventHandler EditOnDone; - EventHandler EditOnCancel; -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/GUI/Window.cpp b/project/jni/application/gemrb/gemrb/core/GUI/Window.cpp deleted file mode 100644 index 504bc1e19..000000000 --- a/project/jni/application/gemrb/gemrb/core/GUI/Window.cpp +++ /dev/null @@ -1,443 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "GUI/Window.h" - -#include "GUI/Button.h" -#include "GUI/Control.h" -#include "GUI/MapControl.h" -#include "GUI/Progressbar.h" -#include "GUI/ScrollBar.h" -#include "GUI/Slider.h" - -#include "win32def.h" - -#include "Interface.h" -#include "Video.h" - -Window::Window(unsigned short WindowID, unsigned short XPos, - unsigned short YPos, unsigned short Width, unsigned short Height) -{ - this->WindowID = WindowID; - this->XPos = XPos; - this->YPos = YPos; - this->Width = Width; - this->Height = Height; - this->BackGround = NULL; - lastC = NULL; - lastFocus = NULL; - lastMouseFocus = NULL; - lastOver = NULL; - Visible = WINDOW_INVISIBLE; - Flags = WF_CHANGED; - Cursor = IE_CURSOR_NORMAL; - DefaultControl[0] = -1; - DefaultControl[1] = -1; - ScrollControl = -1; -} - -Window::~Window() -{ - std::vector< Control*>::iterator m = Controls.begin(); - while (Controls.size() != 0) { - Control* ctrl = ( *m ); - delete ctrl; - Controls.erase( m ); - m = Controls.begin(); - } - core->GetVideoDriver()->FreeSprite( BackGround ); - BackGround = NULL; -} -/** Add a Control in the Window */ -void Window::AddControl(Control* ctrl) -{ - if (ctrl == NULL) { - return; - } - ctrl->Owner = this; - for (size_t i = 0; i < Controls.size(); i++) { - if (Controls[i]->ControlID == ctrl->ControlID) { - delete( Controls[i] ); - Controls[i] = ctrl; - Invalidate(); - return; - } - } - Controls.push_back( ctrl ); - Invalidate(); -} -/** Set the Window's BackGround Image. If 'img' is NULL, no background will be set. If the 'clean' parameter is true (default is false) the old background image will be deleted. */ -void Window::SetBackGround(Sprite2D* img, bool clean) -{ - if (clean && BackGround) { - core->GetVideoDriver()->FreeSprite( this->BackGround ); - } - BackGround = img; - Invalidate(); -} -/** This function Draws the Window on the Output Screen */ -void Window::DrawWindow() -{ - Video* video = core->GetVideoDriver(); - Region clip( XPos, YPos, Width, Height ); - //Frame && Changed - if ( (Flags & (WF_FRAME|WF_CHANGED) )== (WF_FRAME|WF_CHANGED) ) { - Region screen( 0, 0, core->Width, core->Height ); - video->SetClipRect( NULL ); - //removed this? - Color black = { 0, 0, 0, 255 }; - video->DrawRect( screen, black ); - if (core->WindowFrames[0]) - video->BlitSprite( core->WindowFrames[0], 0, 0, true ); - if (core->WindowFrames[1]) - video->BlitSprite( core->WindowFrames[1], core->Width - core->WindowFrames[1]->Width, 0, true ); - if (core->WindowFrames[2]) - video->BlitSprite( core->WindowFrames[2], (core->Width - core->WindowFrames[2]->Width) / 2, 0, true ); - if (core->WindowFrames[3]) - video->BlitSprite( core->WindowFrames[3], (core->Width - core->WindowFrames[3]->Width) / 2, core->Height - core->WindowFrames[3]->Height, true ); - } else if (clip_regions.size()) { - // clip drawing (we only do Background right now) for InvalidateForControl - for (unsigned int i = 0; i < clip_regions.size(); i++) { - Region to_clip = clip_regions[i]; - to_clip.x += XPos; - to_clip.y += YPos; - video->SetClipRect(&to_clip); - if (BackGround) { - video->BlitSprite( BackGround, XPos, YPos, true ); - } - } - } - clip_regions.clear(); - video->SetClipRect( &clip ); - //Float || Changed - if (BackGround && (Flags & (WF_FLOAT|WF_CHANGED) ) ) { - video->BlitSprite( BackGround, XPos, YPos, true ); - } - std::vector< Control*>::iterator m; - for (m = Controls.begin(); m != Controls.end(); ++m) { - ( *m )->Draw( XPos, YPos ); - } - if ( (Flags&WF_CHANGED) && (Visible == WINDOW_GRAYED) ) { - Color black = { 0, 0, 0, 128 }; - video->DrawRect(clip, black); - } - video->SetClipRect( NULL ); - Flags &= ~WF_CHANGED; -} - -/** Set window frame used to fill screen on higher resolutions*/ -void Window::SetFrame() -{ - if ( (Width < core->Width) || (Height < core->Height) ) { - Flags|=WF_FRAME; - } - Invalidate(); -} - -/** Returns the Control at X,Y Coordinates */ -Control* Window::GetControl(unsigned short x, unsigned short y, bool ignore) -{ - Control* ctrl = NULL; - - //Check if we are still on the last control - if (( lastC != NULL )) { - if (( XPos + lastC->XPos <= x ) - && ( YPos + lastC->YPos <= y ) - && ( XPos + lastC->XPos + lastC->Width >= x ) - && ( YPos + lastC->YPos + lastC->Height >= y ) - && ! lastC->IsPixelTransparent (x - XPos - lastC->XPos, y - YPos - lastC->YPos)) { - //Yes, we are on the last returned Control - return lastC; - } - } - std::vector< Control*>::const_iterator m; - for (m = Controls.begin(); m != Controls.end(); m++) { - if (ignore && (*m)->ControlID&IGNORE_CONTROL) { - continue; - } - if (( XPos + ( *m )->XPos <= x ) - && ( YPos + ( *m )->YPos <= y ) - && ( XPos + ( *m )->XPos + ( *m )->Width >= x ) - && ( YPos + ( *m )->YPos + ( *m )->Height >= y ) - && ! ( *m )->IsPixelTransparent (x - XPos - ( *m )->XPos, y - YPos - ( *m )->YPos)) { - ctrl = *m; - break; - } - } - lastC = ctrl; - return ctrl; -} - -Control* Window::GetOver() const -{ - return lastOver; -} - -Control* Window::GetFocus() const -{ - return lastFocus; -} - -Control* Window::GetMouseFocus() const -{ - return lastMouseFocus; -} - -/** Sets 'ctrl' as Focused */ -void Window::SetFocused(Control* ctrl) -{ - if (lastFocus != NULL) { - lastFocus->hasFocus = false; - lastFocus->Changed = true; - } - lastFocus = ctrl; - if (ctrl != NULL) { - lastFocus->hasFocus = true; - lastFocus->Changed = true; - } -} - -/** Sets 'ctrl' as Mouse Focused */ -void Window::SetMouseFocused(Control* ctrl) -{ - if (lastMouseFocus != NULL) { - lastMouseFocus->Changed = true; - } - lastMouseFocus = ctrl; - if (ctrl != NULL) { - lastMouseFocus->Changed = true; - } -} - -unsigned int Window::GetControlCount() const -{ - return Controls.size(); -} - -Control* Window::GetControl(unsigned short i) const -{ - if (i < Controls.size()) { - return Controls[i]; - } - return NULL; -} - -bool Window::IsValidControl(unsigned short ID, Control *ctrl) const -{ - size_t i = Controls.size(); - while (i--) { - if (Controls[i]==ctrl) { - return ctrl->ControlID==ID; - } - } - return false; -} - -void Window::DelControl(unsigned short i) -{ - if (i < Controls.size() ) { - Control *ctrl = Controls[i]; - if (ctrl==lastC) { - lastC=NULL; - } - if (ctrl==lastOver) { - lastOver=NULL; - } - if (ctrl==lastFocus) { - lastFocus=NULL; - } - if (ctrl==lastMouseFocus) { - lastMouseFocus=NULL; - } - delete ctrl; - Controls.erase(Controls.begin()+i); - } - Invalidate(); -} - -Control* Window::GetDefaultControl(unsigned int ctrltype) const -{ - if (!Controls.size()) { - return NULL; - } - if (ctrltype>=2) { - return NULL; - } - return GetControl( (ieWord) DefaultControl[ctrltype] ); -} - -Control* Window::GetScrollControl() const -{ - if (!Controls.size()) { - return NULL; - } - return GetControl( (ieWord) ScrollControl ); -} - -void Window::release(void) -{ - Visible = WINDOW_INVALID; - lastC = NULL; - lastFocus = NULL; - lastMouseFocus = NULL; - lastOver = NULL; -} - -/** Redraw all the Window */ -void Window::Invalidate() -{ - DefaultControl[0] = -1; - DefaultControl[1] = -1; - ScrollControl = -1; - for (unsigned int i = 0; i < Controls.size(); i++) { - if (!Controls[i]) { - continue; - } - Controls[i]->Changed = true; - switch (Controls[i]->ControlType) { - case IE_GUI_SCROLLBAR: - if ((ScrollControl == -1) || (Controls[i]->Flags & IE_GUI_SCROLLBAR_DEFAULT)) - ScrollControl = i; - break; - case IE_GUI_BUTTON: - if (( Controls[i]->Flags & IE_GUI_BUTTON_DEFAULT )) { - DefaultControl[0] = i; - } - if (( Controls[i]->Flags & IE_GUI_BUTTON_CANCEL )) { - DefaultControl[1] = i; - } - break; - //falling through - case IE_GUI_GAMECONTROL: - DefaultControl[0] = i; - DefaultControl[1] = i; - break; - default: ; - } - } - Flags |= WF_CHANGED; -} - -/** Redraw enough to update the specified Control */ -void Window::InvalidateForControl(Control *ctrl) { - // TODO: for this to be general-purpose, we should mark anything inside this - // region with Changed, and also do mass Invalidate() if we overlap with - // another window, but for now this just clips the *background*, see DrawWindow() - clip_regions.push_back( Region(ctrl->XPos, ctrl->YPos, ctrl->Width, ctrl->Height) ); -} - -void Window::RedrawControls(const char* VarName, unsigned int Sum) -{ - for (unsigned int i = 0; i < Controls.size(); i++) { - switch (Controls[i]->ControlType) { - case IE_GUI_MAP: - { - MapControl *mc = ( MapControl* ) (Controls[i]); - mc->RedrawMapControl( VarName, Sum ); - break; - } - case IE_GUI_BUTTON: - { - Button* bt = ( Button* ) ( Controls[i] ); - bt->RedrawButton( VarName, Sum ); - break; - } - case IE_GUI_TEXTAREA: - { - TextArea* pb = ( TextArea* ) ( Controls[i] ); - pb->RedrawTextArea( VarName, Sum ); - break; - } - case IE_GUI_PROGRESSBAR: - { - Progressbar* pb = ( Progressbar* ) ( Controls[i] ); - pb->RedrawProgressbar( VarName, Sum ); - break; - } - case IE_GUI_SLIDER: - { - Slider* sl = ( Slider* ) ( Controls[i] ); - sl->RedrawSlider( VarName, Sum ); - break; - } - case IE_GUI_SCROLLBAR: - { - ScrollBar* sb = ( ScrollBar* ) ( Controls[i] ); - sb->RedrawScrollBar( VarName, Sum ); - break; - } - } - } -} - -/** Searches for a ScrollBar and a TextArea to link them */ -void Window::Link(unsigned short SBID, unsigned short TAID) -{ - ScrollBar* sb = NULL; - TextArea* ta = NULL; - std::vector< Control*>::iterator m; - for (m = Controls.begin(); m != Controls.end(); m++) { - if (( *m )->Owner != this) - continue; - if (( *m )->ControlType == IE_GUI_SCROLLBAR) { - if (( *m )->ControlID == SBID) { - sb = ( ScrollBar * ) ( *m ); - if (ta != NULL) - break; - } - } else if (( *m )->ControlType == IE_GUI_TEXTAREA) { - if (( *m )->ControlID == TAID) { - ta = ( TextArea * ) ( *m ); - if (sb != NULL) - break; - } - } - } - if (sb && ta) { - sb->ta = ta; - ta->SetScrollBar( sb ); - } -} - -void Window::OnMouseEnter(unsigned short x, unsigned short y, Control *ctrl) -{ - lastOver = ctrl; - if (!lastOver) { - return; - } - lastOver->OnMouseEnter( x - XPos - lastOver->XPos, y - YPos - lastOver->YPos ); -} - -void Window::OnMouseLeave(unsigned short x, unsigned short y) -{ - if (!lastOver) { - return; - } - lastOver->OnMouseLeave( x - XPos - lastOver->XPos, y - YPos - lastOver->YPos ); - lastOver = NULL; -} - -void Window::OnMouseOver(unsigned short x, unsigned short y) -{ - if (!lastOver) { - return; - } - lastOver->OnMouseOver( x - XPos - lastOver->XPos, y - YPos - lastOver->YPos ); -} diff --git a/project/jni/application/gemrb/gemrb/core/GUI/Window.h b/project/jni/application/gemrb/gemrb/core/GUI/Window.h deleted file mode 100644 index 450bc05cf..000000000 --- a/project/jni/application/gemrb/gemrb/core/GUI/Window.h +++ /dev/null @@ -1,188 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -/** - * @file Window.h - * Declares Window, class serving as a container for Control/widget objects - * and displaying windows in GUI - * @author The GemRB Project - */ - -#ifndef WINDOW_H -#define WINDOW_H - -#include "GUI/Control.h" - -#include "exports.h" - -#include - -class Sprite2D; - -// Window Flags -#define WF_CHANGED 1 //window changed -#define WF_FRAME 2 //window has frame -#define WF_FLOAT 4 //floating window -#define WF_CHILD 8 //if invalidated, it invalidates all windows on top of it - -// Window position anchors (actually flags for WindowSetPos()) -// !!! Keep these synchronized with GUIDefines.py !!! -#define WINDOW_TOPLEFT 0x00 -#define WINDOW_CENTER 0x01 -#define WINDOW_ABSCENTER 0x02 -#define WINDOW_RELATIVE 0x04 -#define WINDOW_SCALE 0x08 -#define WINDOW_BOUNDED 0x10 - -// IE specific cursor types - -#define IE_CURSOR_INVALID -1 -#define IE_CURSOR_NORMAL 0 -#define IE_CURSOR_TAKE 2 //over pile type containers -#define IE_CURSOR_WALK 4 -#define IE_CURSOR_BLOCKED 6 -#define IE_CURSOR_USE 8 //never hardcoded -#define IE_CURSOR_WAIT 10 //hourglass -#define IE_CURSOR_ATTACK 12 -#define IE_CURSOR_SWAP 14 //dragging portraits -#define IE_CURSOR_DEFEND 16 -#define IE_CURSOR_TALK 18 -#define IE_CURSOR_CAST 20 //targeting with non weapon -#define IE_CURSOR_INFO 22 //never hardcoded -#define IE_CURSOR_LOCK 24 //locked door -#define IE_CURSOR_LOCK2 26 //locked container -#define IE_CURSOR_STAIR 28 //never hardcoded -#define IE_CURSOR_DOOR 30 //doors -#define IE_CURSOR_CHEST 32 -#define IE_CURSOR_TRAVEL 34 -#define IE_CURSOR_STEALTH 36 -#define IE_CURSOR_TRAP 38 -#define IE_CURSOR_PICK 40 //pickpocket -#define IE_CURSOR_PASS 42 //never hardcoded -#define IE_CURSOR_GRAB 44 -#define IE_CURSOR_WAY 46 //waypoint (not in PST) -#define IE_CURSOR_INFO2 46 //PST -#define IE_CURSOR_PORTAL 48 //PST -#define IE_CURSOR_STAIR2 50 //PST -#define IE_CURSOR_EXTRA 52 //PST - -#define IE_CURSOR_MASK 127 -#define IE_CURSOR_GRAY 128 -/** - * @class Window - * Class serving as a container for Control/widget objects - * and displaying windows in GUI. - */ - -class GEM_EXPORT Window { -public: - Window(unsigned short WindowID, unsigned short XPos, unsigned short YPos, - unsigned short Width, unsigned short Height); - ~Window(); - /** Set the Window's BackGround Image. - * If 'img' is NULL, no background will be set. If the 'clean' parameter is true (default is false) the old background image will be deleted. */ - void SetBackGround(Sprite2D* img, bool clean = false); - /** Add a Control in the Window */ - void AddControl(Control* ctrl); - /** This function Draws the Window on the Output Screen */ - void DrawWindow(); - /** Set window frame used to fill screen on higher resolutions*/ - void SetFrame(); - /** Returns the Control at X,Y Coordinates */ - Control* GetControl(unsigned short x, unsigned short y, bool ignore=0); - /** Returns the Control by Index */ - Control* GetControl(unsigned short i) const; - /** Returns the number of Controls */ - unsigned int GetControlCount() const; - /** Returns true if ctrl is valid and ctrl->ControlID is ID */ - bool IsValidControl(unsigned short ID, Control *ctrl) const; - /** Deletes the xth. Control */ - void DelControl(unsigned short i); - /** Returns the Default Control which may be a button/gamecontrol atm */ - Control* GetDefaultControl(unsigned int ctrltype) const; - /** Returns the Control which should get mouse scroll events */ - Control* GetScrollControl() const; - /** Sets 'ctrl' as currently under mouse */ - void SetOver(Control* ctrl); - /** Returns last control under mouse */ - Control* GetOver() const; - /** Sets 'ctrl' as Focused */ - void SetFocused(Control* ctrl); - /** Sets 'ctrl' as mouse event Focused */ - void SetMouseFocused(Control* ctrl); - /** Returns last focused control */ - Control* GetFocus() const; - /** Returns last mouse event focused control */ - Control* GetMouseFocus() const; - /** Redraw all the Window */ - void Invalidate(); - /** Redraw enough to update the specified Control */ - void InvalidateForControl(Control *ctrl); - /** Redraw controls of the same group */ - void RedrawControls(const char* VarName, unsigned int Sum); - /** Links a scrollbar to a text area */ - void Link(unsigned short SBID, unsigned short TAID); - /** Mouse entered a new control's rectangle */ - void OnMouseEnter(unsigned short x, unsigned short y, Control *ctrl); - /** Mouse left the current control */ - void OnMouseLeave(unsigned short x, unsigned short y); - /** Mouse is over the current control */ - void OnMouseOver(unsigned short x, unsigned short y); -public: //Public attributes - /** WinPack */ - char WindowPack[10]; - /** Window ID */ - unsigned short WindowID; - /** X Position */ - unsigned short XPos; - /** Y Position */ - unsigned short YPos; - /** Width */ - unsigned short Width; - /** Height */ - unsigned short Height; - /** Visible value: deleted, invisible, visible, grayed */ - signed char Visible; //-1,0,1,2 - /** Window flags: Changed, Floating, Framed, Child */ - int Flags; - int Cursor; - int DefaultControl[2]; //default enter and cancel - int ScrollControl; -private: // Private attributes - /** BackGround Image. No BackGround if this variable is NULL. */ - Sprite2D* BackGround; - /** Controls Array */ - std::vector< Control*> Controls; - /** Last Control returned by GetControl */ - Control* lastC; - /** Last Focused Control */ - Control* lastFocus; - /** Last mouse event Focused Control */ - Control* lastMouseFocus; - /** Last Control under mouse */ - Control* lastOver; - /** Regions which need to be redrawn */ - std::vector< Region> clip_regions; - -public: - void release(void); -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/GUI/WorldMapControl.cpp b/project/jni/application/gemrb/gemrb/core/GUI/WorldMapControl.cpp deleted file mode 100644 index f13b74aa7..000000000 --- a/project/jni/application/gemrb/gemrb/core/GUI/WorldMapControl.cpp +++ /dev/null @@ -1,420 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "GUI/WorldMapControl.h" - -#include "win32def.h" - -#include "Font.h" -#include "Game.h" -#include "GameData.h" -#include "Interface.h" -#include "Video.h" -#include "WorldMap.h" -#include "GUI/EventMgr.h" -#include "GUI/Window.h" - -#define MAP_TO_SCREENX(x) XWin + XPos - ScrollX + (x) -#define MAP_TO_SCREENY(y) YWin + YPos - ScrollY + (y) - -WorldMapControl::WorldMapControl(const char *font, int direction) -{ - ScrollX = 0; - ScrollY = 0; - MouseIsDown = false; - Changed = true; - Area = NULL; - Value = direction; - Game* game = core->GetGame(); - WorldMap* worldmap = core->GetWorldMap(); - strncpy(currentArea, game->CurrentArea, 8); - int entry = core->GetAreaAlias(currentArea); - if (entry >= 0) { - WMPAreaEntry *m = worldmap->GetEntry(entry); - strncpy(currentArea, m->AreaResRef, 8); - } - - //if there is no trivial area, look harder - if (!worldmap->GetArea(currentArea, (unsigned int &) entry) && - core->HasFeature(GF_FLEXIBLE_WMAP) ) { - WMPAreaEntry *m = worldmap->FindNearestEntry(currentArea, (unsigned int &) entry); - if (m) { - strncpy(currentArea, m->AreaResRef, 8); - } - } - - //this also updates visible locations - worldmap->CalculateDistances(currentArea, Value); - - // alpha bit is unfortunately ignored - if (font[0]) { - ftext = core->GetFont(font); - } else { - ftext = NULL; - } - - // 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 }; - Color black = { 0x00, 0x00, 0x00, 0x00 }; - - pal_normal = core->CreatePalette ( normal, black ); - pal_selected = core->CreatePalette ( selected, black ); - pal_notvisited = core->CreatePalette ( notvisited, black ); - - - ResetEventHandler( WorldMapControlOnPress ); - ResetEventHandler( WorldMapControlOnEnter ); -} - -WorldMapControl::~WorldMapControl(void) -{ - //Video *video = core->GetVideoDriver(); - - gamedata->FreePalette( pal_normal ); - gamedata->FreePalette( pal_selected ); - gamedata->FreePalette( pal_notvisited ); -} - -/** Draws the Control on the Output Display */ -void WorldMapControl::Draw(unsigned short XWin, unsigned short YWin) -{ - WorldMap* worldmap = core->GetWorldMap(); - if (!Width || !Height) { - return; - } - if(!Changed) - return; - Changed = false; - Video* video = core->GetVideoDriver(); - Region r( XWin+XPos, YWin+YPos, Width, Height ); - Region clipbackup; - video->GetClipRect(clipbackup); - video->SetClipRect(&r); - video->BlitSprite( worldmap->GetMapMOS(), MAP_TO_SCREENX(0), MAP_TO_SCREENY(0), true, &r ); - - unsigned int i; - unsigned int ec = worldmap->GetEntryCount(); - for(i=0;iGetEntry(i); - if (! (m->GetAreaStatus() & WMP_ENTRY_VISIBLE)) continue; - - int xOffs = MAP_TO_SCREENX(m->X); - int yOffs = MAP_TO_SCREENY(m->Y); - Sprite2D* icon = m->GetMapIcon(worldmap->bam); - if( icon ) { - video->BlitSprite( icon, xOffs, yOffs, true, &r ); - video->FreeSprite( icon ); - } - - if (AnimPicture && !strnicmp(m->AreaResRef, currentArea, 8) ) { - core->GetVideoDriver()->BlitSprite( AnimPicture, xOffs, yOffs, true, &r ); - } - } - - // Draw WMP entry labels - if (ftext==NULL) { - video->SetClipRect(&clipbackup); - return; - } - for(i=0;iGetEntry(i); - if (! (m->GetAreaStatus() & WMP_ENTRY_VISIBLE)) continue; - Sprite2D *icon=m->GetMapIcon(worldmap->bam); - int h=0,w=0,xpos=0,ypos=0; - if (icon) { - h=icon->Height; - w=icon->Width; - xpos=icon->XPos; - ypos=icon->YPos; - video->FreeSprite( icon ); - } - - Region r2 = Region( MAP_TO_SCREENX(m->X-xpos), MAP_TO_SCREENY(m->Y-ypos), w, h ); - if (!m->GetCaption()) - continue; - - int tw = ftext->CalcStringWidth( m->GetCaption() ) + 5; - int th = ftext->maxHeight; - - Palette* text_pal = pal_normal; - - if (Area == m) { - text_pal = pal_selected; - } else { - if (! (m->GetAreaStatus() & WMP_ENTRY_VISITED)) { - text_pal = pal_notvisited; - } - } - - ftext->Print( Region( r2.x + (r2.w - tw)/2, r2.y + r2.h, tw, th ), - ( const unsigned char * ) m->GetCaption(), text_pal, 0, true ); - } - video->SetClipRect(&clipbackup); -} - -/** Key Release Event */ -void WorldMapControl::OnKeyRelease(unsigned char Key, unsigned short Mod) -{ - switch (Key) { - case 'f': - if (Mod & GEM_MOD_CTRL) - core->GetVideoDriver()->ToggleFullscreenMode(); - break; - default: - break; - } -} -void WorldMapControl::AdjustScrolling(short x, short y) -{ - WorldMap* worldmap = core->GetWorldMap(); - if (x || y) { - ScrollX += x; - ScrollY += y; - } else { - //center worldmap on current area - unsigned entry; - - WMPAreaEntry *m = worldmap->GetArea(currentArea,entry); - if (m) { - ScrollX = m->X - Width/2; - ScrollY = m->Y - Height/2; - } - } - Sprite2D *MapMOS = worldmap->GetMapMOS(); - if (ScrollX > MapMOS->Width - Width) - ScrollX = MapMOS->Width - Width; - if (ScrollY > MapMOS->Height - Height) - ScrollY = MapMOS->Height - Height; - if (ScrollX < 0) - ScrollX = 0; - if (ScrollY < 0) - ScrollY = 0; - Changed = true; - Area = NULL; -} - -/** Mouse Over Event */ -void WorldMapControl::OnMouseOver(unsigned short x, unsigned short y) -{ - WorldMap* worldmap = core->GetWorldMap(); - lastCursor = IE_CURSOR_GRAB; - - if (MouseIsDown) { - AdjustScrolling(lastMouseX-x, lastMouseY-y); - } - - lastMouseX = x; - lastMouseY = y; - - if (Value!=(ieDword) -1) { - x =(ieWord) (x + ScrollX); - y =(ieWord) (y + ScrollY); - - WMPAreaEntry *oldArea = Area; - Area = NULL; - - unsigned int i; - unsigned int ec = worldmap->GetEntryCount(); - for (i=0;iGetEntry(i); - - if ( (ae->GetAreaStatus() & WMP_ENTRY_WALKABLE)!=WMP_ENTRY_WALKABLE) { - continue; //invisible or inaccessible - } - if (!strnicmp(ae->AreaResRef, currentArea, 8) ) { - continue; //current area - } - - Sprite2D *icon=ae->GetMapIcon(worldmap->bam); - int h=0,w=0; - if (icon) { - h=icon->Height; - w=icon->Width; - core->GetVideoDriver()->FreeSprite( icon ); - } - if (ftext && ae->GetCaption()) { - int tw = ftext->CalcStringWidth( ae->GetCaption() ) + 5; - int th = ftext->maxHeight; - if(hX > x) continue; - if (ae->X + w < x) continue; - if (ae->Y > y) continue; - if (ae->Y + h < y) continue; - lastCursor = IE_CURSOR_NORMAL; - Area=ae; - if(oldArea!=ae) { - RunEventHandler(WorldMapControlOnEnter); - } - break; - } - } - - Owner->Cursor = lastCursor; -} - -/** Sets the tooltip to be displayed on the screen now */ -void WorldMapControl::DisplayTooltip() -{ - if (Area) { - int x = Owner->XPos+XPos+lastMouseX; - int y = Owner->YPos+YPos+lastMouseY-50; - core->DisplayTooltip( x, y, this ); - } else { - core->DisplayTooltip( 0, 0, NULL ); - } -} - -/** Mouse Leave Event */ -void WorldMapControl::OnMouseLeave(unsigned short /*x*/, unsigned short /*y*/) -{ - Owner->Cursor = IE_CURSOR_NORMAL; - Area = NULL; -} - -/** Mouse Button Down */ -void WorldMapControl::OnMouseDown(unsigned short x, unsigned short y, - unsigned short Button, unsigned short /*Mod*/) -{ - switch(Button) { - case GEM_MB_ACTION: - MouseIsDown = true; - lastMouseX = x; - lastMouseY = y; - break; - case GEM_MB_SCRLUP: - OnSpecialKeyPress(GEM_UP); - break; - case GEM_MB_SCRLDOWN: - OnSpecialKeyPress(GEM_DOWN); - break; - } -} -/** Mouse Button Up */ -void WorldMapControl::OnMouseUp(unsigned short /*x*/, unsigned short /*y*/, - unsigned short Button, unsigned short /*Mod*/) -{ - if (Button != GEM_MB_ACTION) { - return; - } - MouseIsDown = false; - if (lastCursor==IE_CURSOR_NORMAL) { - RunEventHandler( WorldMapControlOnPress ); - } -} - -/** Special Key Press */ -void WorldMapControl::OnSpecialKeyPress(unsigned char Key) -{ - WorldMap* worldmap = core->GetWorldMap(); - switch (Key) { - case GEM_LEFT: - ScrollX -= 64; - break; - case GEM_UP: - ScrollY -= 64; - break; - case GEM_RIGHT: - ScrollX += 64; - break; - case GEM_DOWN: - ScrollY += 64; - break; - case GEM_ALT: - print( "ALT pressed\n" ); - break; - case GEM_TAB: - print( "TAB pressed\n" ); - break; - } - - Sprite2D *MapMOS = worldmap->GetMapMOS(); - if (ScrollX > MapMOS->Width - Width) - ScrollX = MapMOS->Width - Width; - if (ScrollY > MapMOS->Height - Height) - ScrollY = MapMOS->Height - Height; - if (ScrollX < 0) - ScrollX = 0; - if (ScrollY < 0) - ScrollY = 0; -} - -bool WorldMapControl::SetEvent(int eventType, EventHandler handler) -{ - Changed = true; - - switch (eventType) { - case IE_GUI_WORLDMAP_ON_PRESS: - WorldMapControlOnPress = handler; - break; - case IE_GUI_MOUSE_ENTER_WORLDMAP: - WorldMapControlOnEnter = handler; - break; - default: - return false; - } - - return true; -} - -void WorldMapControl::SetColor(int which, Color color) -{ - 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_BACKGROUND: - pal = core->CreatePalette( pal_normal->front, color ); - gamedata->FreePalette( pal_normal ); - 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 = pal; - break; - case IE_GUI_WMAP_COLOR_NOTVISITED: - pal = core->CreatePalette( color, pal_notvisited->back ); - gamedata->FreePalette( pal_notvisited ); - pal_notvisited = pal; - break; - default: - break; - } - - Changed = true; -} diff --git a/project/jni/application/gemrb/gemrb/core/GUI/WorldMapControl.h b/project/jni/application/gemrb/gemrb/core/GUI/WorldMapControl.h deleted file mode 100644 index e0c08ad7c..000000000 --- a/project/jni/application/gemrb/gemrb/core/GUI/WorldMapControl.h +++ /dev/null @@ -1,114 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -/** - * @file WorldMapControl.h - * Declares WorldMapControl, widget for displaying world map - */ - - -#ifndef WORLDMAPCONTROL_H -#define WORLDMAPCONTROL_H - -#include "GUI/Control.h" - -#include "exports.h" - -#include "Dialog.h" -#include "Interface.h" - -class Palette; -class WMPAreaEntry; -class WorldMapControl; - -// !!! Keep these synchronized with GUIDefines.py !!! -/** Which label color is set with SetColor() */ -#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 - - -/** - * @class WorldMapControl - * Widget displaying "world" map, with particular locations and possibly - * allowing travelling between areas. - */ - -#define IE_GUI_WORLDMAP_ON_PRESS 0x08000000 -#define IE_GUI_MOUSE_ENTER_WORLDMAP 0x08000002 - -class GEM_EXPORT WorldMapControl : public Control { -public: - WorldMapControl(const char *fontname, int direction); - ~WorldMapControl(void); - - /** Allows modification of the scrolling factor from outside */ - void AdjustScrolling(short x, short y); - /** Draws the Control on the Output Display */ - void Draw(unsigned short x, unsigned short y); - /** Sets the exit direction (we need this to calculate distances) */ - void SetDirection(int direction); - /** Set color for one type of area labels */ - void SetColor(int which, Color color); - int ScrollX, ScrollY; - unsigned short lastMouseX, lastMouseY; - bool MouseIsDown; - /** pointer to last pointed area */ - WMPAreaEntry *Area; - /** Set handler for specified event */ - bool SetEvent(int eventType, EventHandler handler); -private: - //font for printing area names - Font* ftext; - //mouse cursor - unsigned char lastCursor; - //current area - ieResRef currentArea; - /** Label color of a visited area */ - Palette *pal_normal; - /** Label color of a currently selected area */ - Palette *pal_selected; - /** Label color of a not yet visited area */ - Palette *pal_notvisited; - /** guiscript Event when button pressed */ - EventHandler WorldMapControlOnPress; - /** guiscript Event when mouse is over a reachable area */ - EventHandler WorldMapControlOnEnter; - - /** Mouse Over Event */ - void OnMouseOver(unsigned short x, unsigned short y); - /** Mouse Leave Event */ - void OnMouseLeave(unsigned short x, unsigned short y); - /** Mouse Button Down */ - void OnMouseDown(unsigned short x, unsigned short y, unsigned short Button, - unsigned short Mod); - /** Mouse Button Up */ - void OnMouseUp(unsigned short x, unsigned short y, unsigned short Button, - unsigned short Mod); - /** Key Release Event */ - void OnKeyRelease(unsigned char Key, unsigned short Mod); - /** Special Key Press */ - void OnSpecialKeyPress(unsigned char Key); - /** DisplayTooltip */ - void DisplayTooltip(); -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/Game.cpp b/project/jni/application/gemrb/gemrb/core/Game.cpp deleted file mode 100644 index d9903603b..000000000 --- a/project/jni/application/gemrb/gemrb/core/Game.cpp +++ /dev/null @@ -1,1761 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2004 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -// This class represents the .gam (savegame) file in the engine - -#include "Game.h" - -#include "defsounds.h" -#include "strrefs.h" -#include "win32def.h" - -#include "DisplayMessage.h" -#include "GameData.h" -#include "Interface.h" -#include "IniSpawn.h" -#include "MapMgr.h" -#include "MusicMgr.h" -#include "Particles.h" -#include "PluginMgr.h" -#include "ScriptEngine.h" -#include "TableMgr.h" -#include "GameScript/GameScript.h" -#include "GUI/GameControl.h" -#include "System/DataStream.h" - -#define MAX_MAPS_LOADED 1 - -Game::Game(void) : Scriptable( ST_GLOBAL ) -{ - protagonist = PM_YES; //set it to 2 for iwd/iwd2 and 0 for pst - partysize = 6; - Ticks = 0; - version = 0; - Expansion = 0; - LoadMos[0] = 0; - SelectedSingle = 1; //the PC we are looking at (inventory, shop) - PartyGold = 0; - SetScript( core->GlobalScript, 0 ); - MapIndex = -1; - Reputation = 0; - ControlStatus = 0; - CombatCounter = 0; //stored here until we know better - StateOverrideTime = 0; - StateOverrideFlag = 0; - BanterBlockTime = 0; - BanterBlockFlag = 0; - WeatherBits = 0; - crtable = NULL; - kaputz = NULL; - beasts = NULL; - mazedata = NULL; - timestop_owner = NULL; - timestop_end = 0; - event_timer = 0; - event_handler = NULL; - weather = new Particles(200); - weather->SetRegion(0, 0, core->Width, core->Height); - LastScriptUpdate = 0; - - //loading master areas - AutoTable table; - if (table.load("mastarea")) { - int i = table->GetRowCount(); - mastarea.reserve(i); - while(i--) { - char *tmp = (char *) malloc(9); - strnuprcpy (tmp,table->QueryField(i,0),8); - mastarea.push_back( tmp ); - } - } - - //loading rest/daylight switching movies (only bg2 has them) - memset(restmovies,'*',sizeof(restmovies)); - memset(daymovies,'*',sizeof(restmovies)); - memset(nightmovies,'*',sizeof(restmovies)); - if (table.load("restmov")) { - for(int i=0;i<8;i++) { - strnuprcpy(restmovies[i],table->QueryField(i,0),8); - strnuprcpy(daymovies[i],table->QueryField(i,1),8); - strnuprcpy(nightmovies[i],table->QueryField(i,2),8); - } - } - - interval = 1000/AI_UPDATE_TIME; - hasInfra = false; - familiarBlock = false; - //FIXME:i'm not sure in this... - NoInterrupt(); -} - -Game::~Game(void) -{ - size_t i; - - delete weather; - for (i = 0; i < Maps.size(); i++) { - delete( Maps[i] ); - } - for (i = 0; i < PCs.size(); i++) { - delete ( PCs[i] ); - } - for (i = 0; i < NPCs.size(); i++) { - delete ( NPCs[i] ); - } - for (i = 0; i < mastarea.size(); i++) { - free ( mastarea[i] ); - } - - if (crtable) { - delete[] crtable; - } - - if (mazedata) { - free (mazedata); - } - if (kaputz) { - delete kaputz; - } - if (beasts) { - free (beasts); - } - i=Journals.size(); - while(i--) { - delete Journals[i]; - } - - i=savedpositions.size(); - while(i--) { - free (savedpositions[i]); - } - - i=planepositions.size(); - while(i--) { - free (planepositions[i]); - } -} - -static bool IsAlive(Actor *pc) -{ - if (pc->GetStat(IE_STATE_ID)&STATE_DEAD) { - return false; - } - return true; -} - -int Game::FindPlayer(unsigned int partyID) -{ - for (unsigned int slot=0; slotInParty==partyID) { - return slot; - } - } - return -1; -} - -Actor* Game::FindPC(unsigned int partyID) -{ - for (unsigned int slot=0; slotInParty==partyID) return PCs[slot]; - } - return NULL; -} - -Actor* Game::FindPC(const char *scriptingname) -{ - for (unsigned int slot=0; slotGetScriptName(),scriptingname,32)==0 ) { - return PCs[slot]; - } - } - return NULL; -} - -Actor* Game::FindNPC(unsigned int partyID) -{ - for (unsigned int slot=0; slotInParty==partyID) return NPCs[slot]; - } - return NULL; -} - -Actor* Game::FindNPC(const char *scriptingname) -{ - for (unsigned int slot=0; slotGetScriptName(),scriptingname,32)==0 ) - { - return NPCs[slot]; - } - } - return NULL; -} - -Actor *Game::GetGlobalActorByGlobalID(ieDword globalID) -{ - unsigned int slot; - - for (slot=0; slotGetGlobalID()==globalID ) { - return PCs[slot]; - } - } - for (slot=0; slotGetGlobalID()==globalID ) { - return NPCs[slot]; - } - } - return NULL; -} - -Actor* Game::GetPC(unsigned int slot, bool onlyalive) -{ - if (slot >= PCs.size()) { - return NULL; - } - if (onlyalive) { - unsigned int i=0; - while(i= PCs.size()) { - return -1; - } - if (!PCs[slot]) { - return -1; - } - SelectActor(PCs[slot], false, SELECT_NORMAL); - if (autoFree) { - delete( PCs[slot] ); - } - std::vector< Actor*>::iterator m = PCs.begin() + slot; - PCs.erase( m ); - return 0; -} - -int Game::DelNPC(unsigned int slot, bool autoFree) -{ - if (slot >= NPCs.size()) { - return -1; - } - if (!NPCs[slot]) { - return -1; - } - if (autoFree) { - delete( NPCs[slot] ); - } - std::vector< Actor*>::iterator m = NPCs.begin() + slot; - NPCs.erase( m ); - return 0; -} - -//i'm sure this could be faster -void Game::ConsolidateParty() -{ - int max = (int) PCs.size(); - std::vector< Actor*>::const_iterator m; - for (int i=1;i<=max;) { - if (FindPlayer(i)==-1) { - - for ( m = PCs.begin(); m != PCs.end(); ++m) { - if ( (*m)->InParty>i) { - (*m)->InParty--; - } - } - } else i++; - } - for ( m = PCs.begin(); m != PCs.end(); ++m) { - (*m)->RefreshEffects(NULL); - //TODO: how to set up bardsongs - (*m)->SetModalSpell((*m)->ModalState, 0); - } -} - -int Game::LeaveParty (Actor* actor) -{ - core->SetEventFlag(EF_PORTRAIT); - actor->CreateStats(); //create or update stats for leaving - actor->SetBase(IE_EXPLORE, 0); - - SelectActor(actor, false, SELECT_NORMAL); - int slot = InParty( actor ); - if (slot < 0) { - return slot; - } - std::vector< Actor*>::iterator m = PCs.begin() + slot; - PCs.erase( m ); - - ieDword id = actor->GetGlobalID(); - for ( m = PCs.begin(); m != PCs.end(); ++m) { - (*m)->PCStats->LastLeft = id; - if ( (*m)->InParty>actor->InParty) { - (*m)->InParty--; - } - } - //removing from party, but actor remains in 'game' - actor->SetPersistent(0); - NPCs.push_back( actor ); - - if (core->HasFeature( GF_HAS_DPLAYER )) { - actor->SetScript( "", SCR_DEFAULT ); - } - actor->SetBase( IE_EA, EA_NEUTRAL ); - return ( int ) NPCs.size() - 1; -} - -//determines if startpos.2da has rotation rows (it cannot have tutorial line) -bool Game::DetermineStartPosType(const TableMgr *strta) -{ - if ((strta->GetRowCount()>=6) && !stricmp(strta->GetRowName(4),"START_ROT" ) ) - { - return true; - } - return false; -} - -#define PMODE_COUNT 3 - -void Game::InitActorPos(Actor *actor) -{ - //start.2da row labels - const char *mode[PMODE_COUNT] = { "NORMAL", "TUTORIAL", "EXPANSION" }; - - unsigned int ip = (unsigned int) (actor->InParty-1); - AutoTable start("start"); - AutoTable strta("startpos"); - - if (!start || !strta) { - error("Game", "Game is missing character start data.\n"); - } - // 0 - single player, 1 - tutorial, 2 - expansion - ieDword playmode = 0; - core->GetDictionary()->Lookup( "PlayMode", playmode ); - - //Sometimes playmode is set to -1 (in pregenerate) - //normally execution shouldn't ever come here, but it actually does - //preventing problems by defaulting to the regular entry points - if (playmode>PMODE_COUNT) { - playmode = 0; - } - const char *xpos = start->QueryField(mode[playmode],"XPOS"); - const char *ypos = start->QueryField(mode[playmode],"YPOS"); - const char *area = start->QueryField(mode[playmode],"AREA"); - const char *rot = start->QueryField(mode[playmode],"ROT"); - - actor->Pos.x = actor->Destination.x = (short) atoi( strta->QueryField( strta->GetRowIndex(xpos), ip ) ); - actor->Pos.y = actor->Destination.y = (short) atoi( strta->QueryField( strta->GetRowIndex(ypos), ip ) ); - actor->SetOrientation( atoi( strta->QueryField( strta->GetRowIndex(rot), ip) ), false ); - - if (strta.load("startare")) { - strnlwrcpy(actor->Area, strta->QueryField( strta->GetRowIndex(area), 0 ), 8 ); - } else { - strnlwrcpy(actor->Area, CurrentArea, 8 ); - } -} - -int Game::JoinParty(Actor* actor, int join) -{ - core->SetEventFlag(EF_PORTRAIT); - actor->CreateStats(); //create stats if they didn't exist yet - actor->InitButtons(actor->GetStat(IE_CLASS), false); //init actor's buttons - actor->SetBase(IE_EXPLORE, 1); - if (join&JP_INITPOS) { - InitActorPos(actor); - } - int slot = InParty( actor ); - if (slot != -1) { - return slot; - } - size_t size = PCs.size(); - //set the lastjoined trigger - - if (join&JP_JOIN) { - //update kit abilities of actor - actor->ApplyKit(false); - //update the quickslots - actor->ReinitQuickSlots(); - //set the joining date - actor->PCStats->JoinDate = GameTime; - if (size) { - ieDword id = actor->GetGlobalID(); - for (size_t i=0;iPCStats->LastJoined = id; - } - } else { - Reputation = actor->GetStat(IE_REPUTATION); - } - } - slot = InStore( actor ); - if (slot >= 0) { - std::vector< Actor*>::iterator m = NPCs.begin() + slot; - NPCs.erase( m ); - } - - - PCs.push_back( actor ); - if (!actor->InParty) { - actor->InParty = (ieByte) (size+1); - } - - if (join&(JP_INITPOS|JP_SELECT)) { - actor->Selected = 0; // don't confuse SelectActor! - SelectActor(actor,true, SELECT_NORMAL); - } - - return ( int ) size; -} - -int Game::GetPartySize(bool onlyalive) const -{ - if (onlyalive) { - int count = 0; - for (unsigned int i = 0; i < PCs.size(); i++) { - if (!IsAlive(PCs[i])) { - continue; - } - count++; - } - return count; - } - return (int) PCs.size(); -} - -/* sends the hotkey trigger to all selected actors */ -void Game::SetHotKey(unsigned long Key) -{ - std::vector< Actor*>::const_iterator m; - - for ( m = selected.begin(); m != selected.end(); ++m) { - Actor *actor = *m; - - if (actor->IsSelected()) { - actor->AddTrigger(TriggerEntry(trigger_hotkey, (ieDword) Key)); - } - } -} - -bool Game::SelectPCSingle(int index) -{ - Actor* actor = FindPC( index ); - if (!actor || ! actor->ValidTarget( GA_NO_HIDDEN )) - return false; - - SelectedSingle = index; - return true; -} - -int Game::GetSelectedPCSingle() const -{ - return SelectedSingle; -} - -/* - * SelectActor() - handle (de)selecting actors. - * If selection was changed, runs "SelectionChanged" handler - * - * actor - either specific actor, or NULL for all - * select - whether actor(s) should be selected or deselected - * flags: - * SELECT_REPLACE - if true, deselect all other actors when selecting one - * SELECT_QUIET - do not run handler if selection was changed. Used for - * nested calls to SelectActor() - */ - -bool Game::SelectActor(Actor* actor, bool select, unsigned flags) -{ - std::vector< Actor*>::iterator m; - - // actor was not specified, which means all selectables should be (de)selected - if (! actor) { - for ( m = selected.begin(); m != selected.end(); ++m) { - (*m)->Select( false ); - (*m)->SetOver( false ); - } - selected.clear(); - - if (select) { - area->SelectActors(); -/* - for ( m = PCs.begin(); m != PCs.end(); ++m) { - if (! *m) { - continue; - } - SelectActor( *m, true, SELECT_QUIET ); - } -*/ - } - - if (! (flags & SELECT_QUIET)) { - core->SetEventFlag(EF_SELECTION); - } - Infravision(); - return true; - } - - // actor was specified, so we will work with him - if (select) { - if (! actor->ValidTarget( GA_SELECT | GA_NO_DEAD )) - return false; - - // deselect all actors first when exclusive - if (flags & SELECT_REPLACE) { - if (selected.size() == 1 && actor->IsSelected()) { - assert(selected[0] == actor); - // already the only selected actor - return true; - } - SelectActor( NULL, false, SELECT_QUIET ); - } else if (actor->IsSelected()) { - // already selected - return true; - } - - actor->Select( true ); - assert(actor->IsSelected()); - selected.push_back( actor ); - } else { - if (!actor->IsSelected()) { - // already not selected - return true; - - /*for ( m = selected.begin(); m != selected.end(); ++m) { - assert((*m) != actor); - } - return true;*/ - } - for ( m = selected.begin(); m != selected.end(); ++m) { - if ((*m) == actor) { - selected.erase( m ); - break; - } - } - actor->Select( false ); - assert(!actor->IsSelected()); - } - - if (! (flags & SELECT_QUIET)) { - core->SetEventFlag(EF_SELECTION); - } - Infravision(); - return true; -} - -// Gets average party level, of onlyalive is true, then counts only living PCs -int Game::GetPartyLevel(bool onlyalive) const -{ - int count = 0; - for (unsigned int i = 0; iGetStat(IE_STATE_ID)&STATE_DEAD) { - continue; - } - } - count += PCs[i]->GetXPLevel(0); - } - return count; -} - -// Returns map structure (ARE) if it is already loaded in memory -int Game::FindMap(const char *ResRef) -{ - int index = (int) Maps.size(); - while (index--) { - Map *map=Maps[index]; - if (strnicmp(ResRef, map->GetScriptName(), 8) == 0) { - return index; - } - } - return -1; -} - -Map* Game::GetMap(unsigned int index) const -{ - if (index >= Maps.size()) { - return NULL; - } - return Maps[index]; -} - -Map *Game::GetMap(const char *areaname, bool change) -{ - int index = LoadMap(areaname, change); - if (index >= 0) { - if (change) { - MapIndex = index; - area = GetMap(index); - memcpy (CurrentArea, areaname, 8); - area->SetupAmbients(); - //change the tileset if needed - 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); - } - return NULL; -} - -bool Game::MasterArea(const char *area) -{ - unsigned int i=(int) mastarea.size(); - while(i--) { - if (strnicmp(mastarea[i], area, 8) ) { - return true; - } - } - return false; -} - -void Game::SetMasterArea(const char *area) -{ - if (MasterArea(area) ) return; - char *tmp = (char *) malloc(9); - strnlwrcpy (tmp,area,8); - mastarea.push_back(tmp); -} - -int Game::AddMap(Map* map) -{ - if (MasterArea(map->GetScriptName()) ) { - Maps.insert(Maps.begin(), 1, map); - MapIndex++; - return 0; - } - unsigned int i = (unsigned int) Maps.size(); - Maps.push_back( map ); - return i; -} - -int Game::DelMap(unsigned int index, int forced) -{ -//this function should archive the area, and remove it only if the area -//contains no active actors (combat, partymembers, etc) - if (index >= Maps.size()) { - return -1; - } - Map *map = Maps[index]; - - if (MapIndex==(int) index) { //can't remove current map in any case - const char *name = map->GetScriptName(); - memcpy(AnotherArea, name, sizeof(AnotherArea) ); - return -1; - } - - - if (!map) { //this shouldn't happen, i guess - printMessage("Game","Erased NULL Map\n",YELLOW); - Maps.erase( Maps.begin()+index); - if (MapIndex>(int) index) { - MapIndex--; - } - return 1; - } - - if (forced || (Maps.size()>MAX_MAPS_LOADED) ) - { - //keep at least one master - const char *name = map->GetScriptName(); - if (MasterArea(name)) { - if(!AnotherArea[0]) { - memcpy(AnotherArea, name, sizeof(AnotherArea)); - if (!forced) { - return -1; - } - } - } - //this check must be the last, because - //after PurgeActors you cannot keep the - //area in memory - //Or the queues should be regenerated! - if (!map->CanFree()) - { - return 1; - } - //remove map from memory - core->SwapoutArea(Maps[index]); - delete( Maps[index] ); - Maps.erase( Maps.begin()+index); - //current map will be decreased - if (MapIndex>(int) index) { - MapIndex--; - } - return 1; - } - //didn't remove the map - return 0; -} - -/* Loads an area */ -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) { - return -1; - } - - int index = FindMap(ResRef); - if (index>=0) { - return index; - } - - bool hide = false; - if (loadscreen && sE) { - hide = core->HideGCWindow(); - sE->RunFunction("LoadScreen", "StartLoadScreen"); - sE->RunFunction("LoadScreen", "SetLoadScreen"); - } - DataStream* ds = gamedata->GetResource( ResRef, IE_ARE_CLASS_ID ); - if (!ds) { - goto failedload; - } - if(!mM->Open(ds)) { - goto failedload; - } - newMap = mM->GetMap(ResRef, IsDay()); - if (!newMap) { - goto failedload; - } - - core->LoadProgress(100); - - for (i = 0; i < PCs.size(); i++) { - if (stricmp( PCs[i]->Area, ResRef ) == 0) { - newMap->AddActor( PCs[i] ); - } - } - for (i = 0; i < NPCs.size(); i++) { - if (stricmp( NPCs[i]->Area, ResRef ) == 0) { - newMap->AddActor( NPCs[i] ); - } - } - if (hide) { - core->UnhideGCWindow(); - } - return AddMap( newMap ); -failedload: - if (hide) - core->UnhideGCWindow(); - core->LoadProgress(100); - return -1; -} - -int Game::AddNPC(Actor* npc) -{ - int slot = InStore( npc ); //already an npc - if (slot != -1) { - return slot; - } - slot = InParty( npc ); - if (slot != -1) { - return -1; - } //can't add as npc already in party - npc->SetPersistent(0); - NPCs.push_back( npc ); - - return (int) NPCs.size() - 1; -} - -Actor* Game::GetNPC(unsigned int Index) -{ - if (Index >= NPCs.size()) { - return NULL; - } - return NPCs[Index]; -} - -void Game::SwapPCs(unsigned int Index1, unsigned int Index2) -{ - if (Index1 >= PCs.size()) { - return; - } - - if (Index2 >= PCs.size()) { - return; - } - int tmp = PCs[Index1]->InParty; - PCs[Index1]->InParty = PCs[Index2]->InParty; - PCs[Index2]->InParty = tmp; - //signal a change of the portrait window - core->SetEventFlag(EF_PORTRAIT | EF_SELECTION); -} - -void Game::DeleteJournalEntry(ieStrRef strref) -{ - size_t i=Journals.size(); - while(i--) { - if ((Journals[i]->Text==strref) || (strref==(ieStrRef) -1) ) { - delete Journals[i]; - Journals.erase(Journals.begin()+i); - } - } -} - -void Game::DeleteJournalGroup(int Group) -{ - size_t i=Journals.size(); - while(i--) { - if (Journals[i]->Group==(ieByte) Group) { - delete Journals[i]; - Journals.erase(Journals.begin()+i); - } - } -} -/* returns true if it modified or added a journal entry */ -bool Game::AddJournalEntry(ieStrRef strref, int Section, int Group) -{ - GAMJournalEntry *je = FindJournalEntry(strref); - if (je) { - //don't set this entry again in the same section - if (je->Section==Section) { - return false; - } - if ((Section == IE_GAM_QUEST_DONE) && Group) { - //removing all of this group and adding a new entry - DeleteJournalGroup(Group); - } else { - //modifying existing entry - je->Section = (ieByte) Section; - je->Group = (ieByte) Group; - ieDword chapter = 0; - locals->Lookup("CHAPTER", chapter); - je->Chapter = (ieByte) chapter; - je->GameTime = GameTime; - return true; - } - } - je = new GAMJournalEntry; - je->GameTime = GameTime; - ieDword chapter = 0; - locals->Lookup("CHAPTER", chapter); - je->Chapter = (ieByte) chapter; - je->unknown09 = 0; - je->Section = (ieByte) Section; - je->Group = (ieByte) Group; - je->Text = strref; - - Journals.push_back( je ); - return true; -} - -void Game::AddJournalEntry(GAMJournalEntry* entry) -{ - Journals.push_back( entry ); -} - -unsigned int Game::GetJournalCount() const -{ - return (unsigned int) Journals.size(); -} - -GAMJournalEntry* Game::FindJournalEntry(ieStrRef strref) -{ - unsigned int Index = (unsigned int) Journals.size(); - while(Index--) { - GAMJournalEntry *ret = Journals[Index]; - - if (ret->Text==strref) { - return ret; - } - } - - return NULL; -} - -GAMJournalEntry* Game::GetJournalEntry(unsigned int Index) -{ - if (Index >= Journals.size()) { - return NULL; - } - return Journals[Index]; -} - -unsigned int Game::GetSavedLocationCount() const -{ - return (unsigned int) savedpositions.size(); -} - -void Game::ClearSavedLocations() -{ - size_t i=savedpositions.size(); - while(i--) { - delete savedpositions[i]; - } - savedpositions.clear(); -} - -GAMLocationEntry* Game::GetSavedLocationEntry(unsigned int i) -{ - size_t current = savedpositions.size(); - if (i>=current) { - if (i>PCs.size()) { - return NULL; - } - savedpositions.resize(i+1); - while(current<=i) { - savedpositions[current++]=(GAMLocationEntry *) calloc(1, sizeof(GAMLocationEntry) ); - } - } - return savedpositions[i]; -} - -unsigned int Game::GetPlaneLocationCount() const -{ - return (unsigned int) planepositions.size(); -} - -void Game::ClearPlaneLocations() -{ - size_t i=planepositions.size(); - while(i--) { - delete planepositions[i]; - } - planepositions.clear(); -} - -GAMLocationEntry* Game::GetPlaneLocationEntry(unsigned int i) -{ - size_t current = planepositions.size(); - if (i>=current) { - if (i>PCs.size()) { - return NULL; - } - planepositions.resize(i+1); - while(current<=i) { - planepositions[current++]=(GAMLocationEntry *) calloc(1, sizeof(GAMLocationEntry) ); - } - } - return planepositions[i]; -} - -char *Game::GetFamiliar(unsigned int Index) -{ - return Familiars[Index]; -} - -//reading the challenge rating table for iwd2 (only when needed) -void Game::LoadCRTable() -{ - AutoTable table("moncrate"); - if (table.ok()) { - int maxrow = table->GetRowCount()-1; - crtable = new CRRow[MAX_LEVEL]; - for(int i=0;iGetColumnCount(row)-1; - for(int j=0;jQueryField(row,col) ); - } - } - } -} - -int Game::GetXPFromCR(int cr) -{ - if (!crtable) LoadCRTable(); - if (crtable) { - int level = GetPartyLevel(true); - if (cr>=MAX_CRLEVEL) { - cr=MAX_CRLEVEL-1; - } - print("Challenge Rating: %d, party level: %d ", cr, level); - return crtable[level][cr]; - } - printMessage("Game","Cannot find moncrate.2da!\n", LIGHT_RED); - return 0; -} - -void Game::ShareXP(int xp, int flags) -{ - int individual; - - if (flags&SX_CR) { - xp = GetXPFromCR(xp); - } - - if (flags&SX_DIVIDE) { - int PartySize = GetPartySize(true); //party size, only alive - if (PartySize<1) { - return; - } - individual = xp / PartySize; - } else { - individual = xp; - } - - if (!individual) { - return; - } - - if (xp>0) { - displaymsg->DisplayConstantStringValue( STR_GOTXP, 0xbcefbc, (ieDword) xp); //you have gained ... xp - } else { - displaymsg->DisplayConstantStringValue( STR_LOSTXP, 0xbcefbc, (ieDword) -xp); //you have lost ... xp - } - for (unsigned int i=0; iGetStat(IE_STATE_ID)&STATE_DEAD) { - continue; - } - PCs[i]->AddExperience(individual); - } -} - -bool Game::EveryoneStopped() const -{ - for (unsigned int i=0; iGetNextStep() ) return false; - } - return true; -} - -//canmove=true: if some PC can't move (or hostile), then this returns false -bool Game::EveryoneNearPoint(Map *area, const Point &p, int flags) const -{ - for (unsigned int i=0; iSelected) { - continue; - } - } - if (PCs[i]->GetStat(IE_STATE_ID)&STATE_DEAD) { - continue; - } - if (flags&ENP_CANMOVE) { - //someone is uncontrollable, can't move - if (PCs[i]->GetStat(IE_EA)>EA_GOODCUTOFF) { - return false; - } - - if (PCs[i]->GetStat(IE_STATE_ID)&STATE_CANTMOVE) { - return false; - } - } - if (PCs[i]->GetCurrentArea()!=area) { - return false; - } - if (Distance(p,PCs[i])>MAX_TRAVELING_DISTANCE) { - print("Actor %s is not near!\n", PCs[i]->LongName); - return false; - } - } - return true; -} - -//called when someone died -void Game::PartyMemberDied(Actor *actor) -{ - //this could be null, in some extreme cases... - Map *area = actor->GetCurrentArea(); - - for (unsigned int i=0; iGetStat(IE_STATE_ID)&STATE_DEAD) { - continue; - } - if (PCs[i]->GetCurrentArea()!=area) { - continue; - } - PCs[i]->ReactToDeath(actor->GetScriptName()); - } -} - -void Game::IncrementChapter() -{ - //chapter first set to 0 (prologue) - ieDword chapter = (ieDword) -1; - locals->Lookup("CHAPTER",chapter); - //increment chapter only if it exists - locals->SetAt("CHAPTER", chapter+1, core->HasFeature(GF_NO_NEW_VARIABLES) ); - //clear statistics - for (unsigned int i=0; iPCStats->IncrementChapter(); - } -} - -void Game::SetReputation(ieDword r) -{ - if (r<10) r=10; - else if (r>200) r=200; - if (Reputation>r) { - displaymsg->DisplayConstantStringValue(STR_LOSTREP,0xc0c000,(Reputation-r)/10); - } else if (ReputationDisplayConstantStringValue(STR_GOTREP,0xc0c000,(r-Reputation)/10); - } - Reputation = r; - for (unsigned int i=0; iSetBase(IE_REPUTATION, Reputation); - } -} - -void Game::SetControlStatus(int value, int mode) -{ - switch(mode) { - case BM_OR: ControlStatus|=value; break; - case BM_NAND: ControlStatus&=~value; break; - case BM_SET: ControlStatus=value; break; - case BM_AND: ControlStatus&=value; break; - case BM_XOR: ControlStatus^=value; break; - } - core->SetEventFlag(EF_CONTROL); -} - -void Game::AddGold(ieDword add) -{ - ieDword old; - - if (!add) { - return; - } - old = PartyGold; - PartyGold += add; - if (oldDisplayConstantStringValue( STR_GOTGOLD, 0xc0c000, PartyGold-old); - } else { - displaymsg->DisplayConstantStringValue( STR_LOSTGOLD, 0xc0c000, old-PartyGold); - } -} - -//later this could be more complicated -void Game::AdvanceTime(ieDword add) -{ - ieDword h = GameTime/(300*AI_UPDATE_TIME); - GameTime+=add; - if (h!=GameTime/(300*AI_UPDATE_TIME)) { - //asking for a new weather when the hour changes - WeatherBits&=~WB_HASWEATHER; - } - Ticks+=add*interval; - //change the tileset if needed - Map *map = GetCurrentArea(); - if (map && map->ChangeMap(IsDay())) { - //play the daylight transition movie appropriate for the area - //it is needed to play only when the area truly changed its tileset - //this is signalled by ChangeMap - int areatype = (area->AreaType&(AT_FOREST|AT_CITY|AT_DUNGEON))>>3; - ieResRef *res; - - printMessage("Game","Switching DayLight\n",GREEN); - if (IsDay()) { - res=&nightmovies[areatype]; - } else { - res=&daymovies[areatype]; - } - if (*res[0]!='*') { - core->PlayMovie(*res); - } - } -} - -//returns true if there are excess players in the team -bool Game::PartyOverflow() const -{ - GameControl *gc = core->GetGameControl(); - if (!gc) { - return false; - } - //don't start this screen when the gui is busy - if (gc->GetDialogueFlags() & (DF_IN_DIALOG|DF_IN_CONTAINER|DF_FREEZE_SCRIPTS) ) { - return false; - } - if (!partysize) { - return false; - } - return (PCs.size()>partysize); -} - -bool Game::AnyPCInCombat() const -{ - if (!CombatCounter) { - return false; - } - - return true; -} - -//returns true if the protagonist (or the whole party died) -bool Game::EveryoneDead() const -{ - //if there are no PCs, then we assume everyone dead - if (!PCs.size() ) { - return true; - } - if (protagonist==PM_NO) { - Actor *nameless = PCs[0]; - if (nameless->GetStat(IE_STATE_ID)&STATE_NOSAVE) { - if (area->INISpawn) { - area->INISpawn->RespawnNameless(); - } - } - return false; - } - // if protagonist died - if (protagonist==PM_YES) { - if (PCs[0]->GetStat(IE_STATE_ID)&STATE_NOSAVE) { - return true; - } - return false; - } - //protagonist == 2 - for (unsigned int i=0; iGetStat(IE_STATE_ID)&STATE_NOSAVE) ) { - return false; - } - } - return true; -} - -//runs all area scripts - -void Game::UpdateScripts() -{ - Update(); - size_t idx; - - PartyAttack = false; - - for (idx=0;idxUpdateScripts(); - } - - if (PartyAttack) { - //ChangeSong will set the battlesong only if CombatCounter is nonzero - CombatCounter=150; - ChangeSong(false, true); - } else { - if (CombatCounter) { - CombatCounter--; - //Change song if combatcounter went down to 0 - if (!CombatCounter) { - ChangeSong(false, false); - } - } - } - - if (StateOverrideTime) - StateOverrideTime--; - if (BanterBlockTime) - BanterBlockTime--; - - if (Maps.size()>MAX_MAPS_LOADED) { - idx = Maps.size(); - - //starting from 0, so we see the most recent master area first - for(unsigned int i=0;iGetMusicMgr()->IsPlaying()) { - ChangeSong(false,false); - } - - //this is used only for the death delay so far - if (event_handler) { - if (!event_timer) { - event_handler->call(); - event_handler = NULL; - } - event_timer--; - } - - if (EveryoneDead()) { - //don't check it any more - protagonist = PM_NO; - core->GetGUIScriptEngine()->RunFunction("GUIWORLD", "DeathWindow"); - return; - } - - if (PartyOverflow()) { - partysize = 0; - core->GetGUIScriptEngine()->RunFunction("GUIWORLD", "OpenReformPartyWindow"); - return; - } -} - -void Game::SetTimedEvent(EventHandler func, int count) -{ - event_timer = count; - event_handler = func; -} - -void Game::SetProtagonistMode(int mode) -{ - protagonist = mode; -} - -void Game::SetPartySize(int size) -{ - // 0 size means no party size control - if (size<0) { - return; - } - partysize = (size_t) size; -} - -//Get the area dependent rest movie -ieResRef *Game::GetDream(Map *area) -{ - //select dream based on area - int daynight = IsDay(); - if (area->Dream[daynight][0]) { - return area->Dream+daynight; - } - int dream = (area->AreaType&(AT_FOREST|AT_CITY|AT_DUNGEON))>>3; - return restmovies+dream; -} - -//Start dream cutscenes for player1 -void Game::PlayerDream() -{ - Scriptable *Sender = GetPC(0,true); - if (!Sender) return; - - GameScript* gs = new GameScript( "player1d", Sender,0,0 ); - gs->Update(); - delete( gs ); -} - -//noareacheck = no random encounters -//dream = 0 - based on area non-0 - select from list -//-1 no dream -//hp is how much hp the rest will heal -void Game::RestParty(int checks, int dream, int hp) -{ - if (!(checks&REST_NOMOVE) ) { - if (!EveryoneStopped()) { - return; - } - } - Actor *leader = GetPC(0, true); - if (!leader) { - return; - } - - Map *area = leader->GetCurrentArea(); - //we let them rest if someone is paralyzed, but the others gather around - if (!(checks&REST_NOSCATTER) ) { - if (!EveryoneNearPoint( area, leader->Pos, 0 ) ) { - //party too scattered - displaymsg->DisplayConstantString( STR_SCATTERED, 0xff0000 ); - return; - } - } - - if (!(checks&REST_NOCRITTER) ) { - //don't allow resting while in combat - if (AnyPCInCombat()) { - displaymsg->DisplayConstantString( STR_CANTRESTMONS, 0xff0000 ); - return; - } - //don't allow resting if hostiles are nearby - if (area->AnyEnemyNearPoint(leader->Pos)) { - displaymsg->DisplayConstantString( STR_CANTRESTMONS, 0xff0000 ); - return; - } - } - - //rest check, if PartyRested should be set, area should return true - //area should advance gametime too (so partial rest is possible) - int hours = 8; - if (!(checks&REST_NOAREA) ) { - //you cannot rest here - if (area->AreaFlags&1) { - displaymsg->DisplayConstantString( STR_MAYNOTREST, 0xff0000 ); - return; - } - //you may not rest here, find an inn - if (!(area->AreaType&(AT_OUTDOOR|AT_FOREST|AT_DUNGEON|AT_CAN_REST) )) - { - displaymsg->DisplayConstantString( STR_MAYNOTREST, 0xff0000 ); - return; - } - //area encounters - if(area->Rest( leader->Pos, 8, (GameTime/AI_UPDATE_TIME)%7200/3600) ) { - return; - } - } - AdvanceTime(2400*AI_UPDATE_TIME); - - int i = GetPartySize(true); // party size, only alive - - while (i--) { - Actor *tar = GetPC(i, true); - tar->ClearPath(); - tar->ClearActions(); - tar->SetModal(MS_NONE, 0); - //if hp = 0, then healing will be complete - tar->Heal(hp); - //removes fatigue, recharges spells - tar->Rest(0); - tar->PartyRested(); - } - - //movie and cutscene dreams - if (dream>=0) { - //cutscene dreams - if (gamedata->Exists("player1d",IE_BCS_CLASS_ID, true)) - PlayerDream(); - - //select dream based on area - ieResRef *movie; - if (dream==0 || dream>7) { - movie = GetDream(area); - } else { - movie = restmovies+dream; - } - if (*movie[0]!='*') { - core->PlayMovie(*movie); - } - } - - //set partyrested flags - PartyRested(); - area->PartyRested(); - core->SetEventFlag(EF_ACTION); - - //restindex will be -1 in the case of PST - //FIXME: I don't quite see why we can't sumply use the same strings.2da entry - //It seems we could reduce complexity here, and free up 2-3 string slots too - int restindex = displaymsg->GetStringReference(STR_REST); - int strindex; - char* tmpstr = NULL; - - core->GetTokenDictionary()->SetAtCopy("HOUR", hours); - if (restindex != -1) { - strindex = displaymsg->GetStringReference(STR_HOURS); - } else { - strindex = displaymsg->GetStringReference(STR_PST_HOURS); - restindex = displaymsg->GetStringReference(STR_PST_REST); - } - - //this would be bad - if (strindex == -1 || restindex == -1) return; - tmpstr = core->GetString(strindex, 0); - //as would this - if (!tmpstr) return; - - core->GetTokenDictionary()->SetAtCopy("DURATION", tmpstr); - core->FreeString(tmpstr); - displaymsg->DisplayString(restindex, 0xffffff, 0); -} - -//timestop effect -void Game::TimeStop(Actor* owner, ieDword end) -{ - timestop_owner=owner; - timestop_end=end; -} - -// check if the passed actor is a victim of timestop -bool Game::TimeStoppedFor(const Actor* target) -{ - if (!timestop_owner) { - return false; - } - if (target == timestop_owner || target->GetStat(IE_DISABLETIMESTOP)) { - return false; - } - return true; -} - -//recalculate the party's infravision state -void Game::Infravision() -{ - hasInfra = false; - Map *map = GetCurrentArea(); - if (!map) return; - for(size_t i=0;iGetCurrentArea()!=map) continue; - //Group infravision overrides this??? - if (!actor->Selected) continue; - if (actor->GetStat(IE_STATE_ID) & STATE_INFRA) { - hasInfra = true; - return; - } - } -} - -//returns the colour which should be applied onto the whole game area viewport -//this is based on timestop, dream area, weather, daytime - -static const Color DreamTint={0xf0,0xe0,0xd0,0x10}; //light brown scale -static const Color NightTint={0x80,0x80,0xe0,0x40}; //dark, bluish -static const Color DuskTint={0xe0,0x80,0x80,0x40}; //dark, reddish -static const Color FogTint={0xff,0xff,0xff,0x40}; //whitish -static const Color DarkTint={0x80,0x80,0xe0,0x10}; //slightly dark bluish - -const Color *Game::GetGlobalTint() const -{ - Map *map = GetCurrentArea(); - if (!map) return NULL; - if (map->AreaFlags&AF_DREAM) { - return &DreamTint; - } - if ((map->AreaType&(AT_OUTDOOR|AT_DAYNIGHT|AT_EXTENDED_NIGHT)) == (AT_OUTDOOR|AT_DAYNIGHT) ) { - //get daytime colour - ieDword daynight = ((GameTime/AI_UPDATE_TIME)%7200/300); - if (daynight<2 || daynight>22) { - return &NightTint; - } - if (daynight>20 || daynight<4) { - return &DuskTint; - } - } - if ((map->AreaType&(AT_OUTDOOR|AT_WEATHER)) == (AT_OUTDOOR|AT_WEATHER)) { - //get weather tint - if (WeatherBits&WB_RAIN) { - return &DarkTint; - } - if (WeatherBits&WB_FOG) { - return &FogTint; - } - } - - return NULL; -} - -bool Game::IsDay() -{ - ieDword daynight = ((GameTime/AI_UPDATE_TIME)%7200/300); - if(daynight<4 || daynight>20) { - return false; - } - return true; -} - -void Game::ChangeSong(bool always, bool force) -{ - int Song; - - if (CombatCounter) { - //battlesong - Song = SONG_BATTLE; - } else { - //will select SONG_DAY or SONG_NIGHT - Song = (GameTime/AI_UPDATE_TIME)%7200/3600; - } - //area may override the song played (stick in battlemusic) - //always transition gracefully with ChangeSong - //force just means, we schedule the song for later, if currently - //is playing - area->PlayAreaSong( Song, always, force ); -} - -/* this method redraws weather. If update is false, - then the weather particles won't change (game paused) -*/ -void Game::DrawWeather(const Region &screen, bool update) -{ - if (!weather) { - return; - } - if (!area->HasWeather()) { - return; - } - - weather->Draw( screen ); - if (!update) { - return; - } - - if (!(WeatherBits & (WB_RAIN|WB_SNOW)) ) { - if (weather->GetPhase() == P_GROW) { - weather->SetPhase(P_FADE); - } - } - //if (GameTime&1) { - int drawn = weather->Update(); - if (drawn) { - WeatherBits &= ~WB_START; - } - //} - - if (WeatherBits&WB_HASWEATHER) { - return; - } - StartRainOrSnow(true, area->GetWeather()); -} - -/* sets the weather type */ -void Game::StartRainOrSnow(bool conditional, int w) -{ - if (conditional && (w & (WB_RAIN|WB_SNOW)) ) { - if (WeatherBits & (WB_RAIN | WB_SNOW) ) - return; - } - // whatever was responsible for calling this, we now have some set weather - WeatherBits = w | WB_HASWEATHER; - if (w & WB_LIGHTNING) { - if (WeatherBits&WB_START) { - //already raining - if (GameTime&1) { - core->PlaySound(DS_LIGHTNING1); - } else { - core->PlaySound(DS_LIGHTNING2); - } - } else { - //start raining (far) - core->PlaySound(DS_LIGHTNING3); - } - } - if (w&WB_SNOW) { - core->PlaySound(DS_SNOW); - weather->SetType(SP_TYPE_POINT, SP_PATH_FLIT, SP_SPAWN_SOME); - weather->SetPhase(P_GROW); - weather->SetColor(SPARK_COLOR_WHITE); - return; - } - if (w&WB_RAIN) { - core->PlaySound(DS_RAIN); - weather->SetType(SP_TYPE_LINE, SP_PATH_RAIN, SP_SPAWN_SOME); - weather->SetPhase(P_GROW); - weather->SetColor(SPARK_COLOR_STONE); - return; - } - weather->SetPhase(P_FADE); -} - -void Game::SetExpansion(ieDword value) -{ - if (Expansion>=value) { - return; - } - Expansion = value; - - switch(Expansion) { - default: - core->SetEventFlag(EF_EXPANSION); - break; - //TODO: move this hardcoded hack to the scripts - case 5: - core->GetDictionary()->SetAt( "PlayMode", 2 ); - - int i = GetPartySize(false); - while(i--) { - Actor *actor = GetPC(i, false); - InitActorPos(actor); - } - } -} - -void Game::DebugDump() -{ - size_t idx; - - print("Currently loaded areas:\n"); - for(idx=0;idxGetScriptName()); - } - print("Current area: %s Previous area: %s\n", CurrentArea, PreviousArea); - print("Global script: %s\n", Scripts[0]->GetName()); - print("CombatCounter: %d\n", (int) CombatCounter); - - print("Party size: %d\n", (int) PCs.size()); - for(idx=0;idxShortName, actor->InParty, actor->Selected?"x":"-"); - } -} - -Actor *Game::GetActorByGlobalID(ieDword globalID) -{ - size_t mc = GetLoadedMapCount(); - while(mc--) { - Map *map = GetMap(mc); - Actor *actor = map->GetActorByGlobalID(globalID); - if (actor) return actor; - } - return GetGlobalActorByGlobalID(globalID); -} - -ieByte *Game::AllocateMazeData() -{ - if (mazedata) { - free(mazedata); - } - mazedata = (ieByte*)malloc(MAZE_DATA_SIZE); - return mazedata; -} - -bool Game::IsTimestopActive() -{ - return timestop_end > GameTime; -} diff --git a/project/jni/application/gemrb/gemrb/core/Game.h b/project/jni/application/gemrb/gemrb/core/Game.h deleted file mode 100644 index 851d28d72..000000000 --- a/project/jni/application/gemrb/gemrb/core/Game.h +++ /dev/null @@ -1,482 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -/** - * @file Game.h - * Declares Game class, object representing current game state. - * @author The GemRB Project - */ - - -class Game; - -#ifndef GAME_H -#define GAME_H - -#include "exports.h" -#include "ie_types.h" - -#include "Callback.h" -#include "Scriptable/Scriptable.h" -#include "Scriptable/PCStatStruct.h" -#include "Variables.h" - -#include - -class Actor; -class Map; -class Particles; -class TableMgr; - -//the size of the bestiary register -#define BESTIARY_SIZE 260 - -//ShareXP flags -#define SX_DIVIDE 1 //divide XP among team members -#define SX_CR 2 //use challenge rating resolution - -//joinparty flags -#define JP_JOIN 1 //refresh join time -#define JP_INITPOS 2 //init startpos -#define JP_SELECT 4 //select the actor after joining - -//protagonist mode -#define PM_NO 0 //no death checks -#define PM_YES 1 //if protagonist dies, game over -#define PM_TEAM 2 //if team dies, game over - -// Flags bits for SelectActor() -// !!! Keep these synchronized with GUIDefines.py !!! -#define SELECT_NORMAL 0x00 -#define SELECT_REPLACE 0x01 // when selecting actor, deselect all others -#define SELECT_QUIET 0x02 // do not run handler when changing selection - -// Flags bits for EveryoneNearPoint() -#define ENP_CANMOVE 1 // also check if the PC can move -#define ENP_ONLYSELECT 2 // check only selected PC - -// GUI Control Status flags (saved in game) -#define CS_PARTY_AI 1 //enable party AI -#define CS_MEDIUM 2 //medium dialog -#define CS_LARGE 6 //large dialog, both bits set -#define CS_DIALOGSIZEMASK 6 -#define CS_DIALOG 8 //dialog is running -#define CS_HIDEGUI 16 //hide all gui -#define CS_ACTION 32 //hide action pane -#define CS_PORTRAIT 64 //hide portrait pane -#define CS_MAPNOTES 128 //hide mapnotes - -//Weather bits -#define WB_NORMAL 0 -#define WB_RAIN 1 -#define WB_SNOW 2 -#define WB_FOG 3 -#define WB_MASK 7 -#define WB_LIGHTNING 8 -#define WB_HASWEATHER 0x40 -#define WB_START 0x80 - -//Rest flags -#define REST_NOAREA 1 //no area check -#define REST_NOSCATTER 2 //no scatter check -#define REST_NOMOVE 4 //no movement check -#define REST_NOCRITTER 8 //no hostiles check - -//Song types (hardcoded) -#define SONG_DAY 0 -#define SONG_NIGHT 1 -#define SONG_BATTLE 3 - -/** - * @struct PCStruct - * Information about party member. - */ - -struct PCStruct { - ieWord Selected; - ieWord PartyOrder; - ieDword OffsetToCRE; - ieDword CRESize; - ieResRef CREResRef; - ieDword Orientation; - ieResRef Area; - ieWord XPos; - ieWord YPos; - ieWord ViewXPos; - ieWord ViewYPos; - ieWord ModalState; - ieWord Happiness; - ieDword Interact[MAX_INTERACT]; - ieWord QuickWeaponSlot[MAX_QUICKWEAPONSLOT]; - ieWord QuickWeaponHeader[MAX_QUICKWEAPONSLOT]; - ieResRef QuickSpellResRef[MAX_QSLOTS]; - ieWord QuickItemSlot[MAX_QUICKITEMSLOT]; - ieWord QuickItemHeader[MAX_QUICKITEMSLOT]; - char Name[32]; - ieDword TalkCount; - ieByte QSlots[GUIBT_COUNT]; - ieByte QuickSpellClass[MAX_QSLOTS]; -}; - -#define IE_GAM_JOURNAL 0 -#define IE_GAM_QUEST_UNSOLVED 1 -#define IE_GAM_QUEST_DONE 2 -#define IE_GAM_JOURNAL_USER 3 - -/** - * @struct GAMJournalEntry - * Single entry in a journal - */ - -struct GAMJournalEntry { - ieStrRef Text; - ieDword GameTime; // in game time seconds - ieByte Chapter; - ieByte unknown09; - ieByte Section; - ieByte Group; // this is a GemRB extension -}; - -// Saved location of party member. -struct GAMLocationEntry { - ieResRef AreaResRef; - Point Pos; -}; - -//pst maze data structures (TODO: create a separate class?) -struct maze_entry { - ieDword override; - ieDword accessible; - ieDword valid; - ieDword trapped; - ieDword traptype; - ieWord walls; - ieDword visited; -}; - -struct maze_header { - ieDword maze_sizex, maze_sizey; - ieDword pos1x, pos1y; //nordom's position - ieDword pos2x, pos2y; //main hall position - ieDword pos3x, pos3y; //foyer entrance - ieDword pos4x, pos4y; //unknown - ieDword trapcount; //based on map size - ieDword initialized; //set to 1 - ieDword unknown2c; //unknown - ieDword unknown30; //unknown -}; - -#define MAZE_ENTRY_SIZE sizeof(maze_entry) -#define MAZE_HEADER_SIZE sizeof(maze_header) -#define MAZE_MAX_DIM 8 -#define MAZE_ENTRY_COUNT (MAZE_MAX_DIM*MAZE_MAX_DIM) -#define MAZE_DATA_SIZE (MAZE_ENTRY_COUNT*MAZE_ENTRY_SIZE+MAZE_HEADER_SIZE) -#define MAZE_DATA_SIZE_HARDCODED 1720 - -//maze header indices -#define MH_POS1X 0 -#define MH_POS1Y 1 -#define MH_POS2X 2 -#define MH_POS2Y 3 -#define MH_POS3X 4 -#define MH_POS3Y 5 -#define MH_POS4X 6 -#define MH_POS4Y 7 -#define MH_TRAPCOUNT 8 -#define MH_INITED 9 -#define MH_UNKNOWN2C 10 -#define MH_UNKNOWN30 11 - -//maze entry indices -#define ME_OVERRIDE 0 -#define ME_VALID 1 -#define ME_ACCESSIBLE 2 -#define ME_TRAP 3 -#define ME_WALLS 4 -#define ME_VISITED 5 - -//ME_WALL bitfields -#define WALL_SOUTH 1 -#define WALL_NORTH 2 -#define WALL_EAST 4 -#define WALL_WEST 8 - -#define MAX_CRLEVEL 32 - -typedef int CRRow[MAX_CRLEVEL]; - -/** - * @class Game - * Object representing current game state, mostly party. - */ - -class GEM_EXPORT Game : public Scriptable { -public: - Game(void); - ~Game(void); -private: - std::vector< Actor*> PCs; - std::vector< Actor*> NPCs; - std::vector< Map*> Maps; - std::vector< GAMJournalEntry*> Journals; - std::vector< GAMLocationEntry*> savedpositions; - std::vector< GAMLocationEntry*> planepositions; - std::vector< char*> mastarea; - CRRow *crtable; - ieResRef restmovies[8]; - ieResRef daymovies[8]; - ieResRef nightmovies[8]; - int MapIndex; -public: - std::vector< Actor*> selected; - int version; - Variables* kaputz; - ieByte* beasts; - ieByte* mazedata; //only in PST - ieResRef Familiars[9]; - ieDword CombatCounter; - ieDword StateOverrideFlag, StateOverrideTime; - ieDword BanterBlockFlag, BanterBlockTime; - - /** Index of PC selected in non-walking environment (shops, inventory...) */ - int SelectedSingle; - /** 0 if the protagonist's death doesn't cause game over */ - /** 1 if the protagonist's death causes game over */ - /** 2 if no check is needed (pst) */ - int protagonist; - /** if party size exceeds this amount, a callback will be called */ - size_t partysize; - ieDword Ticks; - ieDword interval; // 1000/AI_UPDATE (a tenth of a round in ms) - ieDword GameTime; - ieDword LastScriptUpdate; // GameTime at which UpdateScripts last ran - ieDword RealTime; - ieWord WhichFormation; - ieWord Formations[5]; - ieDword PartyGold; - ieWord NpcInParty; - ieWord WeatherBits; - ieDword Unknown48; //still unknown - ieDword Reputation; - ieDword ControlStatus; // used in bg2, iwd (where you can switch panes off) - ieDword Expansion; // mostly used by BG2. IWD games set it to 3 on newgame - ieResRef AnotherArea; - ieResRef CurrentArea; - ieResRef PreviousArea; //move here if the worldmap exit is illegal? - ieResRef LoadMos; - Actor *timestop_owner; - ieDword timestop_end; - Particles *weather; - int event_timer; - EventHandler event_handler; //like in Control - bool hasInfra; - bool familiarBlock; - bool PartyAttack; -private: - /** reads the challenge rating table */ - void LoadCRTable(); -public: - /** Returns the PC's slot count for partyID */ - int FindPlayer(unsigned int partyID); - /** Returns actor by slot */ - Actor* GetPC(unsigned int slot, bool onlyalive); - /** Finds an actor in party by party ID, returns Actor, if not there, returns NULL*/ - Actor* FindPC(unsigned int partyID); - Actor* FindNPC(unsigned int partyID); - /** Finds a global actor by global ID */ - Actor* GetGlobalActorByGlobalID(ieDword globalID); - /** Finds an actor in party, returns slot, if not there, returns -1*/ - int InParty(Actor* pc) const; - /** Finds an actor in store, returns slot, if not there, returns -1*/ - int InStore(Actor* pc) const; - /** Finds an actor in party by scripting name*/ - Actor* FindPC(const char *deathvar); - /** Finds an actor in store by scripting name*/ - Actor* FindNPC(const char *deathvar); - /** Sets the area and position of the actor to the starting position */ - void InitActorPos(Actor *actor); - /** Joins party */ - int JoinParty(Actor* pc, int join=JP_JOIN); - /** Return current party size */ - int GetPartySize(bool onlyalive) const; - /** Returns the npcs count */ - int GetNPCCount() const { return (int)NPCs.size(); } - /** Sends the hotkey trigger to all selected pcs */ - void SetHotKey(unsigned long Key); - /** Select PC for non-walking environment (shops, inventory, ...) */ - bool SelectPCSingle(int index); - /** Get index of selected PC for non-walking env (shops, inventory, ...) */ - int GetSelectedPCSingle() const; - /** (De)selects actor. */ - bool SelectActor( Actor* actor, bool select, unsigned flags ); - - /** Return current party level count for xp calculations */ - int GetPartyLevel(bool onlyalive) const; - /** Reassigns inparty numbers, call it after party creation */ - void ConsolidateParty(); - /** Removes actor from party (if in there) */ - int LeaveParty(Actor* pc); - /** Returns slot*/ - int DelPC(unsigned int slot, bool autoFree = false); - int DelNPC(unsigned int slot, bool autoFree = false); - /** Returns map in index */ - Map* GetMap(unsigned int index) const; - /** Returns a map from area name, loads it if needed - * use it for the biggest safety, change = true will change the current map */ - Map* GetMap(const char *areaname, bool change); - /** Returns slot of the map if found */ - int FindMap(const char *ResRef); - int AddMap(Map* map); - /** Determine if area is master area*/ - bool MasterArea(const char *area); - /** Dynamically adding an area to master areas*/ - void SetMasterArea(const char *area); - /** Returns slot of the map, if it was already loaded, - * don't load it again, set changepf == true, - * if you want to change the pathfinder too. */ - int LoadMap(const char* ResRef, bool loadscreen); - int DelMap(unsigned int index, int forced = 0); - int AddNPC(Actor* npc); - Actor* GetNPC(unsigned int Index); - void SwapPCs(unsigned int Index1, unsigned int Index2); - bool IsDay(); - - //journal entries - /** Deletes one or all journal entries if strref is -1 */ - void DeleteJournalEntry(ieStrRef strref); - /** Delete entries of the same group */ - void DeleteJournalGroup(int Group); - /** Adds a journal entry from dialog data. - * Time and chapter are calculated on the fly - * Returns false if the entry already exists */ - bool AddJournalEntry(ieStrRef strref, int section, int group); - /** Adds a journal entry while loading the .gam structure */ - void AddJournalEntry(GAMJournalEntry* entry); - unsigned int GetJournalCount() const; - GAMJournalEntry* FindJournalEntry(ieStrRef strref); - GAMJournalEntry* GetJournalEntry(unsigned int Index); - - //saved locations - unsigned int GetSavedLocationCount() const; - void ClearSavedLocations(); - GAMLocationEntry* GetSavedLocationEntry(unsigned int Index); - - //plane locations - unsigned int GetPlaneLocationCount() const; - void ClearPlaneLocations(); - GAMLocationEntry* GetPlaneLocationEntry(unsigned int Index); - - char *GetFamiliar(unsigned int Index); - - bool IsBeastKnown(unsigned int Index) const { - if (!beasts) { - return false; - } - if (Index>=BESTIARY_SIZE) { - return false; - } - return beasts[Index] != 0; - } - void SetBeastKnown(unsigned int Index) { - if (!beasts) { - return; - } - if (Index>=BESTIARY_SIZE) { - return; - } - beasts[Index] = 1; - } - ieWord GetFormation() const { - if (WhichFormation>4) { - return 0; - } - return Formations[WhichFormation]; - } - - /** converts challenge rating to xp */ - int GetXPFromCR(int cr); - /** shares XP among all party members */ - void ShareXP(int XP, int flags); - /** returns true if we should start the party overflow window */ - bool PartyOverflow() const; - /** returns true if any pc is attacker or being attacked */ - bool AnyPCInCombat() const; - /** returns true if the party death condition is true */ - bool EveryoneDead() const; - /** returns true if no one moves */ - bool EveryoneStopped() const; - bool EveryoneNearPoint(Map *map, const Point &p, int flags) const; - /** a party member just died now */ - void PartyMemberDied(Actor *); - /** Increments chapter variable and refreshes kill stats */ - void IncrementChapter(); - /** Sets party reputation */ - void SetReputation(ieDword r); - /** Sets the gamescreen control status (pane states, dialog textarea size) */ - void SetControlStatus(int value, int operation); - /** Sets party size (1-32000) */ - void SetPartySize(int value); - /** Sets a guiscript function to happen after x AI cycles have elapsed */ - void SetTimedEvent(EventHandler func, int count); - /** Sets protagonist mode to 0-none,1-protagonist,2-team */ - void SetProtagonistMode(int value); - void StartRainOrSnow(bool conditional, int weather); - size_t GetLoadedMapCount() const { return Maps.size(); } - /** Adds or removes gold */ - void AddGold(ieDword add); - /** Adds ticks to game time */ - void AdvanceTime(ieDword add); - /** Runs the script engine on the global script and the area scripts - areas run scripts on door, infopoint, container, actors too */ - void UpdateScripts(); - /** runs area functionality, sets partyrested trigger */ - void RestParty(int checks, int dream, int hp); - /** timestop effect initiated by actor */ - void TimeStop(Actor *actor, ieDword end); - /** check if the passed actor is a victim of timestop */ - bool TimeStoppedFor(const Actor* target=NULL); - /** updates the infravision info */ - void Infravision(); - /** gets the colour which should be applied over the game area, - may return NULL */ - const Color *GetGlobalTint() const; - /** returns true if party has infravision */ - bool PartyHasInfravision() const { return hasInfra; } - /** draw weather */ - void DrawWeather(const Region &screen, bool update); - /** updates current area music */ - void ChangeSong(bool always = true, bool force = true); - /** sets expansion mode */ - void SetExpansion(ieDword value); - /** Dumps information about the object */ - void DebugDump(); - /** Finds an actor by global ID */ - Actor *GetActorByGlobalID(ieDword objectID); - /** Allocates maze data */ - ieByte *AllocateMazeData(); - /** Checks if any timestop effects are active */ - bool IsTimestopActive(); -private: - bool DetermineStartPosType(const TableMgr *strta); - ieResRef *GetDream(Map *area); - void PlayerDream(); -}; - -#endif // ! GAME_H diff --git a/project/jni/application/gemrb/gemrb/core/GameData.cpp b/project/jni/application/gemrb/gemrb/core/GameData.cpp deleted file mode 100644 index f4c82b53f..000000000 --- a/project/jni/application/gemrb/gemrb/core/GameData.cpp +++ /dev/null @@ -1,549 +0,0 @@ -/* 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 "GameData.h" - -#include "globals.h" - -#include "ActorMgr.h" -#include "AnimationMgr.h" -#include "Cache.h" -#include "CharAnimations.h" -#include "Effect.h" -#include "EffectMgr.h" -#include "Factory.h" -#include "Game.h" -#include "ImageFactory.h" -#include "ImageMgr.h" -#include "Interface.h" -#include "Item.h" -#include "ItemMgr.h" -#include "PluginMgr.h" -#include "ResourceDesc.h" -#include "ScriptedAnimation.h" -#include "Spell.h" -#include "SpellMgr.h" -#include "StoreMgr.h" -#include "Scriptable/Actor.h" -#include "System/FileStream.h" - -#include - -static void ReleaseItem(void *poi) -{ - delete ((Item *) poi); -} - -static void ReleaseSpell(void *poi) -{ - delete ((Spell *) poi); -} - -static void ReleaseEffect(void *poi) -{ - delete ((Effect *) poi); -} - -static void ReleasePalette(void *poi) -{ - //we allow nulls, but we shouldn't release them - if (!poi) return; - //as long as palette has its own refcount, this should be Release - ((Palette *) poi)->Release(); -} - -GEM_EXPORT GameData* gamedata; - -GameData::GameData() -{ - factory = new Factory(); -} - -GameData::~GameData() -{ - delete factory; -} - -void GameData::ClearCaches() -{ - ItemCache.RemoveAll(ReleaseItem); - SpellCache.RemoveAll(ReleaseSpell); - EffectCache.RemoveAll(ReleaseEffect); - PaletteCache.RemoveAll(ReleasePalette); -} - -Actor *GameData::GetCreature(const char* ResRef, unsigned int PartySlot) -{ - DataStream* ds = GetResource( ResRef, IE_CRE_CLASS_ID ); - if (!ds) - return 0; - - PluginHolder actormgr(IE_CRE_CLASS_ID); - if (!actormgr->Open(ds)) { - return 0; - } - Actor* actor = actormgr->GetActor(PartySlot); - return actor; -} - -int GameData::LoadCreature(const char* ResRef, unsigned int PartySlot, bool character, int VersionOverride) -{ - DataStream *stream; - - Actor* actor; - if (character) { - char nPath[_MAX_PATH], fName[16]; - snprintf( fName, sizeof(fName), "%s.chr", ResRef); - PathJoin( nPath, core->GamePath, "characters", fName, NULL ); - stream = FileStream::OpenFile(nPath); - PluginHolder actormgr(IE_CRE_CLASS_ID); - if (!actormgr->Open(stream)) { - return -1; - } - actor = actormgr->GetActor(PartySlot); - } else { - actor = GetCreature(ResRef, PartySlot); - } - - if ( !actor ) { - return -1; - } - - if (VersionOverride != -1) { - actor->version = VersionOverride; - } - - //both fields are of length 9, make this sure! - memcpy(actor->Area, core->GetGame()->CurrentArea, sizeof(actor->Area) ); - if (actor->BaseStats[IE_STATE_ID] & STATE_DEAD) { - actor->SetStance( IE_ANI_TWITCH ); - } else { - actor->SetStance( IE_ANI_AWAKE ); - } - actor->SetOrientation( 0, false ); - - if ( PartySlot != 0 ) { - return core->GetGame()->JoinParty( actor, JP_JOIN|JP_INITPOS ); - } - else { - return core->GetGame()->AddNPC( actor ); - } -} - -/** Loads a 2DA Table, returns -1 on error or the Table Index on success */ -int GameData::LoadTable(const ieResRef ResRef) -{ - int ind = GetTableIndex( ResRef ); - if (ind != -1) { - tables[ind].refcount++; - return ind; - } - //print("(%s) Table not found... Loading from file\n", ResRef); - DataStream* str = GetResource( ResRef, IE_2DA_CLASS_ID ); - if (!str) { - return -1; - } - PluginHolder tm(IE_2DA_CLASS_ID); - if (!tm) { - delete str; - return -1; - } - if (!tm->Open(str)) { - return -1; - } - Table t; - t.refcount = 1; - strncpy( t.ResRef, ResRef, 8 ); - t.tm = tm; - ind = -1; - for (size_t i = 0; i < tables.size(); i++) { - if (tables[i].refcount == 0) { - ind = ( int ) i; - break; - } - } - if (ind != -1) { - tables[ind] = t; - return ind; - } - tables.push_back( t ); - return ( int ) tables.size() - 1; -} -/** Gets the index of a loaded table, returns -1 on error */ -int GameData::GetTableIndex(const char* ResRef) const -{ - for (size_t i = 0; i < tables.size(); i++) { - if (tables[i].refcount == 0) - continue; - if (strnicmp( tables[i].ResRef, ResRef, 8 ) == 0) - return ( int ) i; - } - return -1; -} -/** Gets a Loaded Table by its index, returns NULL on error */ -Holder GameData::GetTable(unsigned int index) const -{ - if (index >= tables.size()) { - return NULL; - } - if (tables[index].refcount == 0) { - return NULL; - } - return tables[index].tm; -} - -/** Frees a Loaded Table, returns false on error, true on success */ -bool GameData::DelTable(unsigned int index) -{ - if (index==0xffffffff) { - tables.clear(); - return true; - } - if (index >= tables.size()) { - return false; - } - if (tables[index].refcount == 0) { - return false; - } - tables[index].refcount--; - if (tables[index].refcount == 0) - if (tables[index].tm) - tables[index].tm.release(); - return true; -} - -Palette *GameData::GetPalette(const ieResRef resname) -{ - Palette *palette = (Palette *) PaletteCache.GetResource(resname); - if (palette) { - return palette; - } - //additional hack for allowing NULL's - if (PaletteCache.RefCount(resname)!=-1) { - return NULL; - } - ResourceHolder im(resname); - if (im == NULL) { - PaletteCache.SetAt(resname, NULL); - return NULL; - } - - palette = new Palette(); - im->GetPalette(256,palette->col); - palette->named=true; - PaletteCache.SetAt(resname, (void *) palette); - return palette; -} - -void GameData::FreePalette(Palette *&pal, const ieResRef name) -{ - int res; - - if (!pal) { - return; - } - if (!name || !name[0]) { - if(pal->named) { - error("GameData", "Palette is supposed to be named, but got no name!\n"); - } else { - pal->Release(); - pal=NULL; - } - return; - } - if (!pal->named) { - error("GameData", "Unnamed palette, it should be %s!\n", name); - } - res=PaletteCache.DecRef((void *) pal, name, true); - if (res<0) { - error("Core", "Corrupted Palette cache encountered (reference count went below zero), Palette name is: %.8s\n", name); - } - if (!res) { - pal->Release(); - } - pal = NULL; -} - -Item* GameData::GetItem(const ieResRef resname) -{ - Item *item = (Item *) ItemCache.GetResource(resname); - if (item) { - return item; - } - DataStream* str = GetResource( resname, IE_ITM_CLASS_ID ); - PluginHolder sm(IE_ITM_CLASS_ID); - if (!sm) { - delete ( str ); - return NULL; - } - if (!sm->Open(str)) { - return NULL; - } - - item = new Item(); - //this is required for storing the 'source' - strnlwrcpy(item->Name, resname, 8); - sm->GetItem( item ); - if (item == NULL) { - return NULL; - } - - ItemCache.SetAt(resname, (void *) item); - return item; -} - -//you can supply name for faster access -void GameData::FreeItem(Item const *itm, const ieResRef name, bool free) -{ - int res; - - res=ItemCache.DecRef((void *) itm, name, free); - if (res<0) { - error("Core", "Corrupted Item cache encountered (reference count went below zero), Item name is: %.8s\n", name); - } - if (res) return; - if (free) delete itm; -} - -Spell* GameData::GetSpell(const ieResRef resname, bool silent) -{ - Spell *spell = (Spell *) SpellCache.GetResource(resname); - if (spell) { - return spell; - } - DataStream* str = GetResource( resname, IE_SPL_CLASS_ID, silent ); - PluginHolder sm(IE_SPL_CLASS_ID); - if (!sm) { - delete ( str ); - return NULL; - } - if (!sm->Open(str)) { - return NULL; - } - - spell = new Spell(); - //this is required for storing the 'source' - strnlwrcpy(spell->Name, resname, 8); - sm->GetSpell( spell, silent ); - if (spell == NULL) { - return NULL; - } - - SpellCache.SetAt(resname, (void *) spell); - return spell; -} - -void GameData::FreeSpell(Spell *spl, const ieResRef name, bool free) -{ - int res; - - res=SpellCache.DecRef((void *) spl, name, free); - if (res<0) { - printMessage("Core", "Corrupted Spell cache encountered (reference count went below zero), Spell name is: %.8s or %.8s\n", LIGHT_RED, - name, spl->Name); - abort(); - } - if (res) return; - if (free) delete spl; -} - -Effect* GameData::GetEffect(const ieResRef resname) -{ - Effect *effect = (Effect *) EffectCache.GetResource(resname); - if (effect) { - return effect; - } - DataStream* str = GetResource( resname, IE_EFF_CLASS_ID ); - PluginHolder em(IE_EFF_CLASS_ID); - if (!em) { - delete ( str ); - return NULL; - } - if (!em->Open(str)) { - return NULL; - } - - effect = em->GetEffect(new Effect() ); - if (effect == NULL) { - return NULL; - } - - EffectCache.SetAt(resname, (void *) effect); - return effect; -} - -void GameData::FreeEffect(Effect *eff, const ieResRef name, bool free) -{ - int res; - - res=EffectCache.DecRef((void *) eff, name, free); - if (res<0) { - error("Core", "Corrupted Effect cache encountered (reference count went below zero), Effect name is: %.8s\n", name); - } - if (res) return; - if (free) delete eff; -} - -//if the default setup doesn't fit for an animation -//create a vvc for it! -ScriptedAnimation* GameData::GetScriptedAnimation( const char *effect, bool doublehint) -{ - ScriptedAnimation *ret = NULL; - - if (Exists( effect, IE_VVC_CLASS_ID, true ) ) { - DataStream *ds = GetResource( effect, IE_VVC_CLASS_ID ); - ret = new ScriptedAnimation(ds); - } else { - AnimationFactory *af = (AnimationFactory *) - GetFactoryResource( effect, IE_BAM_CLASS_ID, IE_NORMAL ); - if (af) { - ret = new ScriptedAnimation(); - ret->LoadAnimationFactory( af, doublehint?2:0); - } - } - if (ret) { - strnlwrcpy(ret->ResName, effect, 8); - } - return ret; -} - -// Return single BAM frame as a sprite. Use if you want one frame only, -// otherwise it's not efficient -Sprite2D* GameData::GetBAMSprite(const ieResRef ResRef, int cycle, int frame) -{ - Sprite2D *tspr; - AnimationFactory* af = ( AnimationFactory* ) - GetFactoryResource( ResRef, IE_BAM_CLASS_ID, IE_NORMAL ); - if (!af) return 0; - if (cycle == -1) - tspr = af->GetFrameWithoutCycle( (unsigned short) frame ); - else - tspr = af->GetFrame( (unsigned short) frame, (unsigned char) cycle ); - return tspr; -} - -void* GameData::GetFactoryResource(const char* resname, SClass_ID type, - unsigned char mode, bool silent) -{ - int fobjindex = factory->IsLoaded(resname,type); - // already cached - if ( fobjindex != -1) - return factory->GetFactoryObject( fobjindex ); - - // empty resref - if (!strcmp(resname, "")) - return NULL; - - switch (type) { - case IE_BAM_CLASS_ID: - { - DataStream* ret = GetResource( resname, type, silent ); - if (ret) { - PluginHolder ani(IE_BAM_CLASS_ID); - if (!ani) - return NULL; - if (!ani->Open(ret)) - return NULL; - AnimationFactory* af = ani->GetAnimationFactory( resname, mode ); - factory->AddFactoryObject( af ); - return af; - } - return NULL; - } - case IE_BMP_CLASS_ID: - { - ResourceHolder img(resname); - if (img) { - ImageFactory* fact = img->GetImageFactory( resname ); - factory->AddFactoryObject( fact ); - return fact; - } - - return NULL; - } - default: - print( "\n" ); - printMessage("KEYImporter", "%s files are not supported.\n", WHITE, - core->TypeExt(type)); - return NULL; - } -} - -Store* GameData::GetStore(const ieResRef ResRef) -{ - StoreMap::iterator it = stores.find(ResRef); - if (it != stores.end()) { - return it->second; - } - - DataStream* str = gamedata->GetResource(ResRef, IE_STO_CLASS_ID); - PluginHolder sm(IE_STO_CLASS_ID); - if (sm == NULL) { - delete ( str ); - return NULL; - } - if (!sm->Open(str)) { - return NULL; - } - - Store* store = sm->GetStore(new Store()); - if (store == NULL) { - return NULL; - } - strnlwrcpy(store->Name, ResRef, 8); - // The key needs to last as long as the store, - // so use the one we just copied. - stores[store->Name] = store; - return store; -} - -void GameData::SaveStore(Store* store) -{ - if (!store) - return; - StoreMap::iterator it = stores.find(store->Name); - if (it == stores.end()) { - error("GameData", "Saving a store that wasn't cached."); - } - - PluginHolder sm(IE_STO_CLASS_ID); - if (sm == NULL) { - error("GameData", "Can't save store to cache."); - } - - FileStream str; - - if (!str.Create(store->Name, IE_STO_CLASS_ID)) { - error("GameData", "Can't create file while saving store."); - } - if (!sm->PutStore(&str, store)) { - error("GameData", "Error saving store."); - } - - stores.erase(it); - delete store; -} - -void GameData::SaveAllStores() -{ - while (!stores.empty()) { - SaveStore(stores.begin()->second); - } -} diff --git a/project/jni/application/gemrb/gemrb/core/GameData.h b/project/jni/application/gemrb/gemrb/core/GameData.h deleted file mode 100644 index 30c9aaf68..000000000 --- a/project/jni/application/gemrb/gemrb/core/GameData.h +++ /dev/null @@ -1,138 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#ifndef GAMEDATA_H -#define GAMEDATA_H - -#include "SClassID.h" -#include "exports.h" -#include "ie_types.h" -#include "iless.h" - -#include "Cache.h" -#include "Holder.h" -#include "ResourceManager.h" - -#include -#include - -#ifdef _MSC_VER // No SFINAE -#include "TableMgr.h" -#endif - -class Actor; -struct Effect; -class Factory; -class Item; -class Palette; -class ScriptedAnimation; -class Spell; -class Sprite2D; -class TableMgr; -class Store; - -struct Table { - Holder tm; - char ResRef[8]; - unsigned int refcount; -}; - -class GEM_EXPORT GameData : public ResourceManager -{ -public: - GameData(); - ~GameData(); - - void ClearCaches(); - - /** Returns actor */ - Actor *GetCreature(const char *ResRef, unsigned int PartySlot=0); - /** Returns a PC index, by loading a creature */ - int LoadCreature(const char *ResRef, unsigned int PartySlot, bool character=false, int VersionOverride=-1); - - - // 2DA table functions. - // (See also the AutoTable class) - - /** Loads a 2DA Table, returns -1 on error or the Table Index on success */ - int LoadTable(const char * ResRef); - /** Gets the index of a loaded table, returns -1 on error */ - int GetTableIndex(const char * ResRef) const; - /** Gets a Loaded Table by its index, returns NULL on error */ - Holder GetTable(unsigned int index) const; - /** Frees a Loaded Table, returns false on error, true on success */ - bool DelTable(unsigned int index); - - Palette* GetPalette(const ieResRef resname); - void FreePalette(Palette *&pal, const ieResRef name=NULL); - - Item* GetItem(const ieResRef resname); - void FreeItem(Item const *itm, const ieResRef name, bool free=false); - Spell* GetSpell(const ieResRef resname, bool silent=false); - void FreeSpell(Spell *spl, const ieResRef name, bool free=false); - Effect* GetEffect(const ieResRef resname); - void FreeEffect(Effect *eff, const ieResRef name, bool free=false); - - /** creates a vvc/bam animation object at point */ - ScriptedAnimation* GetScriptedAnimation( const char *ResRef, bool doublehint); - - /** returns a single sprite (not cached) from a BAM resource */ - Sprite2D* GetBAMSprite(const ieResRef ResRef, int cycle, int frame); - - /** returns factory resource, currently works only with animations */ - void* GetFactoryResource(const char* resname, SClass_ID type, - unsigned char mode = IE_NORMAL, bool silent=false); - - Store* GetStore(const ieResRef ResRef); - /// Saves a store to the cache and frees it. - void SaveStore(Store* store); - /// Saves all stores in the cache - void SaveAllStores(); -private: - Cache ItemCache; - Cache SpellCache; - Cache EffectCache; - Cache PaletteCache; - Factory* factory; - std::vector tables; - typedef std::map StoreMap; - StoreMap stores; -}; - -extern GEM_EXPORT GameData * gamedata; - -template -class ResourceHolder : public Holder -{ -public: - ResourceHolder() - { - } - ResourceHolder(const char* resname) - : Holder(static_cast(gamedata->GetResource(resname,&T::ID))) - { - } - ResourceHolder(const char* resname, const ResourceManager& manager, bool silent = false) - : Holder(static_cast(manager.GetResource(resname,&T::ID,silent))) - { - } -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/GameScript/Actions.cpp b/project/jni/application/gemrb/gemrb/core/GameScript/Actions.cpp deleted file mode 100644 index 89c11ddf6..000000000 --- a/project/jni/application/gemrb/gemrb/core/GameScript/Actions.cpp +++ /dev/null @@ -1,7243 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003-2007 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "GameScript/GameScript.h" - -#include "GameScript/GSUtils.h" -#include "GameScript/Matching.h" - -#include "win32def.h" - -#include "AmbientMgr.h" -#include "Audio.h" -#include "CharAnimations.h" -#include "DataFileMgr.h" -#include "DialogHandler.h" -#include "DisplayMessage.h" -#include "Game.h" -#include "GameData.h" -#include "GlobalTimer.h" -#include "IniSpawn.h" -#include "Item.h" -#include "Map.h" -#include "MusicMgr.h" -#include "SaveGameIterator.h" -#include "ScriptEngine.h" -#include "TileMap.h" -#include "Video.h" -#include "WorldMap.h" -#include "GUI/GameControl.h" -#include "GUI/EventMgr.h" -#include "Scriptable/Container.h" -#include "Scriptable/Door.h" -#include "Scriptable/InfoPoint.h" - -//------------------------------------------------------------ -// Action Functions -//------------------------------------------------------------- - -void GameScript::SetExtendedNight(Scriptable* Sender, Action* parameters) -{ - Map *map=Sender->GetCurrentArea(); - //sets the 'can rest other' bit - if (parameters->int0Parameter) { - map->AreaType|=AT_EXTENDED_NIGHT; - } else { - map->AreaType&=~AT_EXTENDED_NIGHT; - } -} - -void GameScript::SetAreaRestFlag(Scriptable* Sender, Action* parameters) -{ - Map *map=Sender->GetCurrentArea(); - //sets the 'can rest other' bit - if (parameters->int0Parameter) { - map->AreaType|=AT_CAN_REST; - } else { - map->AreaType&=~AT_CAN_REST; - } -} - -void GameScript::AddAreaFlag(Scriptable* Sender, Action* parameters) -{ - Map *map=Sender->GetCurrentArea(); - map->AreaFlags|=parameters->int0Parameter; -} - -void GameScript::RemoveAreaFlag(Scriptable* Sender, Action* parameters) -{ - Map *map=Sender->GetCurrentArea(); - map->AreaFlags&=~parameters->int0Parameter; -} - -void GameScript::SetAreaFlags(Scriptable* Sender, Action* parameters) -{ - Map *map=Sender->GetCurrentArea(); - ieDword value = map->AreaFlags; - HandleBitMod( value, parameters->int0Parameter, parameters->int1Parameter); - map->AreaFlags=value; -} - -void GameScript::AddAreaType(Scriptable* Sender, Action* parameters) -{ - Map *map=Sender->GetCurrentArea(); - map->AreaType|=parameters->int0Parameter; -} - -void GameScript::RemoveAreaType(Scriptable* Sender, Action* parameters) -{ - Map *map=Sender->GetCurrentArea(); - map->AreaType&=~parameters->int0Parameter; -} - -void GameScript::NoActionAtAll(Scriptable* /*Sender*/, Action* /*parameters*/) -{ - //thats all :) -} - -// this action stops modal actions, so... -void GameScript::NoAction(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor *actor = (Actor *) Sender; - actor->SetModal( MS_NONE); -} - -void GameScript::SG(Scriptable* Sender, Action* parameters) -{ - SetVariable( Sender, parameters->string0Parameter, "GLOBAL", parameters->int0Parameter ); -} - -void GameScript::SetGlobal(Scriptable* Sender, Action* parameters) -{ - SetVariable( Sender, parameters->string0Parameter, parameters->int0Parameter ); -} - -void GameScript::SetGlobalRandom(Scriptable* Sender, Action* parameters) -{ - int max=parameters->int1Parameter-parameters->int0Parameter+1; - if (max>0) { - SetVariable( Sender, parameters->string0Parameter, RandomNumValue%max+parameters->int0Parameter ); - } else { - SetVariable( Sender, parameters->string0Parameter, 0); - } -} - -void GameScript::StartTimer(Scriptable* Sender, Action* parameters) -{ - Sender->StartTimer(parameters->int0Parameter, parameters->int1Parameter); -} - -void GameScript::StartRandomTimer(Scriptable* Sender, Action* parameters) -{ - ieDword value = core->Roll(1, parameters->int2Parameter-parameters->int1Parameter, parameters->int2Parameter-1); - Sender->StartTimer(parameters->int0Parameter, value); -} - -void GameScript::SetGlobalTimer(Scriptable* Sender, Action* parameters) -{ - ieDword mytime; - - mytime=core->GetGame()->GameTime; //gametime (should increase it) - SetVariable( Sender, parameters->string0Parameter, - parameters->int0Parameter*AI_UPDATE_TIME + mytime); -} - -void GameScript::SetGlobalTimerRandom(Scriptable* Sender, Action* parameters) -{ - ieDword mytime; - int random; - - //This works both ways in the original engine - if (parameters->int1Parameter>parameters->int0Parameter) { - random = parameters->int1Parameter-parameters->int0Parameter+1; - //random cannot be 0, its minimal value is 1 - random = RandomNumValue % random + parameters->int0Parameter; - } else { - random = parameters->int0Parameter-parameters->int1Parameter+1; - random = RandomNumValue % random + parameters->int1Parameter; - } - mytime=core->GetGame()->GameTime; //gametime (should increase it) - SetVariable( Sender, parameters->string0Parameter, random*AI_UPDATE_TIME + mytime); -} - -void GameScript::SetGlobalTimerOnce(Scriptable* Sender, Action* parameters) -{ - ieDword mytime = CheckVariable( Sender, parameters->string0Parameter ); - if (mytime != 0) { - return; - } - mytime=core->GetGame()->GameTime; //gametime (should increase it) - SetVariable( Sender, parameters->string0Parameter, - parameters->int0Parameter*AI_UPDATE_TIME + mytime); -} - -void GameScript::RealSetGlobalTimer(Scriptable* Sender, Action* parameters) -{ - ieDword mytime=core->GetGame()->RealTime; - - SetVariable( Sender, parameters->string0Parameter, - parameters->int0Parameter*AI_UPDATE_TIME + mytime); -} - -void GameScript::ChangeAllegiance(Scriptable* Sender, Action* parameters) -{ - Scriptable *scr = Sender; - if (parameters->objects[1]) { - scr=GetActorFromObject( Sender, parameters->objects[1] ); - } - if (!scr || scr->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) scr; - actor->SetBase( IE_EA, parameters->int0Parameter ); -} - -void GameScript::ChangeGeneral(Scriptable* Sender, Action* parameters) -{ - Scriptable *scr = Sender; - if (parameters->objects[1]) { - scr=GetActorFromObject( Sender, parameters->objects[1] ); - } - if (!scr || scr->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) scr; - actor->SetBase( IE_GENERAL, parameters->int0Parameter ); -} - -void GameScript::ChangeRace(Scriptable* Sender, Action* parameters) -{ - Scriptable *scr = Sender; - if (parameters->objects[1]) { - scr=GetActorFromObject( Sender, parameters->objects[1] ); - } - if (!scr || scr->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) scr; - actor->SetBase( IE_RACE, parameters->int0Parameter ); -} - -void GameScript::ChangeClass(Scriptable* Sender, Action* parameters) -{ - Scriptable *scr = Sender; - if (parameters->objects[1]) { - scr=GetActorFromObject( Sender, parameters->objects[1] ); - } - if (!scr || scr->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) scr; - actor->SetBase( IE_CLASS, parameters->int0Parameter ); -} - -void GameScript::SetNamelessClass(Scriptable* /*Sender*/, Action* parameters) -{ - //same as Protagonist - Actor* actor = core->GetGame()->GetPC(0, false); - actor->SetBase( IE_CLASS, parameters->int0Parameter ); -} - -void GameScript::SetNamelessDisguise(Scriptable* Sender, Action* parameters) -{ - SetVariable(Sender, "APPEARANCE", "GLOBAL", parameters->int0Parameter); - core->SetEventFlag(EF_UPDATEANIM); -} - -void GameScript::ChangeSpecifics(Scriptable* Sender, Action* parameters) -{ - Scriptable *scr = Sender; - if (parameters->objects[1]) { - scr=GetActorFromObject( Sender, parameters->objects[1] ); - } - if (!scr || scr->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) scr; - actor->SetBase( IE_SPECIFIC, parameters->int0Parameter ); -} - -void GameScript::PermanentStatChange(Scriptable* Sender, Action* parameters) -{ - Scriptable *scr = Sender; - if (parameters->objects[1]) { - scr=GetActorFromObject( Sender, parameters->objects[1] ); - } - if (!scr || scr->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) scr; - ieDword value; - switch (parameters->int1Parameter) { - case 1: - value = actor->GetBase(parameters->int0Parameter); - value-= parameters->int2Parameter; - break; - case 2: - value = actor->GetBase(parameters->int0Parameter); - value+= parameters->int2Parameter; - break; - case 3: - default: //no idea what happens - value = parameters->int2Parameter; - break; - } - actor->SetBase( parameters->int0Parameter, value); -} - -void GameScript::ChangeStat(Scriptable* Sender, Action* parameters) -{ - Scriptable *scr = Sender; - if (parameters->objects[1]) { - scr=GetActorFromObject( Sender, parameters->objects[1] ); - } - if (!scr || scr->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) scr; - ieDword value = parameters->int1Parameter; - if (parameters->int2Parameter==1) { - value+=actor->GetBase(parameters->int0Parameter); - } - actor->SetBase( parameters->int0Parameter, value); -} - -void GameScript::ChangeStatGlobal(Scriptable* Sender, Action* parameters) -{ - Scriptable *scr = Sender; - if (parameters->objects[1]) { - scr=GetActorFromObject( Sender, parameters->objects[1] ); - } - if (!scr || scr->Type != ST_ACTOR) { - return; - } - ieDword value = (ieDword) CheckVariable( Sender, parameters->string0Parameter, parameters->string1Parameter ); - Actor* actor = ( Actor* ) scr; - if (parameters->int1Parameter==1) { - value+=actor->GetBase(parameters->int0Parameter); - } - actor->SetBase( parameters->int0Parameter, value); -} - -void GameScript::ChangeGender(Scriptable* Sender, Action* parameters) -{ - Scriptable *scr = Sender; - if (parameters->objects[1]) { - scr=GetActorFromObject( Sender, parameters->objects[1] ); - } - if (!scr || scr->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) scr; - actor->SetBase( IE_SEX, parameters->int0Parameter ); -} - -void GameScript::ChangeAlignment(Scriptable* Sender, Action* parameters) -{ - Scriptable *scr = Sender; - if (parameters->objects[1]) { - scr=GetActorFromObject( Sender, parameters->objects[1] ); - } - if (!scr || scr->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) scr; - actor->SetBase( IE_ALIGNMENT, parameters->int0Parameter ); -} - -void GameScript::SetFaction(Scriptable* Sender, Action* parameters) -{ - Scriptable *scr = Sender; - if (parameters->objects[1]) { - scr=GetActorFromObject( Sender, parameters->objects[1] ); - } - if (!scr || scr->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) scr; - actor->SetBase( IE_FACTION, parameters->int0Parameter ); -} - -void GameScript::SetHP(Scriptable* Sender, Action* parameters) -{ - Scriptable *scr = Sender; - if (parameters->objects[1]) { - scr=GetActorFromObject( Sender, parameters->objects[1] ); - } - if (!scr || scr->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) scr; - actor->SetBase( IE_HITPOINTS, parameters->int0Parameter ); -} - -void GameScript::SetHPPercent(Scriptable* Sender, Action* parameters) -{ - Scriptable *scr = Sender; - if (parameters->objects[1]) { - scr=GetActorFromObject( Sender, parameters->objects[1] ); - } - if (!scr || scr->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) scr; - actor->NewBase( IE_HITPOINTS, parameters->int0Parameter, MOD_PERCENT); -} - -void GameScript::AddHP(Scriptable* Sender, Action* parameters) -{ - Scriptable *scr = Sender; - if (parameters->objects[1]) { - scr=GetActorFromObject( Sender, parameters->objects[1] ); - } - if (!scr || scr->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) scr; - actor->NewBase(IE_HITPOINTS, parameters->int0Parameter, MOD_ADDITIVE); -} - -//this works on an object (pst) -//but can also work on actor itself (gemrb) -void GameScript::SetTeam(Scriptable* Sender, Action* parameters) -{ - Scriptable *scr = Sender; - if (parameters->objects[1]) { - scr=GetActorFromObject( Sender, parameters->objects[1] ); - } - if (!scr || scr->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) scr; - actor->SetBase( IE_TEAM, parameters->int0Parameter ); -} - -//this works on an object (gemrb) -//or on Myself if object isn't given (iwd2) -void GameScript::SetTeamBit(Scriptable* Sender, Action* parameters) -{ - Scriptable *scr = Sender; - if (parameters->objects[1]) { - scr=GetActorFromObject( Sender, parameters->objects[1] ); - } - if (!scr || scr->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) scr; - if (parameters->int1Parameter) { - actor->SetBase( IE_TEAM, actor->GetStat(IE_TEAM) | parameters->int0Parameter ); - } else { - actor->SetBase( IE_TEAM, actor->GetStat(IE_TEAM) & ~parameters->int0Parameter ); - } -} - -void GameScript::TriggerActivation(Scriptable* Sender, Action* parameters) -{ - Scriptable* ip; - - if (!parameters->objects[1]) { - ip=Sender; - } else { - ip = Sender->GetCurrentArea()->TMap->GetInfoPoint(parameters->objects[1]->objectName); - } - if (!ip || (ip->Type!=ST_TRIGGER && ip->Type!=ST_TRAVEL && ip->Type!=ST_PROXIMITY)) { - print("Script error: No Trigger Named \"%s\"\n", parameters->objects[1]->objectName); - return; - } - InfoPoint *trigger = (InfoPoint *) ip; - if ( parameters->int0Parameter != 0 ) { - trigger->Flags &= ~TRAP_DEACTIVATED; - } else { - trigger->Flags |= TRAP_DEACTIVATED; - } -} - -void GameScript::FadeToColor(Scriptable* Sender, Action* parameters) -{ - core->timer->SetFadeToColor( parameters->pointParameter.x ); -// Sender->SetWait( parameters->pointParameter.x ); - Sender->ReleaseCurrentAction(); // todo, blocking? -} - -void GameScript::FadeFromColor(Scriptable* Sender, Action* parameters) -{ - core->timer->SetFadeFromColor( parameters->pointParameter.x ); -// Sender->SetWait( parameters->pointParameter.x ); - Sender->ReleaseCurrentAction(); // todo, blocking? -} - -void GameScript::FadeToAndFromColor(Scriptable* Sender, Action* parameters) -{ - core->timer->SetFadeToColor( parameters->pointParameter.x ); - core->timer->SetFadeFromColor( parameters->pointParameter.x ); -// Sender->SetWait( parameters->pointParameter.x<<1 ); //multiply by 2 - Sender->ReleaseCurrentAction(); // todo, blocking? -} - -void GameScript::JumpToPoint(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - Actor* ab = ( Actor* ) Sender; - ab->SetPosition( parameters->pointParameter, true ); -} - -void GameScript::JumpToPointInstant(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type != ST_ACTOR) { - return; - } - Actor* ab = ( Actor* ) tar; - ab->SetPosition( parameters->pointParameter, true ); -} - -/** instant jump to location saved in stats */ -/** default subject is the current actor */ -void GameScript::JumpToSavedLocation(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - tar = Sender; - } - if (tar->Type != ST_ACTOR) { - return; - } - Actor *actor = (Actor *) tar; - Point p((short) actor->GetStat(IE_SAVEDXPOS), (short) actor->GetStat(IE_SAVEDYPOS) ); - actor->SetPosition(p, true ); - actor->SetOrientation( actor->GetStat(IE_SAVEDFACE), false ); -} - -void GameScript::JumpToObject(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - - if (!tar) { - return; - } - const Map *map = tar->GetCurrentArea(); - - if (map) { - if (parameters->string0Parameter[0]) { - CreateVisualEffectCore(Sender, Sender->Pos, parameters->string0Parameter, 0); - } - MoveBetweenAreasCore( (Actor *) Sender, map->GetScriptName(), tar->Pos, -1, true); - } -} - -void GameScript::TeleportParty(Scriptable* /*Sender*/, Action* parameters) -{ - Game *game = core->GetGame(); - int i = game->GetPartySize(false); - while (i--) { - Actor *tar = game->GetPC(i, false); - MoveBetweenAreasCore( tar, parameters->string0Parameter, - parameters->pointParameter, -1, true); - } -} - -//5 is the ToB value, but it might be useful to have multiple expansions -void GameScript::MoveToExpansion(Scriptable* Sender, Action* parameters) -{ - Game *game = core->GetGame(); - - if (!parameters->int0Parameter) { - parameters->int0Parameter = 5; - } - game->SetExpansion(parameters->int0Parameter); - Sender->ReleaseCurrentAction(); -} - -//add some animation effects too? -void GameScript::ExitPocketPlane(Scriptable* /*Sender*/, Action* /*parameters*/) -{ - Game *game = core->GetGame(); - for (int i = 0; i < game->GetPartySize(false); i++) { - Actor* act = game->GetPC( i, false ); - if (act) { - if (game->GetPlaneLocationCount() <= (unsigned int)i) { - // what are we meant to do here? - print("argh, couldn't restore party member %d!", i + 1); - continue; - } - GAMLocationEntry *gle = game->GetPlaneLocationEntry(i); - MoveBetweenAreasCore(act, gle->AreaResRef, gle->Pos, -1, true); - } - } - - // don't clear locations! -} - -//moves pcs and npcs from an area to another area -void GameScript::MoveGlobalsTo(Scriptable* /*Sender*/, Action* parameters) -{ - Game *game = core->GetGame(); - int i = game->GetPartySize(false); - while (i--) { - Actor *tar = game->GetPC(i, false); - //if the actor isn't in the area, we don't care - if (strnicmp(tar->Area, parameters->string0Parameter,8) ) { - continue; - } - MoveBetweenAreasCore( tar, parameters->string1Parameter, - parameters->pointParameter, -1, true); - } - i = game->GetNPCCount(); - while (i--) { - Actor *tar = game->GetNPC(i); - //if the actor isn't in the area, we don't care - if (strnicmp(tar->Area, parameters->string0Parameter,8) ) { - continue; - } - MoveBetweenAreasCore( tar, parameters->string1Parameter, - parameters->pointParameter, -1, true); - } -} - -void GameScript::MoveGlobal(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type != ST_ACTOR) { - return; - } - - MoveBetweenAreasCore( (Actor *) tar, parameters->string0Parameter, - parameters->pointParameter, -1, true); -} - -//we also allow moving to door, container -void GameScript::MoveGlobalObject(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type != ST_ACTOR) { - return; - } - Scriptable* to = GetActorFromObject( Sender, parameters->objects[2] ); - if (!to) { - return; - } - const Map *map = to->GetCurrentArea(); - - if (map) { - MoveBetweenAreasCore( (Actor *) tar, map->GetScriptName(), - to->Pos, -1, true); - } -} - -void GameScript::MoveGlobalObjectOffScreen(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type != ST_ACTOR) { - return; - } - Scriptable* to = GetActorFromObject( Sender, parameters->objects[2] ); - if (!to) { - return; - } - MoveBetweenAreasCore( (Actor *) tar, parameters->string0Parameter, - to->Pos, -1, false); -} - -//don't use offset from Sender -void GameScript::CreateCreature(Scriptable* Sender, Action* parameters) -{ - CreateCreatureCore( Sender, parameters, CC_CHECK_IMPASSABLE|CC_CHECK_OVERLAP|CC_SCRIPTNAME ); -} - -//another highly redundant action -void GameScript::CreateCreatureDoor(Scriptable* Sender, Action* parameters) -{ - //we hack this to death - strcpy(parameters->string1Parameter, "SPDIMNDR"); - CreateCreatureCore( Sender, parameters, CC_CHECK_IMPASSABLE|CC_CHECK_OVERLAP | CC_PLAY_ANIM ); -} - -//another highly redundant action -void GameScript::CreateCreatureObjectDoor(Scriptable* Sender, Action* parameters) -{ - //we hack this to death - strcpy(parameters->string1Parameter, "SPDIMNDR"); - CreateCreatureCore( Sender, parameters, CC_OBJECT | CC_CHECK_IMPASSABLE|CC_CHECK_OVERLAP | CC_PLAY_ANIM ); -} - -//don't use offset from Sender -void GameScript::CreateCreatureImpassable(Scriptable* Sender, Action* parameters) -{ - CreateCreatureCore( Sender, parameters, CC_CHECK_OVERLAP ); -} - -void GameScript::CreateCreatureImpassableAllowOverlap(Scriptable* Sender, Action* parameters) -{ - CreateCreatureCore( Sender, parameters, 0 ); -} - -//use offset from Sender -void GameScript::CreateCreatureAtFeet(Scriptable* Sender, Action* parameters) -{ - CreateCreatureCore( Sender, parameters, CC_OFFSET | CC_CHECK_IMPASSABLE | CC_CHECK_OVERLAP); -} - -void GameScript::CreateCreatureOffScreen(Scriptable* Sender, Action* parameters) -{ - CreateCreatureCore( Sender, parameters, CC_OFFSCREEN | CC_CHECK_IMPASSABLE | CC_CHECK_OVERLAP ); -} - -//creates copy at actor, plays animation -void GameScript::CreateCreatureObjectCopy(Scriptable* Sender, Action* parameters) -{ - CreateCreatureCore( Sender, parameters, CC_OBJECT | CC_CHECK_IMPASSABLE | CC_CHECK_OVERLAP | CC_COPY | CC_PLAY_ANIM ); -} - -//creates copy at absolute point -void GameScript::CreateCreatureCopyPoint(Scriptable* Sender, Action* parameters) -{ - CreateCreatureCore( Sender, parameters, CC_CHECK_IMPASSABLE | CC_CHECK_OVERLAP | CC_COPY | CC_PLAY_ANIM ); -} - -//this is the same, object + offset -//using this for simple createcreatureobject, (0 offsets) -//createcreatureobjecteffect may have animation -void GameScript::CreateCreatureObjectOffset(Scriptable* Sender, Action* parameters) -{ - CreateCreatureCore( Sender, parameters, CC_OBJECT | CC_CHECK_IMPASSABLE | CC_CHECK_OVERLAP | CC_PLAY_ANIM); -} - -void GameScript::CreateCreatureObjectOffScreen(Scriptable* Sender, Action* parameters) -{ - CreateCreatureCore( Sender, parameters, CC_OFFSCREEN | CC_OBJECT | CC_CHECK_IMPASSABLE | CC_CHECK_OVERLAP ); -} - -//I think this simply removes the cursor and hides the gui without disabling scripts -//See Interface::SetCutSceneMode -void GameScript::SetCursorState(Scriptable* /*Sender*/, Action* parameters) -{ - int active = parameters->int0Parameter; - - Game *game = core->GetGame(); - if (active) { - game->ControlStatus |= CS_HIDEGUI; - } else { - game->ControlStatus &= ~CS_HIDEGUI; - } - core->SetEventFlag(EF_CONTROL); - core->GetVideoDriver()->SetMouseEnabled(!active); -} - -void GameScript::StartCutSceneMode(Scriptable* /*Sender*/, Action* /*parameters*/) -{ - core->SetCutSceneMode( true ); -} - -void GameScript::EndCutSceneMode(Scriptable* /*Sender*/, Action* /*parameters*/) -{ - core->SetCutSceneMode( false ); -} - -void GameScript::StartCutScene(Scriptable* Sender, Action* parameters) -{ - GameScript* gs = new GameScript( parameters->string0Parameter, Sender ); - gs->EvaluateAllBlocks(); - delete( gs ); -} - -void GameScript::CutSceneID(Scriptable* /*Sender*/, Action* /*parameters*/) -{ - // shouldn't get called - printMessage("GameScript","CutSceneID was called!\n",YELLOW); -} - -void GameScript::Enemy(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) Sender; - actor->SetBase( IE_EA, EA_ENEMY ); -} - -void GameScript::Ally(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) Sender; - actor->SetBase( IE_EA, EA_ALLY ); -} - -/** GemRB extension: you can replace baldur.bcs */ -void GameScript::ChangeAIScript(Scriptable* Sender, Action* parameters) -{ - 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; - //clearing the queue, and checking script level was intentionally removed - actor->SetScript( parameters->string0Parameter, parameters->int0Parameter, false ); -} - -void GameScript::SetPlayerSound(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) tar; - actor->StrRefs[parameters->int0Parameter]=parameters->int1Parameter; -} - -//this one works only on real actors, they got constants -void GameScript::VerbalConstantHead(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type != ST_ACTOR) { - return; - } - DisplayStringCore( tar, parameters->int0Parameter, DS_HEAD|DS_CONSOLE|DS_CONST); -} - -void GameScript::VerbalConstant(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type != ST_ACTOR) { - return; - } - DisplayStringCore( tar, parameters->int0Parameter, DS_CONSOLE|DS_CONST); -} - -//bg2 - variable -void GameScript::SaveLocation(Scriptable* Sender, Action* parameters) -{ - ieDword value = parameters->pointParameter.asDword(); - if (!parameters->string0Parameter[0]) { - strcpy(parameters->string0Parameter,"LOCALSsavedlocation"); - } - SetVariable(Sender, parameters->string0Parameter, value); -} - -//PST:has parameters, IWD2: no params -void GameScript::SetSavedLocation(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor *actor = (Actor *) Sender; - //iwd2 - if (parameters->pointParameter.isnull()) { - actor->SetBase(IE_SAVEDXPOS, actor->Pos.x); - actor->SetBase(IE_SAVEDYPOS, actor->Pos.y); - actor->SetBase(IE_SAVEDFACE, actor->GetOrientation()); - return; - } - //pst - actor->SetBase(IE_SAVEDXPOS, parameters->pointParameter.x); - actor->SetBase(IE_SAVEDYPOS, parameters->pointParameter.y); - actor->SetBase(IE_SAVEDFACE, parameters->int0Parameter); -} -//IWD2, sets the homepoint int0,int1,int2 -void GameScript::SetSavedLocationPoint(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor *actor = (Actor *) Sender; - actor->SetBase(IE_SAVEDXPOS, parameters->int0Parameter); - actor->SetBase(IE_SAVEDYPOS, parameters->int1Parameter); - actor->SetBase(IE_SAVEDFACE, parameters->int2Parameter); -} -//IWD2, sets the homepoint P -void GameScript::SetStartPos(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor *actor = (Actor *) Sender; - actor->SetBase(IE_SAVEDXPOS, parameters->pointParameter.x); - actor->SetBase(IE_SAVEDYPOS, parameters->pointParameter.y); - actor->SetBase(IE_SAVEDFACE, parameters->int0Parameter); -} - -void GameScript::SaveObjectLocation(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - return; - } - ieDword value = tar->Pos.asDword(); - if (!parameters->string0Parameter[0]) { - strcpy(parameters->string0Parameter,"LOCALSsavedlocation"); - } - SetVariable(Sender, parameters->string0Parameter, value); -} - -/** you may omit the string0Parameter, in this case this will be a */ -/** CreateCreatureAtSavedLocation */ -void GameScript::CreateCreatureAtLocation(Scriptable* Sender, Action* parameters) -{ - if (!parameters->string0Parameter[0]) { - strcpy(parameters->string0Parameter,"LOCALSsavedlocation"); - } - ieDword value = CheckVariable(Sender, parameters->string0Parameter); - parameters->pointParameter.y = (ieWord) (value & 0xffff); - parameters->pointParameter.x = (ieWord) (value >> 16); - CreateCreatureCore(Sender, parameters, CC_CHECK_IMPASSABLE|CC_STRING1); -} - -void GameScript::WaitRandom(Scriptable* Sender, Action* parameters) -{ - if (!Sender->CurrentActionState) { - int width = parameters->int1Parameter-parameters->int0Parameter; - if (width<2) { - width = parameters->int0Parameter; - } else { - width = rand() % width + parameters->int0Parameter; - } - Sender->CurrentActionState = width * AI_UPDATE_TIME; - } else { - Sender->CurrentActionState--; - } - - if (!Sender->CurrentActionState) { - Sender->ReleaseCurrentAction(); - } - - assert(Sender->CurrentActionState >= 0); -} - -void GameScript::Wait(Scriptable* Sender, Action* parameters) -{ - if (!Sender->CurrentActionState) { - Sender->CurrentActionState = parameters->int0Parameter * AI_UPDATE_TIME; - } else { - Sender->CurrentActionState--; - } - - if (!Sender->CurrentActionState) { - Sender->ReleaseCurrentAction(); - } - - assert(Sender->CurrentActionState >= 0); -} - -void GameScript::SmallWait(Scriptable* Sender, Action* parameters) -{ - if (!Sender->CurrentActionState) { - Sender->CurrentActionState = parameters->int0Parameter; - } else { - Sender->CurrentActionState--; - } - - if (!Sender->CurrentActionState) { - Sender->ReleaseCurrentAction(); - } - - assert(Sender->CurrentActionState >= 0); -} - -void GameScript::SmallWaitRandom(Scriptable* Sender, Action* parameters) -{ - if (!Sender->CurrentActionState) { - int random = parameters->int1Parameter - parameters->int0Parameter; - if (random<1) { - random = 1; - } - Sender->CurrentActionState = rand() % random + parameters->int0Parameter; - } else { - Sender->CurrentActionState--; - } - - if (!Sender->CurrentActionState) { - Sender->ReleaseCurrentAction(); - } - - assert(Sender->CurrentActionState >= 0); -} - -void GameScript::MoveViewPoint(Scriptable* Sender, Action* parameters) -{ - core->timer->SetMoveViewPort( parameters->pointParameter.x, parameters->pointParameter.y, parameters->int0Parameter<<1, true ); - Sender->SetWait(1); // todo, blocking? - Sender->ReleaseCurrentAction(); // todo, blocking? -} - -void GameScript::MoveViewObject(Scriptable* Sender, Action* parameters) -{ - Scriptable * scr = GetActorFromObject( Sender, parameters->objects[1]); - if (!scr) { - Sender->ReleaseCurrentAction(); - return; - } - core->timer->SetMoveViewPort( scr->Pos.x, scr->Pos.y, parameters->int0Parameter<<1, true ); - Sender->SetWait(1); // todo, blocking? - Sender->ReleaseCurrentAction(); // todo, blocking? -} - -void GameScript::AddWayPoint(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Actor* actor = ( Actor* ) Sender; - actor->AddWayPoint( parameters->pointParameter ); - // this is marked as AF_BLOCKING (and indeed AddWayPoint causes moves), - // but this probably needs more thought - Sender->ReleaseCurrentAction(); -} - -void GameScript::MoveToPointNoRecticle(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Actor *actor = ( Actor* ) Sender; - if (!actor->InMove() || actor->Destination != parameters->pointParameter) { - actor->WalkTo( parameters->pointParameter, IF_NORECTICLE, 0 ); - } - if (!actor->InMove()) { - // we should probably instead keep retrying until we reach dest - Sender->ReleaseCurrentAction(); - } -} - -void GameScript::MoveToPointNoInterrupt(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Actor* actor = ( Actor* ) Sender; - if (!actor->InMove() || actor->Destination != parameters->pointParameter) { - actor->WalkTo( parameters->pointParameter, IF_NOINT, 0 ); - } - // should we always force IF_NOINT here? - if (!actor->InMove()) { - // we should probably instead keep retrying until we reach dest - actor->Interrupt(); - Sender->ReleaseCurrentAction(); - } -} - -void GameScript::RunToPointNoRecticle(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Actor* actor = ( Actor* ) Sender; - if (!actor->InMove() || actor->Destination != parameters->pointParameter) { - actor->WalkTo( parameters->pointParameter, IF_NORECTICLE|IF_RUNNING, 0 ); - } - if (!actor->InMove()) { - // we should probably instead keep retrying until we reach dest - Sender->ReleaseCurrentAction(); - } -} - -void GameScript::RunToPoint(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Actor* actor = ( Actor* ) Sender; - if (!actor->InMove() || actor->Destination != parameters->pointParameter) { - actor->WalkTo( parameters->pointParameter, IF_RUNNING, 0 ); - } - if (!actor->InMove()) { - // we should probably instead keep retrying until we reach dest - Sender->ReleaseCurrentAction(); - } -} - -//movetopoint until timer is down or target reached -void GameScript::TimedMoveToPoint(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - if (parameters->int0Parameter<=0) { - Sender->ReleaseCurrentAction(); - return; - } - Actor *actor = (Actor *) Sender; - - if (!actor->InMove() || actor->Destination != parameters->pointParameter) { - actor->WalkTo( parameters->pointParameter, parameters->int1Parameter,0 ); - } - - //hopefully this hack will prevent lockups - if (!actor->InMove()) { - // we should probably instead keep retrying until we reach dest - Sender->ReleaseCurrentAction(); - return; - } - - //repeat movement... - if (parameters->int0Parameter>0) { - Action *newaction = ParamCopyNoOverride(parameters); - newaction->int0Parameter--; - actor->AddActionInFront(newaction); - Sender->SetWait(1); - } - - Sender->ReleaseCurrentAction(); -} - -void GameScript::MoveToPoint(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Actor* actor = ( Actor* ) Sender; - - // try the actual move, if we are not already moving there - if (!actor->InMove() || actor->Destination != parameters->pointParameter) { - actor->WalkTo( parameters->pointParameter, 0 ); - } - - // give up if we can't move there (no path was found) - if (!actor->InMove()) { - // we should probably instead keep retrying until we reach dest - Sender->ReleaseCurrentAction(); - } -} - -//bg2, jumps to saved location in variable -void GameScript::MoveToSavedLocation(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - tar = Sender; - } - if (tar->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - - Point p; - Actor* actor = ( Actor* ) tar; - ieDword value = (ieDword) CheckVariable( Sender, parameters->string0Parameter ); - p.fromDword(value); - actor->SetPosition(p, true ); - Sender->ReleaseCurrentAction(); -} -/** iwd2 returntosavedlocation (with stats) */ -/** pst returntosavedplace */ -/** use Sender as default subject */ -void GameScript::ReturnToSavedLocation(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1], GA_NO_DEAD ); - if (!tar) { - tar = Sender; - } - if (tar->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - - Actor* actor = ( Actor* ) tar; - Point p((short) actor->GetBase(IE_SAVEDXPOS),(short) actor->GetBase(IE_SAVEDYPOS) ); - if (p.isnull()) { - Sender->ReleaseCurrentAction(); - return; - } - if (!actor->InMove() || actor->Destination != p) { - actor->WalkTo( p, 0, 0 ); - } - if (!actor->InMove()) { - // we should probably instead keep retrying until we reach dest - Sender->ReleaseCurrentAction(); - } -} - -//PST -void GameScript::RunToSavedLocation(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1], GA_NO_DEAD ); - if (!tar) { - tar = Sender; - } - if (tar->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - - Actor* actor = ( Actor* ) tar; - Point p((short) actor->GetBase(IE_SAVEDXPOS),(short) actor->GetBase(IE_SAVEDYPOS) ); - if (p.isnull()) { - Sender->ReleaseCurrentAction(); - return; - } - if (!actor->InMove() || actor->Destination != p) { - actor->WalkTo( p, IF_RUNNING, 0 ); - } - if (!actor->InMove()) { - // we should probably instead keep retrying until we reach dest - Sender->ReleaseCurrentAction(); - } -} - -//iwd2 -void GameScript::ReturnToSavedLocationDelete(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1], GA_NO_DEAD ); - if (!tar) { - tar = Sender; - } - if (tar->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - - Actor* actor = ( Actor* ) tar; - Point p((short) actor->GetBase(IE_SAVEDXPOS),(short) actor->GetBase(IE_SAVEDYPOS) ); - actor->SetBase(IE_SAVEDXPOS,0); - actor->SetBase(IE_SAVEDYPOS,0); - if (p.isnull()) { - Sender->ReleaseCurrentAction(); - return; - } - if (!actor->InMove() || actor->Destination != p) { - actor->WalkTo( p, 0, 0 ); - } - //what else? - if (!actor->InMove()) { - // we should probably instead keep retrying until we reach dest - Sender->ReleaseCurrentAction(); - } -} - -void GameScript::MoveToObjectNoInterrupt(Scriptable* Sender, Action* parameters) -{ - MoveToObjectCore(Sender, parameters, IF_NOINT, false); -} - -void GameScript::RunToObject(Scriptable* Sender, Action* parameters) -{ - MoveToObjectCore(Sender, parameters, IF_RUNNING, false); -} - -void GameScript::MoveToObject(Scriptable* Sender, Action* parameters) -{ - MoveToObjectCore(Sender, parameters, 0, false); -} - -void GameScript::MoveToObjectUntilSee(Scriptable* Sender, Action* parameters) -{ - MoveToObjectCore(Sender, parameters, 0, true); -} - -void GameScript::MoveToObjectFollow(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Scriptable* target = GetStoredActorFromObject( Sender, parameters->objects[1] ); - if (!target) { - Sender->ReleaseCurrentAction(); - return; - } - Actor* actor = ( Actor* ) Sender; - //follow leader from a distance of 5 - //could also follow the leader with a point offset - if (target->Type==ST_ACTOR) { - actor->SetLeader( (Actor *) target, 5); - } - MoveNearerTo(Sender, target, MAX_OPERATING_DISTANCE); -} - -void GameScript::StorePartyLocation(Scriptable* /*Sender*/, Action* /*parameters*/) -{ - Game *game = core->GetGame(); - for (int i = 0; i < game->GetPartySize(false); i++) { - Actor* act = game->GetPC( i, false ); - GAMLocationEntry *gle = game->GetSavedLocationEntry(i); - if (act && gle) { - gle->Pos = act->Pos; - memcpy(gle->AreaResRef, act->Area, 9); - } - } -} - -void GameScript::RestorePartyLocation(Scriptable* /*Sender*/, Action* /*parameters*/) -{ - Game *game = core->GetGame(); - for (int i = 0; i < game->GetPartySize(false); i++) { - Actor* act = game->GetPC( i, false ); - if (act) { - if (game->GetSavedLocationCount() <= (unsigned int)i) { - // what are we meant to do here? - print("argh, couldn't restore party member %d!", i + 1); - continue; - } - GAMLocationEntry *gle = game->GetSavedLocationEntry(i); - MoveBetweenAreasCore(act, gle->AreaResRef, gle->Pos, -1, true); - } - } - - // presumably this is correct - game->ClearSavedLocations(); -} - -void GameScript::MoveToCenterOfScreen(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Region vp = core->GetVideoDriver()->GetViewport(); - Actor* actor = ( Actor* ) Sender; - Point p((short) (vp.x+vp.w/2), (short) (vp.y+vp.h/2) ); - if (!actor->InMove() || actor->Destination != p) { - actor->WalkTo( p, IF_NOINT, 0 ); - } - if (!actor->InMove()) { - // we should probably instead keep retrying until we reach dest - Sender->ReleaseCurrentAction(); - } -} - -void GameScript::MoveToOffset(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Actor* actor = ( Actor* ) Sender; - Point p(Sender->Pos.x+parameters->pointParameter.x, Sender->Pos.y+parameters->pointParameter.y); - if (!actor->InMove() || actor->Destination != p) { - actor->WalkTo( p, 0, 0 ); - } - if (!actor->InMove()) { - // we should probably instead keep retrying until we reach dest - Sender->ReleaseCurrentAction(); - } -} - -void GameScript::RunAwayFrom(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - if (Sender->GetInternalFlag()&IF_STOPATTACK) { - Sender->ReleaseCurrentAction(); - return; - } - Actor* actor = ( Actor* ) Sender; - Scriptable* tar = GetStoredActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - Sender->ReleaseCurrentAction(); - return; - } - //TODO: actor could use travel areas - // we should be using int0Parameter for the timing here, not distance - if (!actor->InMove()) { - // we should make sure our existing walk is a 'run away', or fix moving/path code - actor->RunAwayFrom( tar->Pos, parameters->int0Parameter, false); - } - - //repeat movement... - if (parameters->int0Parameter>0) { - Action *newaction = ParamCopyNoOverride(parameters); - newaction->int0Parameter--; - actor->AddActionInFront(newaction); - Sender->SetWait(1); - } - - Sender->ReleaseCurrentAction(); -} - -void GameScript::RunAwayFromNoLeaveArea(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - if (Sender->GetInternalFlag()&IF_STOPATTACK) { - Sender->ReleaseCurrentAction(); - return; - } - Actor* actor = ( Actor* ) Sender; - Scriptable* tar = GetStoredActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - Sender->ReleaseCurrentAction(); - return; - } - // we should be using int0Parameter for the timing here, not distance - if (!actor->InMove()) { - // we should make sure our existing walk is a 'run away', or fix moving/path code - actor->RunAwayFrom( tar->Pos, parameters->int0Parameter, false); - } - - //repeat movement... - if (parameters->int0Parameter>0) { - Action *newaction = ParamCopyNoOverride(parameters); - newaction->int0Parameter--; - actor->AddActionInFront(newaction); - Sender->SetWait(1); - } - - Sender->ReleaseCurrentAction(); -} - -void GameScript::RunAwayFromNoInterrupt(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - //i believe being dead still interrupts this action - if (Sender->GetInternalFlag()&IF_STOPATTACK) { - Sender->ReleaseCurrentAction(); - return; - } - Actor* actor = ( Actor* ) Sender; - Scriptable* tar = GetStoredActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - Sender->ReleaseCurrentAction(); - return; - } - //actor->InternalFlags|=IF_NOINT; - actor->NoInterrupt(); - // we should be using int0Parameter for the timing here, not distance - if (!actor->InMove()) { - // we should make sure our existing walk is a 'run away', or fix moving/path code - actor->RunAwayFrom( tar->Pos, parameters->int0Parameter, false); - } - - //repeat movement... - if (parameters->int0Parameter>0) { - Action *newaction = ParamCopyNoOverride(parameters); - newaction->int0Parameter--; - actor->AddActionInFront(newaction); - Sender->SetWait(1); - } else { - actor->Interrupt(); - } - - Sender->ReleaseCurrentAction(); -} - -void GameScript::RunAwayFromPoint(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - if (Sender->GetInternalFlag()&IF_STOPATTACK) { - Sender->ReleaseCurrentAction(); - return; - } - Actor* actor = ( Actor* ) Sender; - // we should be using int0Parameter for the timing here, not distance? - if (!actor->InMove()) { - // we should make sure our existing walk is a 'run away', or fix moving/path code - actor->RunAwayFrom( parameters->pointParameter, parameters->int0Parameter, false); - } - - //repeat movement... - if (parameters->int0Parameter>0) { - Action *newaction = ParamCopyNoOverride(parameters); - newaction->int0Parameter--; - actor->AddActionInFront(newaction); - Sender->SetWait(1); - } - - Sender->ReleaseCurrentAction(); -} - -void GameScript::DisplayStringNoName(Scriptable* Sender, Action* parameters) -{ - Scriptable* target = GetActorFromObject( Sender, parameters->objects[1]); - if (!target) { - target=Sender; - } - if (Sender->Type==ST_ACTOR) { - DisplayStringCore( target, parameters->int0Parameter, DS_CONSOLE|DS_NONAME); - } else { - DisplayStringCore( target, parameters->int0Parameter, DS_AREA|DS_NONAME); - } -} - -void GameScript::DisplayStringNoNameHead(Scriptable* Sender, Action* parameters) -{ - Scriptable* target = GetActorFromObject( Sender, parameters->objects[1] ); - if (!target) { - target=Sender; - } - - DisplayStringCore( target, parameters->int0Parameter, DS_HEAD|DS_CONSOLE|DS_NONAME); -} - -//display message over current script owner -void GameScript::DisplayMessage(Scriptable* Sender, Action* parameters) -{ - DisplayStringCore(Sender, parameters->int0Parameter, DS_CONSOLE ); -} - -//float message over target -void GameScript::DisplayStringHead(Scriptable* Sender, Action* parameters) -{ - Scriptable* target = GetActorFromObject( Sender, parameters->objects[1] ); - if (!target) { - target=Sender; - print("DisplayStringHead/FloatMessage got no target, assuming Sender!\n"); - } - - DisplayStringCore(target, parameters->int0Parameter, DS_CONSOLE|DS_HEAD|DS_SPEECH ); -} - -void GameScript::KillFloatMessage(Scriptable* Sender, Action* parameters) -{ - Scriptable* target = GetActorFromObject( Sender, parameters->objects[1] ); - if (!target) { - target=Sender; - } - target->DisplayHeadText(NULL); -} - -void GameScript::DisplayStringHeadOwner(Scriptable* /*Sender*/, Action* parameters) -{ - Game *game=core->GetGame(); - - int i = game->GetPartySize(true); - while(i--) { - Actor *actor = game->GetPC(i, true); - if (actor->inventory.HasItem(parameters->string0Parameter,parameters->int0Parameter) ) { - DisplayStringCore(actor, parameters->int0Parameter, DS_CONSOLE|DS_HEAD ); - } - } -} - -void GameScript::FloatMessageFixed(Scriptable* Sender, Action* parameters) -{ - Scriptable* target = GetActorFromObject( Sender, parameters->objects[1] ); - if (!target) { - target=Sender; - print("DisplayStringHead/FloatMessage got no target, assuming Sender!\n"); - } - - DisplayStringCore(target, parameters->int0Parameter, DS_CONSOLE|DS_HEAD); -} - -void GameScript::FloatMessageFixedRnd(Scriptable* Sender, Action* parameters) -{ - Scriptable* target = GetActorFromObject( Sender, parameters->objects[1] ); - if (!target) { - target=Sender; - print("DisplayStringHead/FloatMessage got no target, assuming Sender!\n"); - } - - SrcVector *rndstr=LoadSrc(parameters->string0Parameter); - if (!rndstr) { - printMessage("GameScript","Cannot display resource!",LIGHT_RED); - return; - } - DisplayStringCore(target, rndstr->at(rand()%rndstr->size()), DS_CONSOLE|DS_HEAD); - FreeSrc(rndstr, parameters->string0Parameter); -} - -void GameScript::FloatMessageRnd(Scriptable* Sender, Action* parameters) -{ - Scriptable* target = GetActorFromObject( Sender, parameters->objects[1] ); - if (!target) { - target=Sender; - print("DisplayStringHead/FloatMessage got no target, assuming Sender!\n"); - } - - SrcVector *rndstr=LoadSrc(parameters->string0Parameter); - if (!rndstr) { - printMessage("GameScript","Cannot display resource!",LIGHT_RED); - return; - } - DisplayStringCore(target, rndstr->at(rand()%rndstr->size()), DS_CONSOLE|DS_HEAD); - FreeSrc(rndstr, parameters->string0Parameter); -} - -//apparently this should not display over head (for actors) -void GameScript::DisplayString(Scriptable* Sender, Action* parameters) -{ - Scriptable* target = GetActorFromObject( Sender, parameters->objects[1]); - if (!target) { - target=Sender; - } - if (Sender->Type==ST_ACTOR) { - DisplayStringCore( target, parameters->int0Parameter, DS_CONSOLE); - } else { - DisplayStringCore( target, parameters->int0Parameter, DS_AREA); - } -} - -//DisplayStringHead, but wait until done -void GameScript::DisplayStringWait(Scriptable* Sender, Action* parameters) -{ - if (Sender->CurrentActionState) { - // TODO: should probably store the actual time and wait for that, - // rather than this hack - if (!core->GetAudioDrv()->IsSpeaking()) { - Sender->ReleaseCurrentAction(); - } - return; - } - Scriptable* target = GetActorFromObject( Sender, parameters->objects[1]); - if (!target) { - target=Sender; - } - DisplayStringCore( target, parameters->int0Parameter, DS_CONSOLE|DS_WAIT|DS_SPEECH|DS_HEAD); - Sender->CurrentActionState = 1; -} - -void GameScript::ForceFacing(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type!=ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Actor *actor = (Actor *) tar; - actor->SetOrientation(parameters->int0Parameter, false); -} - -/* A -1 means random facing? */ -void GameScript::Face(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Actor* actor = ( Actor* ) Sender; - if (parameters->int0Parameter==-1) { - actor->SetOrientation(core->Roll(1,MAX_ORIENT,-1), false); - } else { - actor->SetOrientation(parameters->int0Parameter, false); - } - actor->SetWait( 1 ); - Sender->ReleaseCurrentAction(); // todo, blocking? -} - -void GameScript::FaceObject(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Scriptable* target = GetActorFromObject( Sender, parameters->objects[1] ); - if (!target) { - Sender->ReleaseCurrentAction(); - return; - } - Actor* actor = ( Actor* ) Sender; - actor->SetOrientation( GetOrient( target->Pos, actor->Pos ), false); - actor->SetWait( 1 ); - Sender->ReleaseCurrentAction(); // todo, blocking? -} - -void GameScript::FaceSavedLocation(Scriptable* Sender, Action* parameters) -{ - Scriptable* target = GetActorFromObject( Sender, parameters->objects[1] ); - if (!target || target->Type!=ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Actor* actor = ( Actor* ) target; - ieDword value; - if (!parameters->string0Parameter[0]) { - strcpy(parameters->string0Parameter,"LOCALSsavedlocation"); - } - value = (ieDword) CheckVariable( target, parameters->string0Parameter ); - Point p; - p.fromDword(value); - - actor->SetOrientation ( GetOrient( p, actor->Pos ), false); - actor->SetWait( 1 ); - Sender->ReleaseCurrentAction(); // todo, blocking? -} - -//pst and bg2 can play a song designated by index -//actually pst has some extra params not currently implemented -//switchplaylist implements fade by simply scheduling the next -//music after the currently running one -//FIXME: This code is similar to PlayAreaSong, consider refactoring -void GameScript::StartSong(Scriptable* /*Sender*/, Action* parameters) -{ - //the force play logic should be handled by SwitchPlayList - bool force; - char* poi = core->GetMusicPlaylist( parameters->int0Parameter ); - if (!poi) return; - - //if parameter is force, force the music, otherwise just schedule it for next - if (parameters->int1Parameter==1) { - force = true; - } else { - force = false; - } - int ret = core->GetMusicMgr()->SwitchPlayList( poi, force ); - if (ret) { - *poi = '*'; - } - if (parameters->int0Parameter == SONG_BATTLE) { - core->GetGame()->CombatCounter = 150; - } -} - -//starts the current area music (songtype is in int0Parameter) -//PlayAreaSong will set the CombatCounter to 150 if -//it is battlemusic (the Counter will tick back to 0) -void GameScript::StartMusic(Scriptable* Sender, Action* parameters) -{ - //don't break on bad values - if (parameters->int0Parameter>10) return; - Map *map = Sender->GetCurrentArea(); - if (!map) return; - bool force, restart; - - switch (parameters->int1Parameter) { - case 1: //force switch - force = true; - restart = true; - break; - case 3: //force switch, but wait for previous music to end gracefully - force = false; - restart = true; - break; - default: - force = false; - restart = false; - break; - } - map->PlayAreaSong(parameters->int0Parameter, restart, force); -} - -void GameScript::StartCombatCounter(Scriptable* Sender, Action* /*parameters*/) -{ - Map *map = Sender->GetCurrentArea(); - if (!map) return; - map->PlayAreaSong(3, 1, 1); -} - -/*iwd2 can set an areasong slot*/ -void GameScript::SetMusic(Scriptable* Sender, Action* parameters) -{ - //iwd2 allows setting all 10 slots, though, there is no evidence they are used - if (parameters->int0Parameter>10) return; - Map *map = Sender->GetCurrentArea(); - if (!map) return; - map->SongHeader.SongList[parameters->int0Parameter]=parameters->int1Parameter; -} - -//optional integer parameter (isSpeech) -void GameScript::PlaySound(Scriptable* Sender, Action* parameters) -{ - print( "PlaySound(%s)\n", parameters->string0Parameter ); - core->GetAudioDrv()->Play( parameters->string0Parameter, Sender->Pos.x, - Sender->Pos.y, parameters->int0Parameter ? GEM_SND_SPEECH : 0 ); -} - -void GameScript::PlaySoundPoint(Scriptable* /*Sender*/, Action* parameters) -{ - print( "PlaySound(%s)\n", parameters->string0Parameter ); - core->GetAudioDrv()->Play( parameters->string0Parameter, parameters->pointParameter.x, parameters->pointParameter.y ); -} - -void GameScript::PlaySoundNotRanged(Scriptable* /*Sender*/, Action* parameters) -{ - print( "PlaySound(%s)\n", parameters->string0Parameter ); - core->GetAudioDrv()->Play( parameters->string0Parameter, 0, 0); -} - -void GameScript::Continue(Scriptable* /*Sender*/, Action* /*parameters*/) -{ -} - -// creates area vvc at position of object -void GameScript::CreateVisualEffectObject(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - return; - } - CreateVisualEffectCore(tar, tar->Pos, parameters->string0Parameter, parameters->int0Parameter); -} - -// creates sticky vvc on actor or normal animation on object -void GameScript::CreateVisualEffectObjectSticky(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - return; - } - if (tar->Type==ST_ACTOR) { - CreateVisualEffectCore((Actor *) tar, parameters->string0Parameter, parameters->int0Parameter); - } else { - CreateVisualEffectCore(tar, tar->Pos, parameters->string0Parameter, parameters->int0Parameter); - } -} - -// creates area effect at point -void GameScript::CreateVisualEffect(Scriptable* Sender, Action* parameters) -{ - CreateVisualEffectCore(Sender, parameters->pointParameter, parameters->string0Parameter, parameters->int0Parameter); -} - -void GameScript::DestroySelf(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - Sender->ClearActions(); - Actor* actor = ( Actor* ) Sender; - actor->DestroySelf(); - //actor->InternalFlags |= IF_CLEANUP; -} - -void GameScript::ScreenShake(Scriptable* Sender, Action* parameters) -{ - if (parameters->int1Parameter) { //IWD2 has a different profile - core->timer->SetScreenShake( parameters->int1Parameter, - parameters->int2Parameter, parameters->int0Parameter ); - } else { - core->timer->SetScreenShake( parameters->pointParameter.x, - parameters->pointParameter.y, parameters->int0Parameter ); - } - Sender->SetWait( parameters->int0Parameter ); - Sender->ReleaseCurrentAction(); // todo, blocking? -} - -void GameScript::UnhideGUI(Scriptable* /*Sender*/, Action* /*parameters*/) -{ - Game* game = core->GetGame(); - game->SetControlStatus(CS_HIDEGUI, BM_NAND); -} - -void GameScript::HideGUI(Scriptable* /*Sender*/, Action* /*parameters*/) -{ - Game* game = core->GetGame(); - game->SetControlStatus(CS_HIDEGUI, BM_OR); -} - -void GameScript::LockScroll(Scriptable* /*Sender*/, Action* /*parameters*/) -{ - GameControl* gc = core->GetGameControl(); - if (gc) { - gc->SetScreenFlags(SF_LOCKSCROLL, BM_OR); - } -} - -void GameScript::UnlockScroll(Scriptable* /*Sender*/, Action* /*parameters*/) -{ - GameControl* gc = core->GetGameControl(); - if (gc) { - gc->SetScreenFlags(SF_LOCKSCROLL, BM_NAND); - } -} - -//no string, increase talkcount, no interrupt -void GameScript::Dialogue(Scriptable* Sender, Action* parameters) -{ - BeginDialog( Sender, parameters, BD_SOURCE | BD_TALKCOUNT | BD_CHECKDIST ); -} - -void GameScript::DialogueForceInterrupt(Scriptable* Sender, Action* parameters) -{ - BeginDialog( Sender, parameters, BD_SOURCE | BD_TALKCOUNT | BD_INTERRUPT ); -} - -// not in IESDP but this one should affect ambients -void GameScript::SoundActivate(Scriptable* /*Sender*/, Action* parameters) -{ - AmbientMgr * ambientmgr = core->GetAudioDrv()->GetAmbientMgr(); - if (parameters->int0Parameter) { - ambientmgr->activate(parameters->objects[1]->objectName); - } else { - ambientmgr->deactivate(parameters->objects[1]->objectName); - } -} - -// according to IESDP this action is about animations -void GameScript::AmbientActivate(Scriptable* Sender, Action* parameters) -{ - AreaAnimation* anim = Sender->GetCurrentArea( )->GetAnimation( parameters->string0Parameter); - if (!anim) { - anim = Sender->GetCurrentArea( )->GetAnimation( parameters->objects[1]->objectName ); - } - if (!anim) { - print( "Script error: No Animation Named \"%s\" or \"%s\"\n", - parameters->string0Parameter,parameters->objects[1]->objectName ); - return; - } - if (parameters->int0Parameter) { - anim->Flags |= A_ANI_ACTIVE; - } else { - anim->Flags &= ~A_ANI_ACTIVE; - } -} - -void GameScript::ChangeTileState(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1], GA_NO_DEAD ); - if (!tar) { - return; - } - if (tar->Type != ST_DOOR) { - return; - } - Door* door = ( Door* ) tar; - int state = parameters->int0Parameter; - if(door) { - door->ToggleTiles(state); /* default is false for playsound */ - } -} - -void GameScript::StaticStart(Scriptable* Sender, Action* parameters) -{ - AreaAnimation *anim = Sender->GetCurrentArea()->GetAnimation(parameters->objects[1]->objectName); - if (!anim) { - print( "Script error: No Animation Named \"%s\"\n", - parameters->objects[1]->objectName ); - return; - } - anim->Flags &=~A_ANI_PLAYONCE; -} - -void GameScript::StaticStop(Scriptable* Sender, Action* parameters) -{ - AreaAnimation *anim = Sender->GetCurrentArea()->GetAnimation(parameters->objects[1]->objectName); - if (!anim) { - print( "Script error: No Animation Named \"%s\"\n", - parameters->objects[1]->objectName ); - return; - } - anim->Flags |= A_ANI_PLAYONCE; -} - -void GameScript::StaticPalette(Scriptable* Sender, Action* parameters) -{ - AreaAnimation *anim = Sender->GetCurrentArea()->GetAnimation(parameters->objects[1]->objectName); - if (!anim) { - print( "Script error: No Animation Named \"%s\"\n", - parameters->objects[1]->objectName ); - return; - } - anim->SetPalette( parameters->string0Parameter ); -} - -//this is a special case of PlaySequence (with wait time, not for area anims) -void GameScript::PlaySequenceTimed(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar; - if (parameters->objects[1]) { - tar = GetActorFromObject( Sender, parameters->objects[1] ); - } else { - tar=Sender; - } - if (!tar || tar->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) tar; - actor->SetStance( parameters->int0Parameter ); - int delay = parameters->int1Parameter || 1; - actor->SetWait( delay ); -} - -//waitanimation: waiting while animation of target is of a certain type -void GameScript::WaitAnimation(Scriptable* Sender, Action* parameters) -{ - Scriptable *tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - tar=Sender; - } - if (tar->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) tar; - if (actor->GetStance()!=parameters->int0Parameter) { - Sender->ReleaseCurrentAction(); - return; - } -} - -// PlaySequence without object parameter defaults to Sender -void GameScript::PlaySequence(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar; - if (parameters->objects[1]) { - tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - //could be an animation - AreaAnimation* anim = Sender->GetCurrentArea( )->GetAnimation( parameters->objects[1]->objectName); - if (anim) { - //set animation's cycle to parameters->int0Parameter; - anim->sequence=parameters->int0Parameter; - anim->frame=0; - //what else to be done??? - anim->InitAnimation(); - } - return; - } - - } else { - tar = Sender; - } - if (tar->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) tar; - actor->SetStance( parameters->int0Parameter ); -} - -//same as PlaySequence, but the value comes from a variable -//ToDo: create a PlaySequenceCore in GSUtils -void GameScript::PlaySequenceGlobal(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar; - ieDword value; - - value = (ieDword) CheckVariable( Sender, parameters->string0Parameter ); - - if (parameters->objects[1]) { - tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - //could be an animation - AreaAnimation* anim = Sender->GetCurrentArea( )->GetAnimation( parameters->objects[1]->objectName); - if (anim) { - //set animation's cycle to value; - anim->sequence=value; - anim->frame=0; - //what else to be done??? - anim->InitAnimation(); - } - return; - } - - } else { - tar = Sender; - } - if (tar->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) tar; - actor->SetStance( value ); -} - -void GameScript::SetDialogue(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - Actor* target = ( Actor* ) Sender; - target->SetDialog( parameters->string0Parameter ); -} - -void GameScript::ChangeDialogue(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - return; - } - if (tar->Type != ST_ACTOR) { - return; - } - Actor* target = ( Actor* ) tar; - target->SetDialog( parameters->string0Parameter ); -} - -//string0, no interrupt, talkcount increased -void GameScript::StartDialogue(Scriptable* Sender, Action* parameters) -{ - BeginDialog( Sender, parameters, BD_STRING0 | BD_TALKCOUNT | BD_SETDIALOG ); -} - -//string0, no interrupt, talkcount increased, don't set default -//optionally item name is used -void GameScript::StartDialogueOverride(Scriptable* Sender, Action* parameters) -{ - int flags = BD_STRING0 | BD_TALKCOUNT; - - if (parameters->int2Parameter) { - flags|=BD_ITEM; - } - BeginDialog( Sender, parameters, flags ); -} - -//string0, no interrupt, talkcount increased, don't set default -//optionally item name is used -void GameScript::StartDialogueOverrideInterrupt(Scriptable* Sender, - Action* parameters) -{ - int flags = BD_STRING0 | BD_TALKCOUNT | BD_INTERRUPT; - - if (parameters->int2Parameter) { - flags|=BD_ITEM; - } - BeginDialog( Sender, parameters, flags ); -} - -//start talking to oneself -void GameScript::PlayerDialogue(Scriptable* Sender, Action* parameters) -{ - BeginDialog( Sender, parameters, BD_RESERVED | BD_OWN ); -} - -//we hijack this action for the player initiated dialogue -void GameScript::NIDSpecial1(Scriptable* Sender, Action* parameters) -{ - BeginDialog( Sender, parameters, BD_INTERRUPT | BD_TARGET /*| BD_NUMERIC*/ | BD_TALKCOUNT | BD_CHECKDIST ); -} - -void GameScript::NIDSpecial2(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Game *game=core->GetGame(); - if (!game->EveryoneStopped() ) { - //wait for a while - Sender->SetWait( 1 * AI_UPDATE_TIME ); - return; - } - Actor *actor = (Actor *) Sender; - if (!game->EveryoneNearPoint(actor->GetCurrentArea(), actor->Pos, true) ) { - //we abort the command, everyone should be here - Sender->ReleaseCurrentAction(); - return; - } - //travel direction passed to guiscript - int direction = Sender->GetCurrentArea()->WhichEdge(actor->Pos); - print("Travel direction returned: %d\n", direction); - if (direction==-1) { - Sender->ReleaseCurrentAction(); - return; - } - core->GetDictionary()->SetAt("Travel", (ieDword) direction); - core->GetGUIScriptEngine()->RunFunction( "GUIMA", "OpenWorldMapWindow" ); - //sorry, i have absolutely no idea when i should do this :) - Sender->ReleaseCurrentAction(); -} - -void GameScript::StartDialogueInterrupt(Scriptable* Sender, Action* parameters) -{ - BeginDialog( Sender, parameters, - BD_STRING0 | BD_INTERRUPT | BD_TALKCOUNT | BD_SETDIALOG ); -} - -//No string, flags:0 -void GameScript::StartDialogueNoSet(Scriptable* Sender, Action* parameters) -{ - BeginDialog( Sender, parameters, BD_TALKCOUNT | BD_SOURCE ); -} - -void GameScript::StartDialogueNoSetInterrupt(Scriptable* Sender, - Action* parameters) -{ - BeginDialog( Sender, parameters, BD_TALKCOUNT | BD_SOURCE | BD_INTERRUPT ); -} - -//no talkcount, using banter dialogs -//probably banter dialogs are random, like rumours! -//no, they aren't, but they increase interactcount -void GameScript::Interact(Scriptable* Sender, Action* parameters) -{ - BeginDialog( Sender, parameters, BD_INTERACT | BD_NOEMPTY ); -} - -static unsigned int FindNearPoint(Scriptable* Sender, Point *&p1, Point *&p2) -{ - unsigned int distance1 = Distance(*p1, Sender); - unsigned int distance2 = Distance(*p2, Sender); - if (distance1 <= distance2) { - return distance1; - } else { - Point *tmp = p1; - p1 = p2; - p2 = tmp; - return distance2; - } -} - -//this is an immediate action without checking Sender -void GameScript::DetectSecretDoor(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1], GA_NO_DEAD ); - if (!tar) { - return; - } - if (tar->Type != ST_DOOR) { - return; - } - Door* door = ( Door* ) tar; - if (door->Flags & DOOR_SECRET) { - door->Flags |= DOOR_FOUND; - } -} - -//this is an immediate action without checking Sender -void GameScript::Lock(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - return; - } - switch (tar->Type) { - case ST_DOOR: - ((Door *)tar)->SetDoorLocked(true, true); - break; - case ST_CONTAINER: - ((Container *)tar)->SetContainerLocked(true); - break; - default: - return; - } -} - -void GameScript::Unlock(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - return; - } - switch (tar->Type) { - case ST_DOOR: - ((Door *)tar)->SetDoorLocked(false, true); - break; - case ST_CONTAINER: - ((Container *)tar)->SetContainerLocked(false); - break; - default: - return; - } -} - -void GameScript::SetDoorLocked(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - return; - } - if (tar->Type != ST_DOOR) { - return; - } - Door* door = ( Door* ) tar; - door->SetDoorLocked( parameters->int0Parameter!=0, false); -} - -void GameScript::SetDoorFlag(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - return; - } - if (tar->Type != ST_DOOR) { - return; - } - Door* door = ( Door* ) tar; - ieDword flag = parameters->int0Parameter; - - //these are special flags - if (flag&DOOR_LOCKED) { - flag&=~DOOR_LOCKED; - door->SetDoorLocked(parameters->int1Parameter!=0, false); - } - if (flag&DOOR_OPEN) { - flag&=~DOOR_OPEN; - door->SetDoorOpen(parameters->int1Parameter!=0, false, 0); - } - - if (parameters->int1Parameter) { - door->Flags|=flag; - } else { - door->Flags&=~flag; - } -} - -void GameScript::RemoveTraps(Scriptable* Sender, Action* parameters) -{ - //only actors may try to pick a lock - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - Sender->ReleaseCurrentAction(); - return; - } - unsigned int distance; - Point *p, *otherp; - Door *door = NULL; - Container *container = NULL; - InfoPoint *trigger = NULL; - ScriptableType type = tar->Type; - ieDword flags; - - switch (type) { - case ST_DOOR: - door = ( Door* ) tar; - if (door->IsOpen()) { - //door is already open - Sender->ReleaseCurrentAction(); - return; - } - p = door->toOpen; - otherp = door->toOpen+1; - distance = FindNearPoint( Sender, p, otherp); - flags = door->Trapped && door->TrapDetected; - break; - case ST_CONTAINER: - container = (Container *) tar; - p = &container->Pos; - otherp = p; - distance = Distance(*p, Sender); - flags = container->Trapped && container->TrapDetected; - break; - case ST_PROXIMITY: - trigger = (InfoPoint *) tar; - // this point is incorrect! will cause actor to enter trap - // need to find a point using trigger->outline - p = &trigger->Pos; - otherp = p; - distance = Distance(tar, Sender); - flags = trigger->Trapped && trigger->TrapDetected && trigger->CanDetectTrap(); - break; - default: - Sender->ReleaseCurrentAction(); - return; - } - Actor * actor = (Actor *) Sender; - actor->SetOrientation( GetOrient( *otherp, actor->Pos ), false); - if (distance <= MAX_OPERATING_DISTANCE) { - if (flags) { - switch(type) { - case ST_DOOR: - door->TryDisarm(actor); - break; - case ST_CONTAINER: - container->TryDisarm(actor); - break; - case ST_PROXIMITY: - trigger->TryDisarm(actor); - break; - default: - //not gonna happen! - assert(false); - } - } else { - //no trap here - //displaymsg->DisplayString(STR_NOT_TRAPPED); - } - } else { - MoveNearerTo(Sender, *p, MAX_OPERATING_DISTANCE,0); - return; - } - Sender->SetWait(1); - Sender->ReleaseCurrentAction(); -} - -void GameScript::PickLock(Scriptable* Sender, Action* parameters) -{ - //only actors may try to pick a lock - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - Sender->ReleaseCurrentAction(); - return; - } - unsigned int distance; - Point *p, *otherp; - Door *door = NULL; - Container *container = NULL; - ScriptableType type = tar->Type; - ieDword flags; - - switch (type) { - case ST_DOOR: - door = ( Door* ) tar; - if (door->IsOpen()) { - //door is already open - Sender->ReleaseCurrentAction(); - return; - } - p = door->toOpen; - otherp = door->toOpen+1; - distance = FindNearPoint( Sender, p, otherp); - flags = door->Flags&DOOR_LOCKED; - break; - case ST_CONTAINER: - container = (Container *) tar; - p = &container->Pos; - otherp = p; - distance = Distance(*p, Sender); - flags = container->Flags&CONT_LOCKED; - break; - default: - Sender->ReleaseCurrentAction(); - return; - } - Actor * actor = (Actor *) Sender; - actor->SetOrientation( GetOrient( *otherp, actor->Pos ), false); - if (distance <= MAX_OPERATING_DISTANCE) { - if (flags) { - if (type==ST_DOOR) { - door->TryPickLock(actor); - } else { - container->TryPickLock(actor); - } - } else { - //notlocked - //displaymsg->DisplayString(STR_NOT_LOCKED); - } - } else { - MoveNearerTo(Sender, *p, MAX_OPERATING_DISTANCE,0); - return; - } - Sender->SetWait(1); - Sender->ReleaseCurrentAction(); -} - -void GameScript::OpenDoor(Scriptable* Sender, Action* parameters) { - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - return; - } - if (tar->Type != ST_DOOR) { - return; - } - Door* door = ( Door* ) tar; - // no idea if this is right, or whether OpenDoor/CloseDoor should allow opening - // of all doors, or some doors, or whether it should still check for non-actors - if (Sender->Type == ST_ACTOR) { - Actor *actor = (Actor *)Sender; - actor->SetModal(MS_NONE); - if (!door->TryUnlock(actor)) { - return; - } - } - //if not an actor opens, it don't play sound - door->SetDoorOpen( true, (Sender->Type == ST_ACTOR), 0 ); - Sender->ReleaseCurrentAction(); -} - -void GameScript::CloseDoor(Scriptable* Sender, Action* parameters) { - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - return; - } - if (tar->Type != ST_DOOR) { - return; - } - Door* door = ( Door* ) tar; - // see comments in OpenDoor above - if (Sender->Type == ST_ACTOR) { - Actor *actor = (Actor *)Sender; - if (!door->TryUnlock(actor)) { - return; - } - } - //if not an actor closes, it don't play sound - door->SetDoorOpen( false, (Sender->Type == ST_ACTOR), 0 ); - Sender->ReleaseCurrentAction(); -} - -void GameScript::ToggleDoor(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Actor *actor = (Actor *) Sender; - actor->SetModal(MS_NONE); - - Door* door = actor->GetCurrentArea()->GetDoorByGlobalID(actor->TargetDoor); - if (!door) { - Sender->ReleaseCurrentAction(); - return; - } - unsigned int distance; - Point *p = door->toOpen; - Point *otherp = door->toOpen+1; - distance = FindNearPoint( Sender, p, otherp); - if (distance <= MAX_OPERATING_DISTANCE) { - actor->SetOrientation( GetOrient( *otherp, actor->Pos ), false); - if (!door->TryUnlock(actor)) { - displaymsg->DisplayConstantString(STR_DOORLOCKED,0xd7d7be,door); - //playsound unsuccessful opening of door - if(door->IsOpen()) - core->PlaySound(DS_CLOSE_FAIL); - else - core->PlaySound(DS_OPEN_FAIL); - Sender->ReleaseCurrentAction(); - actor->TargetDoor = 0; - return; //don't open door - } - - // should we be triggering the trap on close? - door->TriggerTrap(0, actor->GetGlobalID()); - door->SetDoorOpen( !door->IsOpen(), true, actor->GetGlobalID() ); - } else { - MoveNearerTo(Sender, *p, MAX_OPERATING_DISTANCE,0); - return; - } - Sender->SetWait(1); - Sender->ReleaseCurrentAction(); - actor->TargetDoor = 0; -} - -void GameScript::ContainerEnable(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type!=ST_CONTAINER) { - return; - } - Container *cnt = (Container *) tar; - if (parameters->int0Parameter) { - cnt->Flags&=~CONT_DISABLED; - } else { - cnt->Flags|=CONT_DISABLED; - } -} - -void GameScript::MoveBetweenAreas(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - if (parameters->string1Parameter[0]) { - CreateVisualEffectCore(Sender, Sender->Pos, parameters->string1Parameter, 0); - } - MoveBetweenAreasCore((Actor *) Sender, parameters->string0Parameter, - parameters->pointParameter, parameters->int0Parameter, true); -} - -//spell is depleted, casting time is calculated, interruptible -//FIXME The caster must meet the level requirements as set in the spell file -void GameScript::Spell(Scriptable* Sender, Action* parameters) -{ - ieResRef spellres; - - //resolve spellname - if (!ResolveSpellName( spellres, parameters) ) { - Sender->ReleaseCurrentAction(); - return; - } - - if (Sender->CurrentActionState) { - if (Sender->LastTarget) { - //if target was set, fire spell - Sender->CastSpellEnd(0); - } else if(!Sender->LastTargetPos.isempty()) { - //the target was converted to a point - Sender->CastSpellPointEnd(0); - } else { - printMessage("GameScript", "Spell lost target somewhere!", LIGHT_RED); - } - Sender->ReleaseCurrentAction(); - return; - } - - //parse target - int seeflag; - unsigned int dist = GetSpellDistance(spellres, Sender); - if (dist == 0xffffffff) { - seeflag = 0; - } else { - seeflag = GA_NO_DEAD; - } - - Scriptable* tar = GetStoredActorFromObject( Sender, parameters->objects[1], seeflag ); - if (!tar) { - Sender->ReleaseCurrentAction(); - return; - } - - if(Sender->Type==ST_ACTOR) { - Actor *act = (Actor *) Sender; - - //move near to target - if (dist != 0xffffffff) { - if (PersonalDistance(tar, Sender) > dist || !Sender->GetCurrentArea()->IsVisible(Sender->Pos, tar->Pos)) { - MoveNearerTo(Sender,tar,dist); - return; - } - } - - //face target - if (tar != Sender) { - act->SetOrientation( GetOrient( tar->Pos, act->Pos ), false ); - } - - //stop doing anything else - act->SetModal(MS_NONE); - } - Sender->CurrentActionState = 1; - int duration = Sender->CastSpell( spellres, tar, true ); - if (duration != -1) Sender->SetWait(duration); - - //if target was set, feed action back - if (!Sender->LastTarget && Sender->LastTargetPos.isempty()) { - Sender->ReleaseCurrentAction(); - } -} - -//spell is depleted, casting time is calculated, interruptible -//FIXME The caster must meet the level requirements as set in the spell file -void GameScript::SpellPoint(Scriptable* Sender, Action* parameters) -{ - ieResRef spellres; - - //resolve spellname - if (!ResolveSpellName( spellres, parameters) ) { - Sender->ReleaseCurrentAction(); - return; - } - - if (Sender->CurrentActionState) { - if(!Sender->LastTargetPos.isempty()) { - //if target was set, fire spell - Sender->CastSpellPointEnd(0); - } else { - printMessage("GameScript", "SpellPoint lost target somewhere!", LIGHT_RED); - } - Sender->ReleaseCurrentAction(); - return; - } - - if(Sender->Type==ST_ACTOR) { - unsigned int dist = GetSpellDistance(spellres, Sender); - - Actor *act = (Actor *) Sender; - //move near to target - if (PersonalDistance(parameters->pointParameter, Sender) > dist || !Sender->GetCurrentArea()->IsVisible(Sender->Pos, parameters->pointParameter)) { - MoveNearerTo(Sender,parameters->pointParameter,dist, 0); - return; - } - - //face target - act->SetOrientation( GetOrient( parameters->pointParameter, act->Pos ), false ); - //stop doing anything else - act->SetModal(MS_NONE); - } - - Sender->CurrentActionState = 1; - int duration = Sender->CastSpellPoint( spellres, parameters->pointParameter, true ); - if (duration != -1) Sender->SetWait(duration); - - //if target was set, feed action back - if (!Sender->LastTarget && Sender->LastTargetPos.isempty()) { - Sender->ReleaseCurrentAction(); - } -} - -//spell is not depleted (doesn't need to be memorised or known) -//casting time is calculated, interruptible -//FIXME The caster must meet the level requirements as set in the spell file -void GameScript::SpellNoDec(Scriptable* Sender, Action* parameters) -{ - ieResRef spellres; - - //resolve spellname - if (!ResolveSpellName( spellres, parameters) ) { - Sender->ReleaseCurrentAction(); - return; - } else { - if (!Sender->SpellResRef[0]) { - Sender->SetSpellResRef(spellres); - } - } - - if (Sender->CurrentActionState) { - if (Sender->LastTarget) { - //if target was set, fire spell - Sender->CastSpellEnd(0); - } else if(!Sender->LastTargetPos.isempty()) { - //the target was converted to a point - Sender->CastSpellPointEnd(0); - } else { - printMessage("GameScript", "SpellNoDec lost target somewhere!", LIGHT_RED); - } - Sender->ReleaseCurrentAction(); - return; - } - - //parse target - Scriptable* tar = GetStoredActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - Sender->ReleaseCurrentAction(); - return; - } - - //face target - if (Sender->Type==ST_ACTOR) { - Actor *act = (Actor *) Sender; - if (tar != Sender) { - act->SetOrientation( GetOrient( tar->Pos, act->Pos ), false ); - } - - //stop doing anything else - act->SetModal(MS_NONE); - } - Sender->CurrentActionState = 1; - int duration = Sender->CastSpell( spellres, tar, false ); - if (duration != -1) Sender->SetWait(duration); - - //if target was set, feed action back - if (!Sender->LastTarget && Sender->LastTargetPos.isempty()) { - Sender->ReleaseCurrentAction(); - } -} - -//spell is not depleted (doesn't need to be memorised or known) -//casting time is calculated, interruptible -//FIXME The caster must meet the level requirements as set in the spell file -void GameScript::SpellPointNoDec(Scriptable* Sender, Action* parameters) -{ - ieResRef spellres; - - //resolve spellname - if (!ResolveSpellName( spellres, parameters) ) { - Sender->ReleaseCurrentAction(); - return; - } else { - if (!Sender->SpellResRef[0]) { - Sender->SetSpellResRef(spellres); - } - } - - if (Sender->CurrentActionState) { - if(!Sender->LastTargetPos.isempty()) { - //if target was set, fire spell - Sender->CastSpellPointEnd(0); - } else { - printMessage("GameScript", "SpellPointNoDec lost target somewhere!", LIGHT_RED); - } - Sender->ReleaseCurrentAction(); - return; - } - - //face target - if (Sender->Type==ST_ACTOR) { - Actor *act = (Actor *) Sender; - act->SetOrientation( GetOrient( parameters->pointParameter, act->Pos ), false ); - - //stop doing anything else - act->SetModal(MS_NONE); - } - - Sender->CurrentActionState = 1; - int duration = Sender->CastSpellPoint( spellres, parameters->pointParameter, false ); - if (duration != -1) Sender->SetWait(duration); - - //if target was set, feed action back - if (Sender->LastTargetPos.isempty()) { - Sender->ReleaseCurrentAction(); - } -} - -//spell is not depleted (doesn't need to be memorised or known) -//casting time is calculated, not interruptable -//FIXME The caster must meet the level requirements as set in the spell file -void GameScript::ForceSpell(Scriptable* Sender, Action* parameters) -{ - ieResRef spellres; - - //resolve spellname - if (!ResolveSpellName( spellres, parameters) ) { - Sender->ReleaseCurrentAction(); - return; - } else { - if (!Sender->SpellResRef[0]) { - Sender->SetSpellResRef(spellres); - } - } - - if (Sender->CurrentActionState) { - if (Sender->LastTarget) { - //if target was set, fire spell - Sender->CastSpellEnd(0); - } else if(!Sender->LastTargetPos.isempty()) { - //the target was converted to a point - Sender->CastSpellPointEnd(0); - } else { - printMessage("GameScript", "ForceSpell lost target somewhere!", LIGHT_RED); - } - Sender->ReleaseCurrentAction(); - return; - } - - //parse target - Scriptable* tar = GetStoredActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - Sender->ReleaseCurrentAction(); - return; - } - - //face target - if (Sender->Type==ST_ACTOR) { - Actor *act = (Actor *) Sender; - if (tar != Sender) { - act->SetOrientation( GetOrient( tar->Pos, act->Pos ), false ); - } - - //stop doing anything else - act->SetModal(MS_NONE); - } - Sender->CurrentActionState = 1; - int duration = Sender->CastSpell (spellres, tar, false); - if (duration != -1) Sender->SetWait(duration); - - //if target was set, feed action back - if (!Sender->LastTarget && Sender->LastTargetPos.isempty()) { - Sender->ReleaseCurrentAction(); - } -} - -//spell is not depleted (doesn't need to be memorised or known) -//casting time is calculated, not interruptable -//FIXME The caster must meet the level requirements as set in the spell file -void GameScript::ForceSpellPoint(Scriptable* Sender, Action* parameters) -{ - ieResRef spellres; - - if (!ResolveSpellName( spellres, parameters) ) { - Sender->ReleaseCurrentAction(); - return; - } else { - if (!Sender->SpellResRef[0]) { - Sender->SetSpellResRef(spellres); - } - } - - if (Sender->CurrentActionState) { - if(!Sender->LastTargetPos.isempty()) { - //if target was set, fire spell - Sender->CastSpellPointEnd(0); - } else { - printMessage("GameScript", "ForceSpellPoint lost target somewhere!", LIGHT_RED); - } - Sender->ReleaseCurrentAction(); - return; - } - - //face target - if (Sender->Type==ST_ACTOR) { - Actor *act = (Actor *) Sender; - act->SetOrientation( GetOrient( parameters->pointParameter, act->Pos ), false ); - - //stop doing anything else - act->SetModal(MS_NONE); - } - - Sender->CurrentActionState = 1; - int duration = Sender->CastSpellPoint (spellres, parameters->pointParameter, false); - if (duration != -1) Sender->SetWait(duration); - - //if target was set, feed action back - if (Sender->LastTargetPos.isempty()) { - Sender->ReleaseCurrentAction(); - } -} - -//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 (FIXED) -void GameScript::ReallyForceSpell(Scriptable* Sender, Action* parameters) -{ - ieResRef spellres; - int level; - - if (!ResolveSpellName( spellres, parameters) ) { - Sender->ReleaseCurrentAction(); - return; - } else { - if (!Sender->SpellResRef[0]) { - Sender->SetSpellResRef(spellres); - } - } - - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - Sender->ReleaseCurrentAction(); - return; - } - if (Sender->Type == ST_ACTOR) { - Actor *actor = (Actor *) Sender; - if (tar != Sender) { - actor->SetOrientation( GetOrient( tar->Pos, actor->Pos ), false ); - } - actor->SetStance (IE_ANI_CONJURE); - } - Sender->CastSpell (spellres, tar, false, true); - if (parameters->string0Parameter[0]) { - level = parameters->int0Parameter; - } else { - level = parameters->int1Parameter; - } - if (tar->Type==ST_ACTOR) { - Sender->CastSpellEnd(level); - } else { - Sender->CastSpellPointEnd(level); - } - Sender->ReleaseCurrentAction(); -} - -//ForceSpellPoint with zero casting time -//zero casting time, no depletion (finish casting at point), not interruptable -//no CFB -//FIXME The caster must meet the level requirements as set in the spell file -void GameScript::ReallyForceSpellPoint(Scriptable* Sender, Action* parameters) -{ - ieResRef spellres; - int level; - - if (!ResolveSpellName( spellres, parameters) ) { - Sender->ReleaseCurrentAction(); - return; - } else { - if (!Sender->SpellResRef[0]) { - Sender->SetSpellResRef(spellres); - } - } - - //Sender->LastTargetPos=parameters->pointParameter; - if (Sender->Type == ST_ACTOR) { - if (Sender->GetInternalFlag()&IF_STOPATTACK) { - Sender->ReleaseCurrentAction(); - return; - } - Actor *actor = (Actor *) Sender; - actor->SetOrientation( GetOrient( parameters->pointParameter, actor->Pos ), false ); - actor->SetStance (IE_ANI_CONJURE); - } - Sender->CastSpellPoint (spellres, parameters->pointParameter, false, true); - if (parameters->string0Parameter[0]) { - level = parameters->int0Parameter; - } else { - level = parameters->int1Parameter; - } - Sender->CastSpellPointEnd(level); - Sender->ReleaseCurrentAction(); -} - -// this differs from ReallyForceSpell that this one allows dead Sender casting -// zero casting time, no depletion -void GameScript::ReallyForceSpellDead(Scriptable* Sender, Action* parameters) -{ - ieResRef spellres; - int level; - - if (!ResolveSpellName( spellres, parameters) ) { - Sender->ReleaseCurrentAction(); - return; - } else { - if (!Sender->SpellResRef[0]) { - Sender->SetSpellResRef(spellres); - } - } - - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - Sender->ReleaseCurrentAction(); - return; - } - Sender->LastTargetPos=parameters->pointParameter; - - Sender->CastSpell (spellres, tar, false, true); - if (parameters->string0Parameter[0]) { - level = parameters->int0Parameter; - } else { - level = parameters->int1Parameter; - } - if (tar->Type==ST_ACTOR) { - Sender->CastSpellEnd(level); - } else { - Sender->CastSpellPointEnd(level); - } - Sender->ReleaseCurrentAction(); -} - -void GameScript::Deactivate(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - return; - } - if (tar->Type != ST_ACTOR) { - return; - } - tar->Hide(); -} - -void GameScript::MakeGlobal(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - Actor* act = ( Actor* ) Sender; - core->GetGame()->AddNPC( act ); -} - -void GameScript::UnMakeGlobal(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - Actor* act = ( Actor* ) Sender; - int slot; - slot = core->GetGame()->InStore( act ); - if (slot >= 0) { - core->GetGame()->DelNPC( slot ); - } -} - -//this apparently doesn't check the gold, thus could be used from non actors -void GameScript::GivePartyGoldGlobal(Scriptable* Sender, Action* parameters) -{ - ieDword gold = (ieDword) CheckVariable( Sender, parameters->string0Parameter, parameters->string1Parameter ); - if (Sender->Type == ST_ACTOR) { - Actor* act = ( Actor* ) Sender; - ieDword mygold = act->GetStat(IE_GOLD); - if (mygold < gold) { - gold = mygold; - } - //will get saved, not adjusted - act->SetBase(IE_GOLD, act->GetBase(IE_GOLD)-gold); - } - core->GetGame()->AddGold(gold); -} - -void GameScript::CreatePartyGold(Scriptable* /*Sender*/, Action* parameters) -{ - core->GetGame()->AddGold(parameters->int0Parameter); -} - -void GameScript::GivePartyGold(Scriptable* Sender, Action* parameters) -{ - ieDword gold = (ieDword) parameters->int0Parameter; - if (Sender->Type == ST_ACTOR) { - Actor* act = ( Actor* ) Sender; - ieDword mygold = act->GetStat(IE_GOLD); - if (mygold < gold) { - gold = mygold; - } - //will get saved, not adjusted - act->SetBase(IE_GOLD, act->GetBase(IE_GOLD)-gold); - } - core->GetGame()->AddGold(gold); -} - -void GameScript::DestroyPartyGold(Scriptable* /*Sender*/, Action* parameters) -{ - int gold = core->GetGame()->PartyGold; - if (gold>parameters->int0Parameter) { - gold=parameters->int0Parameter; - } - core->GetGame()->AddGold(-gold); -} - -void GameScript::TakePartyGold(Scriptable* Sender, Action* parameters) -{ - ieDword gold = core->GetGame()->PartyGold; - if (gold>(ieDword) parameters->int0Parameter) { - gold=(ieDword) parameters->int0Parameter; - } - core->GetGame()->AddGold((ieDword) -(int) gold); - if (Sender->Type == ST_ACTOR) { - Actor* act = ( Actor* ) Sender; - act->SetBase(IE_GOLD, act->GetBase(IE_GOLD)+gold); - } -} - -void GameScript::AddXPObject(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - return; - } - if (tar->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) tar; - int xp = parameters->int0Parameter; - if (displaymsg->HasStringReference(STR_GOTQUESTXP)) { - core->GetTokenDictionary()->SetAtCopy("EXPERIENCEAMOUNT", xp); - displaymsg->DisplayConstantStringName(STR_GOTQUESTXP, 0xbcefbc, actor); - } else { - displaymsg->DisplayConstantStringValue(STR_GOTXP, 0xbcefbc, (ieDword)xp); - } - actor->AddExperience(xp); -} - -void GameScript::AddXP2DA(Scriptable* /*Sender*/, Action* parameters) -{ - AutoTable xptable; - - if (core->HasFeature(GF_HAS_EXPTABLE) ) { - xptable.load("exptable"); - } else { - xptable.load("xplist"); - } - - if (parameters->int0Parameter>0) { - displaymsg->DisplayString(parameters->int0Parameter, 0x40f0f000,IE_STR_SOUND); - } - if (!xptable) { - printMessage("GameScript","Can't perform ADDXP2DA",LIGHT_RED); - return; - } - const char * xpvalue = xptable->QueryField( parameters->string0Parameter, "0" ); //level is unused - - if ( xpvalue[0]=='P' && xpvalue[1]=='_') { - //divide party xp - core->GetGame()->ShareXP(atoi(xpvalue+2), SX_DIVIDE ); - } else { - //give xp everyone - core->GetGame()->ShareXP(atoi(xpvalue), 0 ); - } -} - -void GameScript::AddExperienceParty(Scriptable* /*Sender*/, Action* parameters) -{ - core->GetGame()->ShareXP(parameters->int0Parameter, SX_DIVIDE); -} - -//this needs moncrate.2da, but otherwise independent from GF_CHALLENGERATING -void GameScript::AddExperiencePartyCR(Scriptable* /*Sender*/, Action* parameters) -{ - core->GetGame()->ShareXP(parameters->int0Parameter, SX_DIVIDE|SX_CR); -} - -void GameScript::AddExperiencePartyGlobal(Scriptable* Sender, Action* parameters) -{ - ieDword xp = CheckVariable( Sender, parameters->string0Parameter, parameters->string1Parameter ); - core->GetGame()->ShareXP(xp, SX_DIVIDE); -} - -void GameScript::SetMoraleAI(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - Actor* act = ( Actor* ) Sender; - act->SetBase(IE_MORALE, parameters->int0Parameter); -} - -void GameScript::IncMoraleAI(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - Actor* act = ( Actor* ) Sender; - act->SetBase(IE_MORALE, parameters->int0Parameter+act->GetBase(IE_MORALE) ); -} - -void GameScript::MoraleSet(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - return; - } - if (tar->Type != ST_ACTOR) { - return; - } - Actor* act = ( Actor* ) tar; - act->SetBase(IE_MORALEBREAK, parameters->int0Parameter); -} - -void GameScript::MoraleInc(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - return; - } - if (tar->Type != ST_ACTOR) { - return; - } - Actor* act = ( Actor* ) tar; - act->SetBase(IE_MORALEBREAK, act->GetBase(IE_MORALEBREAK)+parameters->int0Parameter); -} - -void GameScript::MoraleDec(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - return; - } - if (tar->Type != ST_ACTOR) { - return; - } - Actor* act = ( Actor* ) tar; - act->SetBase(IE_MORALEBREAK, act->GetBase(IE_MORALEBREAK)-parameters->int0Parameter); -} - -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); - act->SetBase( IE_EA, EA_PC ); - if (core->HasFeature( GF_HAS_DPLAYER )) { - /* we must reset various existing scripts */ - act->SetScript( "DEFAULT", AI_SCRIPT_LEVEL, true ); - act->SetScript( "", SCR_RACE, true ); - act->SetScript( "", SCR_GENERAL, true ); - act->SetScript( "DPLAYER2", SCR_DEFAULT, false ); - } - AutoTable pdtable("pdialog"); - if (pdtable) { - const char* scriptname = act->GetScriptName(); - ieResRef resref; - //set dialog only if we got a row - if (pdtable->GetRowIndex( scriptname ) != -1) { - strnlwrcpy(resref, pdtable->QueryField( scriptname, "JOIN_DIALOG_FILE"),8); - act->SetDialog( resref ); - } - } - game->JoinParty( act, JP_JOIN ); -} - -void GameScript::LeaveParty(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - Actor* act = ( Actor* ) Sender; - core->GetGame()->LeaveParty( act ); -} - -//HideCreature hides only the visuals of a creature -//(feet circle and avatar) -//the scripts of the creature are still running -//iwd2 stores this flag in the MC field -void GameScript::HideCreature(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) tar; - actor->BaseStats[IE_AVATARREMOVAL]=parameters->int0Parameter; -} - -//i have absolutely no idea why this is needed when we have HideCreature -void GameScript::ForceHide(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - tar=Sender; - } - if (tar->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) tar; - actor->BaseStats[IE_AVATARREMOVAL]=1; -} - -void GameScript::Activate(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type != ST_ACTOR) { - return; - } - // Deactivate hides, so this should unhide.. - //tar->Activate(); - tar->Unhide(); -} - -void GameScript::ForceLeaveAreaLUA(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) tar; - //the LoadMos ResRef may be empty - strncpy(core->GetGame()->LoadMos, parameters->string1Parameter,8); - MoveBetweenAreasCore( actor, parameters->string0Parameter, parameters->pointParameter, parameters->int0Parameter, true); -} - -void GameScript::LeaveAreaLUA(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) Sender; - //the LoadMos ResRef may be empty - strncpy(core->GetGame()->LoadMos, parameters->string1Parameter,8); - MoveBetweenAreasCore( actor, parameters->string0Parameter, parameters->pointParameter, parameters->int0Parameter, true); -} - -//this is a blocking action, because we have to move to the Entry -void GameScript::LeaveAreaLUAEntry(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Game *game = core->GetGame(); - strncpy(game->LoadMos, parameters->string1Parameter,8); - Point p = GetEntryPoint(parameters->string0Parameter, parameters->string1Parameter); - if (p.isempty()) { - Sender->ReleaseCurrentAction(); - return; - } - parameters->pointParameter=p; - strcpy(parameters->string1Parameter, ""); - LeaveAreaLUA(Sender, parameters); - Sender->ReleaseCurrentAction(); -} - -void GameScript::LeaveAreaLUAPanic(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) Sender; - strncpy(core->GetGame()->LoadMos, parameters->string1Parameter,8); - MoveBetweenAreasCore( actor, parameters->string0Parameter, parameters->pointParameter, parameters->int0Parameter, true); -} - -//this is a blocking action, because we have to move to the Entry -void GameScript::LeaveAreaLUAPanicEntry(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Game *game = core->GetGame(); - strncpy(game->LoadMos, parameters->string1Parameter,8); - Point p = GetEntryPoint(parameters->string0Parameter, parameters->string1Parameter); - if (p.isempty()) { - Sender->ReleaseCurrentAction(); - return; - } - parameters->pointParameter=p; - strcpy(parameters->string1Parameter, ""); - LeaveAreaLUAPanic(Sender, parameters); - Sender->ReleaseCurrentAction(); -} - -void GameScript::SetToken(Scriptable* /*Sender*/, Action* parameters) -{ - //SetAt takes a newly created reference (no need of free/copy) - char * str = core->GetString( parameters->int0Parameter); - core->GetTokenDictionary()->SetAt( parameters->string1Parameter, str); -} - -//Assigns a numeric variable to the token -void GameScript::SetTokenGlobal(Scriptable* Sender, Action* parameters) -{ - ieDword value = CheckVariable( Sender, parameters->string0Parameter ); - //using SetAtCopy because we need a copy of the value - core->GetTokenDictionary()->SetAtCopy( parameters->string1Parameter, value ); -} - -//Assigns the target object's name (not scriptname) to the token -void GameScript::SetTokenObject(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) tar; - core->GetTokenDictionary()->SetAtCopy( parameters->string0Parameter, actor->GetName(0) ); -} - -void GameScript::PlayDead(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Actor* actor = ( Actor* ) Sender; - - actor->CurrentActionInterruptable = false; - if (!Sender->CurrentActionTicks && parameters->int0Parameter) { - // set countdown on first run - Sender->CurrentActionState = parameters->int0Parameter; - actor->SetStance( IE_ANI_DIE ); - } - if (Sender->CurrentActionState <= 0) { - actor->SetStance( IE_ANI_GET_UP ); - Sender->ReleaseCurrentAction(); - } - actor->CurrentActionState--; -} - -void GameScript::PlayDeadInterruptable(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Actor* actor = ( Actor* ) Sender; - - if (!Sender->CurrentActionTicks && parameters->int0Parameter) { - // set countdown on first run - Sender->CurrentActionState = parameters->int0Parameter; - actor->SetStance( IE_ANI_DIE ); - } - if (Sender->CurrentActionState <= 0) { - actor->SetStance( IE_ANI_GET_UP ); - Sender->ReleaseCurrentAction(); - } - actor->CurrentActionState--; -} - -/* this may not be correct, just a placeholder you can fix */ -void GameScript::Swing(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) Sender; - actor->SetStance( IE_ANI_ATTACK ); - actor->SetWait( 1 ); -} - -/* this may not be correct, just a placeholder you can fix */ -void GameScript::SwingOnce(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) Sender; - actor->SetStance( IE_ANI_ATTACK ); - actor->SetWait( 1 ); -} - -void GameScript::Recoil(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) Sender; - actor->SetStance( IE_ANI_DAMAGE ); - actor->SetWait( 1 ); -} - -void GameScript::AnkhegEmerge(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) Sender; - if (actor->GetStance()!=IE_ANI_EMERGE) { - actor->SetStance( IE_ANI_EMERGE ); - actor->SetWait( 1 ); - } -} - -void GameScript::AnkhegHide(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) Sender; - if (actor->GetStance()!=IE_ANI_HIDE) { - actor->SetStance( IE_ANI_HIDE ); - actor->SetWait( 1 ); - } -} - -void GameScript::GlobalSetGlobal(Scriptable* Sender, Action* parameters) -{ - ieDword value = CheckVariable( Sender, parameters->string0Parameter ); - SetVariable( Sender, parameters->string1Parameter, value ); -} - -/* adding the second variable to the first, they must be GLOBAL */ -void GameScript::AddGlobals(Scriptable* Sender, Action* parameters) -{ - ieDword value1 = CheckVariable( Sender, parameters->string0Parameter, "GLOBAL"); - ieDword value2 = CheckVariable( Sender, parameters->string1Parameter, "GLOBAL"); - SetVariable( Sender, parameters->string0Parameter, "GLOBAL", value1 + value2 ); -} - -/* adding the second variable to the first, they could be area or locals */ -void GameScript::GlobalAddGlobal(Scriptable* Sender, Action* parameters) -{ - ieDword value1 = CheckVariable( Sender, - parameters->string0Parameter ); - ieDword value2 = CheckVariable( Sender, - parameters->string1Parameter ); - SetVariable( Sender, parameters->string0Parameter, value1 + value2 ); -} - -/* adding the number to the global, they could be area or locals */ -void GameScript::IncrementGlobal(Scriptable* Sender, Action* parameters) -{ - ieDword value = CheckVariable( Sender, parameters->string0Parameter ); - SetVariable( Sender, parameters->string0Parameter, - value + parameters->int0Parameter ); -} - -/* adding the number to the global ONLY if the first global is zero */ -void GameScript::IncrementGlobalOnce(Scriptable* Sender, Action* parameters) -{ - ieDword value = CheckVariable( Sender, parameters->string0Parameter ); - if (value != 0) { - return; - } - value = CheckVariable( Sender, parameters->string1Parameter ); - SetVariable( Sender, parameters->string1Parameter, - value + parameters->int0Parameter ); -} - -void GameScript::GlobalSubGlobal(Scriptable* Sender, Action* parameters) -{ - ieDword value1 = CheckVariable( Sender, - parameters->string0Parameter ); - ieDword value2 = CheckVariable( Sender, - parameters->string1Parameter ); - SetVariable( Sender, parameters->string0Parameter, value1 - value2 ); -} - -void GameScript::GlobalAndGlobal(Scriptable* Sender, Action* parameters) -{ - ieDword value1 = CheckVariable( Sender, - parameters->string0Parameter ); - ieDword value2 = CheckVariable( Sender, - parameters->string1Parameter ); - SetVariable( Sender, parameters->string0Parameter, value1 && value2 ); -} - -void GameScript::GlobalOrGlobal(Scriptable* Sender, Action* parameters) -{ - ieDword value1 = CheckVariable( Sender, - parameters->string0Parameter ); - ieDword value2 = CheckVariable( Sender, - parameters->string1Parameter ); - SetVariable( Sender, parameters->string0Parameter, value1 || value2 ); -} - -void GameScript::GlobalBOrGlobal(Scriptable* Sender, Action* parameters) -{ - ieDword value1 = CheckVariable( Sender, - parameters->string0Parameter ); - ieDword value2 = CheckVariable( Sender, - parameters->string1Parameter ); - SetVariable( Sender, parameters->string0Parameter, value1 | value2 ); -} - -void GameScript::GlobalBAndGlobal(Scriptable* Sender, Action* parameters) -{ - ieDword value1 = CheckVariable( Sender, - parameters->string0Parameter ); - ieDword value2 = CheckVariable( Sender, - parameters->string1Parameter ); - SetVariable( Sender, parameters->string0Parameter, value1 & value2 ); -} - -void GameScript::GlobalXorGlobal(Scriptable* Sender, Action* parameters) -{ - ieDword value1 = CheckVariable( Sender, - parameters->string0Parameter ); - ieDword value2 = CheckVariable( Sender, - parameters->string1Parameter ); - SetVariable( Sender, parameters->string0Parameter, value1 ^ value2 ); -} - -void GameScript::GlobalBOr(Scriptable* Sender, Action* parameters) -{ - ieDword value1 = CheckVariable( Sender, - parameters->string0Parameter ); - SetVariable( Sender, parameters->string0Parameter, - value1 | parameters->int0Parameter ); -} - -void GameScript::GlobalBAnd(Scriptable* Sender, Action* parameters) -{ - ieDword value1 = CheckVariable( Sender, - parameters->string0Parameter ); - SetVariable( Sender, parameters->string0Parameter, - value1 & parameters->int0Parameter ); -} - -void GameScript::GlobalXor(Scriptable* Sender, Action* parameters) -{ - ieDword value1 = CheckVariable( Sender, - parameters->string0Parameter ); - SetVariable( Sender, parameters->string0Parameter, - value1 ^ parameters->int0Parameter ); -} - -void GameScript::GlobalMax(Scriptable* Sender, Action* parameters) -{ - long value1 = CheckVariable( Sender, parameters->string0Parameter ); - if (value1 > parameters->int0Parameter) { - SetVariable( Sender, parameters->string0Parameter, value1 ); - } -} - -void GameScript::GlobalMin(Scriptable* Sender, Action* parameters) -{ - long value1 = CheckVariable( Sender, parameters->string0Parameter ); - if (value1 < parameters->int0Parameter) { - SetVariable( Sender, parameters->string0Parameter, value1 ); - } -} - -void GameScript::BitClear(Scriptable* Sender, Action* parameters) -{ - ieDword value1 = CheckVariable( Sender, - parameters->string0Parameter ); - SetVariable( Sender, parameters->string0Parameter, - value1 & ~parameters->int0Parameter ); -} - -void GameScript::GlobalShL(Scriptable* Sender, Action* parameters) -{ - ieDword value1 = CheckVariable( Sender, - parameters->string0Parameter ); - ieDword value2 = parameters->int0Parameter; - if (value2 > 31) { - value1 = 0; - } else { - value1 <<= value2; - } - SetVariable( Sender, parameters->string0Parameter, value1 ); -} - -void GameScript::GlobalShR(Scriptable* Sender, Action* parameters) -{ - ieDword value1 = CheckVariable( Sender, - parameters->string0Parameter ); - ieDword value2 = parameters->int0Parameter; - if (value2 > 31) { - value1 = 0; - } else { - value1 >>= value2; - } - SetVariable( Sender, parameters->string0Parameter, value1 ); -} - -void GameScript::GlobalMaxGlobal(Scriptable* Sender, Action* parameters) -{ - ieDword value1 = CheckVariable( Sender, parameters->string0Parameter ); - ieDword value2 = CheckVariable( Sender, parameters->string1Parameter ); - if (value1 < value2) { - SetVariable( Sender, parameters->string0Parameter, value2 ); - } -} - -void GameScript::GlobalMinGlobal(Scriptable* Sender, Action* parameters) -{ - ieDword value1 = CheckVariable( Sender, parameters->string0Parameter ); - ieDword value2 = CheckVariable( Sender, parameters->string1Parameter ); - if (value1 > value2) { - SetVariable( Sender, parameters->string0Parameter, value2 ); - } -} - -void GameScript::GlobalShLGlobal(Scriptable* Sender, Action* parameters) -{ - ieDword value1 = CheckVariable( Sender, parameters->string0Parameter ); - ieDword value2 = CheckVariable( Sender, parameters->string1Parameter ); - if (value2 > 31) { - value1 = 0; - } else { - value1 <<= value2; - } - SetVariable( Sender, parameters->string0Parameter, value1 ); -} -void GameScript::GlobalShRGlobal(Scriptable* Sender, Action* parameters) -{ - ieDword value1 = CheckVariable( Sender, parameters->string0Parameter ); - ieDword value2 = CheckVariable( Sender, parameters->string1Parameter ); - if (value2 > 31) { - value1 = 0; - } else { - value1 >>= value2; - } - SetVariable( Sender, parameters->string0Parameter, value1 ); -} - -void GameScript::ClearAllActions(Scriptable* Sender, Action* /*parameters*/) -{ - Actor *except = NULL; - if (Sender->Type==ST_ACTOR) { - except = (Actor *) Sender; - } - Map *map = Sender->GetCurrentArea(); - ieDword gametime = core->GetGame()->GameTime; - int i = map->GetActorCount(true); - while(i--) { - Actor* act = map->GetActor(i,true); - if (act && act!=except) { - if (!act->ValidTarget(GA_NO_DEAD) ) { - continue; - } - //Do we need this??? - if (!act->Schedule(gametime, false) ) { - continue; - } - act->ClearActions(); - act->ClearPath(); - act->SetModal(MS_NONE); - } - } -} - -void GameScript::ClearActions(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = Sender; - if (parameters->objects[1]) { - tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - printMessage("GameScript","Couldn't find target for ClearActions!",YELLOW); - parameters->objects[1]->Dump(); - return; - } - } - tar->ClearActions(); - if (tar->Type==ST_ACTOR) { - Actor* act = (Actor *) tar; - act->ClearPath(); - //not sure about this - //act->SetModal(MS_NONE); - } -} - -void GameScript::SetNumTimesTalkedTo(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) Sender; - actor->TalkCount = parameters->int0Parameter; -} - -void GameScript::StartMovie(Scriptable* Sender, Action* parameters) -{ - core->PlayMovie( parameters->string0Parameter ); - Sender->ReleaseCurrentAction(); // should this be blocking? -} - -void GameScript::SetLeavePartyDialogFile(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - AutoTable pdtable("pdialog"); - Actor* act = ( Actor* ) Sender; - const char* scriptingname = act->GetScriptName(); - act->SetDialog( pdtable->QueryField( scriptingname, "POST_DIALOG_FILE" ) ); -} - -void GameScript::TextScreen(Scriptable* Sender, Action* parameters) -{ - strnlwrcpy(core->GetGame()->LoadMos, parameters->string0Parameter,8); - core->GetGUIScriptEngine()->RunFunction( "TextScreen", "StartTextScreen" ); - core->GetVideoDriver()->SetMouseEnabled(true); - Sender->SetWait(1); - Sender->ReleaseCurrentAction(); // should this be blocking? -} - -void GameScript::IncrementChapter(Scriptable* Sender, Action* parameters) -{ - TextScreen(Sender, parameters); // textscreen will release blocking for us - core->GetGame()->IncrementChapter(); -} - -void GameScript::SetCriticalPathObject(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) tar; - if (parameters->int0Parameter) { - actor->SetMCFlag(MC_PLOT_CRITICAL, BM_OR); - } else { - actor->SetMCFlag(MC_PLOT_CRITICAL, BM_NAND); - } -} - -void GameScript::SetBeenInPartyFlags(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) Sender; - //it is bit 15 of the multi-class flags (confirmed) - actor->SetMCFlag(MC_BEENINPARTY, BM_OR); -} - -/*iwd2 sets the high MC bits this way*/ -void GameScript::SetCreatureAreaFlag(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) Sender; - actor->SetMCFlag(parameters->int0Parameter, parameters->int1Parameter); -} - -//this will be a global change, fixme if it should be local -void GameScript::SetTextColor(Scriptable* /*Sender*/, Action* parameters) -{ - Color c; - memcpy(&c,¶meters->int0Parameter,4); - core->SetInfoTextColor(c); -} - -void GameScript::BitGlobal(Scriptable* Sender, Action* parameters) -{ - ieDword value = CheckVariable(Sender, parameters->string0Parameter ); - HandleBitMod( value, parameters->int0Parameter, parameters->int1Parameter); - SetVariable(Sender, parameters->string0Parameter, value); -} - -void GameScript::GlobalBitGlobal(Scriptable* Sender, Action* parameters) -{ - ieDword value1 = CheckVariable(Sender, parameters->string0Parameter ); - ieDword value2 = CheckVariable(Sender, parameters->string1Parameter ); - HandleBitMod( value1, value2, parameters->int1Parameter); - SetVariable(Sender, parameters->string0Parameter, value1); -} - -void GameScript::SetVisualRange(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) Sender; - actor->SetBase(IE_VISUALRANGE,parameters->int0Parameter); -} - -void GameScript::MakeUnselectable(Scriptable* Sender, Action* parameters) -{ - Sender->UnselectableTimer=parameters->int0Parameter; - - //update color - if (Sender->Type != ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) Sender; - if (parameters->int0Parameter) { - // flags may be wrong - core->GetGame()->SelectActor(actor, false, SELECT_QUIET); - } - - actor->SetCircleSize(); -} - -void GameScript::Debug(Scriptable* /*Sender*/, Action* parameters) -{ - InDebug=parameters->int0Parameter; - printMessage("GameScript","%s",YELLOW,parameters->string0Parameter); -} - -void GameScript::IncrementProficiency(Scriptable* Sender, Action* parameters) -{ - unsigned int idx = parameters->int0Parameter; - if (idx>31) { - return; - } - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - return; - } - if (tar->Type != ST_ACTOR) { - return; - } - Actor* target = ( Actor* ) tar; - //start of the proficiency stats - target->SetBase(IE_PROFICIENCYBASTARDSWORD+idx, - target->GetBase(IE_PROFICIENCYBASTARDSWORD+idx)+parameters->int1Parameter); -} - -void GameScript::IncrementExtraProficiency(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - return; - } - if (tar->Type != ST_ACTOR) { - return; - } - Actor* target = ( Actor* ) tar; - target->SetBase(IE_FREESLOTS, target->GetBase(IE_FREESLOTS)+parameters->int0Parameter); -} - -//the third parameter is a GemRB extension -void GameScript::AddJournalEntry(Scriptable* /*Sender*/, Action* parameters) -{ - core->GetGame()->AddJournalEntry(parameters->int0Parameter, parameters->int1Parameter, parameters->int2Parameter); -} - -void GameScript::SetQuestDone(Scriptable* /*Sender*/, Action* parameters) -{ - Game *game = core->GetGame(); - game->DeleteJournalEntry(parameters->int0Parameter); - game->AddJournalEntry(parameters->int0Parameter, IE_GAM_QUEST_DONE, parameters->int2Parameter); - -} - -void GameScript::RemoveJournalEntry(Scriptable* /*Sender*/, Action* parameters) -{ - core->GetGame()->DeleteJournalEntry(parameters->int0Parameter); -} - -void GameScript::SetInternal(Scriptable* Sender, Action* parameters) -{ - unsigned int idx = parameters->int0Parameter; - if (idx>15) { - return; - } - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - return; - } - if (tar->Type != ST_ACTOR) { - return; - } - Actor* target = ( Actor* ) tar; - //start of the internal stats - target->SetBase(IE_INTERNAL_0+idx, parameters->int1Parameter); -} - -void GameScript::IncInternal(Scriptable* Sender, Action* parameters) -{ - unsigned int idx = parameters->int0Parameter; - if (idx>15) { - return; - } - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type != ST_ACTOR) { - return; - } - Actor* target = ( Actor* ) tar; - //start of the internal stats - target->SetBase(IE_INTERNAL_0+idx, - target->GetBase(IE_INTERNAL_0+idx)+parameters->int1Parameter); -} - -void GameScript::DestroyAllEquipment(Scriptable* Sender, Action* /*parameters*/) -{ - Inventory *inv=NULL; - - switch (Sender->Type) { - case ST_ACTOR: - inv = &(((Actor *) Sender)->inventory); - break; - case ST_CONTAINER: - inv = &(((Container *) Sender)->inventory); - break; - default:; - } - if (inv) { - inv->DestroyItem("",0,(ieDword) ~0); //destroy any and all - } -} - -void GameScript::DestroyItem(Scriptable* Sender, Action* parameters) -{ - Inventory *inv=NULL; - - switch (Sender->Type) { - case ST_ACTOR: - inv = &(((Actor *) Sender)->inventory); - break; - case ST_CONTAINER: - inv = &(((Container *) Sender)->inventory); - break; - default:; - } - if (inv) { - inv->DestroyItem(parameters->string0Parameter,0,1); //destroy one (even indestructible?) - } -} - -//negative destroygold creates gold -void GameScript::DestroyGold(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) - return; - Actor *act=(Actor *) Sender; - int max=(int) act->GetStat(IE_GOLD); - if (parameters->int0Parameter != 0) { - if (max>parameters->int0Parameter) { - max=parameters->int0Parameter; - } - } - act->SetBase(IE_GOLD, act->GetBase(IE_GOLD)-max); -} - -void GameScript::DestroyPartyItem(Scriptable* /*Sender*/, Action* parameters) -{ - Game *game = core->GetGame(); - int i = game->GetPartySize(false); - ieDword count; - if (parameters->int0Parameter) { - count=0; - } else { - count=1; - } - while (i--) { - Inventory *inv = &(game->GetPC( i,false )->inventory); - int res=inv->DestroyItem(parameters->string0Parameter,0,count); - if ( (count == 1) && res) { - break; - } - } -} - -/* this is a gemrb extension */ -void GameScript::DestroyPartyItemNum(Scriptable* /*Sender*/, Action* parameters) -{ - Game *game = core->GetGame(); - int i = game->GetPartySize(false); - ieDword count; - count = parameters->int0Parameter; - while (i--) { - Inventory *inv = &(game->GetPC( i,false )->inventory); - count -= inv->DestroyItem(parameters->string0Parameter,0,count); - if (!count ) { - break; - } - } -} - -void GameScript::DestroyAllDestructableEquipment(Scriptable* Sender, Action* /*parameters*/) -{ - Inventory *inv=NULL; - - switch (Sender->Type) { - case ST_ACTOR: - inv = &(((Actor *) Sender)->inventory); - break; - case ST_CONTAINER: - inv = &(((Container *) Sender)->inventory); - break; - default:; - } - if (inv) { - inv->DestroyItem("", IE_INV_ITEM_DESTRUCTIBLE, (ieDword) ~0); - } -} - -void GameScript::SetApparentName(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type != ST_ACTOR) { - return; - } - Actor* target = ( Actor* ) tar; - target->SetName(parameters->int0Parameter,1); -} - -void GameScript::SetRegularName(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type != ST_ACTOR) { - return; - } - Actor* target = ( Actor* ) tar; - target->SetName(parameters->int0Parameter,2); -} - -/** this is a gemrb extension */ -void GameScript::UnloadArea(Scriptable* /*Sender*/, Action* parameters) -{ - int map=core->GetGame()->FindMap(parameters->string0Parameter); - if (map>=0) { - core->GetGame()->DelMap(map, parameters->int0Parameter); - } -} - -static EffectRef fx_death_ref = { "Death", -1 }; -void GameScript::Kill(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type != ST_ACTOR) { - return; - } - Actor* target = ( Actor* ) tar; - Effect *fx = EffectQueue::CreateEffect(fx_death_ref, 0, 0, FX_DURATION_INSTANT_PERMANENT); - target->fxqueue.AddEffect(fx, false); - delete fx; -} - -void GameScript::SetGabber(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type != ST_ACTOR) { - return; - } - GameControl* gc = core->GetGameControl(); - if (gc->GetDialogueFlags()&DF_IN_DIALOG) { - gc->dialoghandler->speakerID = tar->GetGlobalID(); - } else { - printMessage("GameScript","Can't set gabber!",YELLOW); - } -} - -void GameScript::ReputationSet(Scriptable* /*Sender*/, Action* parameters) -{ - core->GetGame()->SetReputation(parameters->int0Parameter*10); -} - -void GameScript::ReputationInc(Scriptable* /*Sender*/, Action* parameters) -{ - Game *game = core->GetGame(); - game->SetReputation( (int) game->Reputation + parameters->int0Parameter*10); -} - -void GameScript::FullHeal(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type != ST_ACTOR) { - return; - } - Actor *scr = (Actor *) tar; - //0 means full healing - //Heal() might contain curing of some conditions - //if FullHeal doesn't do that, replace this with a SetBase - //fullhealex might still be the curing action - scr->Heal(0); -} - -void GameScript::RemovePaladinHood(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor *act = (Actor *) Sender; - act->ApplyKit(true); - act->SetMCFlag(MC_FALLEN_PALADIN, BM_OR); - if (act->InParty) displaymsg->DisplayConstantStringName(STR_PALADIN_FALL, 0xbcefbc, act); -} - -void GameScript::RemoveRangerHood(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor *act = (Actor *) Sender; - act->ApplyKit(true); - act->SetMCFlag(MC_FALLEN_RANGER, BM_OR); - if (act->InParty) displaymsg->DisplayConstantStringName(STR_RANGER_FALL, 0xbcefbc, act); -} - -void GameScript::RegainPaladinHood(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor *act = (Actor *) Sender; - act->SetMCFlag(MC_FALLEN_PALADIN, BM_NAND); - act->ApplyKit(false); -} - -void GameScript::RegainRangerHood(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor *act = (Actor *) Sender; - act->SetMCFlag(MC_FALLEN_RANGER, BM_NAND); - act->ApplyKit(false); -} - -//transfering item from Sender to target, target must be an actor -//if target can't get it, it will be dropped at its feet -//a container or an actor can take an item from someone -void GameScript::GetItem(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - MoveItemCore(tar, Sender, parameters->string0Parameter,0,0); -} - -//getting one single item -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,IE_INV_ITEM_UNDROPPABLE,IE_INV_ITEM_UNSTEALABLE); - if (res!=MIC_NOITEM) return; - } -} - -//getting x single item -void GameScript::TakePartyItemNum(Scriptable* Sender, Action* parameters) -{ - int count = parameters->int0Parameter; - Game *game=core->GetGame(); - int i=game->GetPartySize(false); - while (i--) { - int res=MoveItemCore(game->GetPC(i,false), Sender, parameters->string0Parameter,IE_INV_ITEM_UNDROPPABLE, IE_INV_ITEM_UNSTEALABLE); - if (res == MIC_GOTITEM) { - i++; - count--; - } - if (!count) return; - } -} - -void GameScript::TakePartyItemRange(Scriptable* Sender, Action* parameters) -{ - Game *game=core->GetGame(); - int i=game->GetPartySize(false); - while (i--) { - Actor *ac = game->GetPC(i,false); - if (Distance(Sender, ac)string0Parameter,IE_INV_ITEM_UNDROPPABLE,IE_INV_ITEM_UNSTEALABLE)==MIC_GOTITEM) { } - } - } -} - -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,IE_INV_ITEM_UNDROPPABLE, IE_INV_ITEM_UNSTEALABLE)==MIC_GOTITEM) { } - } -} - -//an actor can 'give' an item to a container or another actor -void GameScript::GiveItem(Scriptable *Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - MoveItemCore(Sender, tar, parameters->string0Parameter,0,0); -} - -//this action creates an item in a container or a creature -//if there is an object it works as GiveItemCreate -//otherwise it creates the item on the Sender -void GameScript::CreateItem(Scriptable *Sender, Action* parameters) -{ - Scriptable* tar; - if (parameters->objects[1]) { - tar = GetActorFromObject( Sender, parameters->objects[1] ); - } else { - tar = Sender; - } - if (!tar) - return; - Inventory *myinv; - - switch(tar->Type) { - case ST_ACTOR: - myinv = &((Actor *) tar)->inventory; - break; - case ST_CONTAINER: - myinv = &((Container *) tar)->inventory; - break; - default: - return; - } - - CREItem *item = new CREItem(); - if (!CreateItemCore(item, parameters->string0Parameter, parameters->int0Parameter, parameters->int1Parameter, parameters->int2Parameter)) { - delete item; - return; - } - if (tar->Type==ST_CONTAINER) { - myinv->AddItem(item); - } else { - if ( ASI_SUCCESS != myinv->AddSlotItem(item, SLOT_ONLYINVENTORY)) { - Map *map=tar->GetCurrentArea(); - // drop it at my feet - map->AddItemToLocation(tar->Pos, item); - if (((Actor *)tar)->InParty) displaymsg->DisplayConstantString(STR_INVFULL_ITEMDROP, 0xbcefbc); - } else { - if (((Actor *)tar)->InParty) displaymsg->DisplayConstantString(STR_GOTITEM, 0xbcefbc); - } - } -} - -void GameScript::CreateItemNumGlobal(Scriptable *Sender, Action* parameters) -{ - Inventory *myinv; - - switch(Sender->Type) { - case ST_ACTOR: - myinv = &((Actor *) Sender)->inventory; - break; - case ST_CONTAINER: - myinv = &((Container *) Sender)->inventory; - break; - default: - return; - } - int value = CheckVariable( Sender, parameters->string0Parameter ); - CREItem *item = new CREItem(); - if (!CreateItemCore(item, parameters->string1Parameter, value, 0, 0)) { - delete item; - return; - } - if (Sender->Type==ST_CONTAINER) { - myinv->AddItem(item); - } else { - if ( ASI_SUCCESS != myinv->AddSlotItem(item, SLOT_ONLYINVENTORY)) { - Map *map=Sender->GetCurrentArea(); - // drop it at my feet - map->AddItemToLocation(Sender->Pos, item); - if (((Actor *)Sender)->InParty) displaymsg->DisplayConstantString(STR_INVFULL_ITEMDROP, 0xbcefbc); - } else { - if (((Actor *)Sender)->InParty) displaymsg->DisplayConstantString(STR_GOTITEM, 0xbcefbc); - } - } -} - -void GameScript::TakeItemReplace(Scriptable *Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type != ST_ACTOR) { - return; - } - - Actor *scr = (Actor *) tar; - CREItem *item; - int slot = scr->inventory.RemoveItem(parameters->string1Parameter, IE_INV_ITEM_UNDROPPABLE, &item); - if (!item) { - item = new CREItem(); - } - if (!CreateItemCore(item, parameters->string0Parameter, -1, 0, 0)) { - delete item; - return; - } - if (ASI_SUCCESS != scr->inventory.AddSlotItem(item,slot)) { - Map *map = scr->GetCurrentArea(); - map->AddItemToLocation(Sender->Pos, item); - } -} - -//same as equipitem, but with additional slots parameter, and object to perform action -void GameScript::XEquipItem(Scriptable *Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - - if (!tar || tar->Type!=ST_ACTOR) { - return; - } - Actor *actor = (Actor *) tar; - int slot = actor->inventory.FindItem(parameters->string0Parameter, 0); - if (slot<0) { - return; - } - actor->inventory.EquipItem(slot); - actor->ReinitQuickSlots(); -} - -//GemRB extension: if int1Parameter is nonzero, don't destroy existing items -void GameScript::FillSlot(Scriptable *Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - - CREItem *tmp = NULL; - Actor *actor = (Actor *) Sender; - int slot = parameters->int0Parameter; - - //free up target slot - tmp = actor->inventory.RemoveItem(slot); - - actor->inventory.TryEquipAll(slot); - - if (tmp) { - if (actor->inventory.HasItemInSlot("",slot) ) { - slot = SLOT_ONLYINVENTORY; - } - - //reequip original item - if(actor->inventory.AddSlotItem(tmp, slot)!=ASI_SUCCESS) { - delete tmp; - } - } -} - -//iwd2 also has a flag for unequip (it might collide with original!) -void GameScript::EquipItem(Scriptable *Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor *actor = (Actor *) Sender; - int slot = actor->inventory.FindItem(parameters->string0Parameter, IE_INV_ITEM_UNDROPPABLE); - if (slot<0) { - return; - } - - int slot2; - - if (parameters->int0Parameter) { - //unequip item, and move it to the inventory - slot2 = SLOT_ONLYINVENTORY; - } else { - //equip item if possible - slot2 = SLOT_AUTOEQUIP; - } - CREItem *si = actor->inventory.RemoveItem(slot); - if (si) { - if (actor->inventory.AddSlotItem(si, slot2)==ASI_FAILED) { - Map *map = Sender->GetCurrentArea(); - if (map) { - //drop item at the feet of the character instead of destroying it - map->AddItemToLocation(Sender->Pos, si); - } else { - delete si; - } - } - } - actor->ReinitQuickSlots(); -} - -void GameScript::DropItem(Scriptable *Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - if (Distance(parameters->pointParameter, Sender) > 10) { - MoveNearerTo(Sender, parameters->pointParameter, 10,0); - return; - } - Actor *scr = (Actor *) Sender; - Map *map = Sender->GetCurrentArea(); - - if (parameters->string0Parameter[0]) { - //dropping location isn't exactly our place, this is why i didn't use a simple DropItem - scr->inventory.DropItemAtLocation(parameters->string0Parameter, -0, map, parameters->pointParameter); - } else { - //this should be converted from scripting slot to physical slot - scr->inventory.DropItemAtLocation(parameters->int0Parameter, 0, map, parameters->pointParameter); - } - - Sender->ReleaseCurrentAction(); -} - -void GameScript::DropInventory(Scriptable *Sender, Action* /*parameters*/) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor *scr = (Actor *) Sender; - scr->DropItem("",0); -} - -//this should work on containers! -//using the same code for DropInventoryEXExclude -void GameScript::DropInventoryEX(Scriptable *Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - return; - } - Inventory *inv = NULL; - switch (Sender->Type) { - case ST_ACTOR: - inv = &(((Actor *) tar)->inventory); - break; - case ST_CONTAINER: - inv = &(((Container *) tar)->inventory); - break; - default:; - } - if (inv) { - int x = inv->GetSlotCount(); - Map *area = tar->GetCurrentArea(); - while(x--) { - if (parameters->string0Parameter[0]) { - const char *resref = inv->GetSlotItem(x)->ItemResRef; - if (!strnicmp(parameters->string0Parameter, resref, 8)) { - continue; - } - } - inv->DropItemAtLocation(x, 0, area, tar->Pos); - } - } -} - -void GameScript::GivePartyAllEquipment(Scriptable *Sender, Action* /*parameters*/) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Game *game = core->GetGame(); - // pick the first actor first - for (int i = 0; i < game->GetPartySize(false); i++) { - Actor *tar = game->GetPC(i,false); - //don't try to give self, it would be an infinite loop - if (tar==(Actor *) Sender) - continue; - while(MoveItemCore(Sender, tar, "",0,0)!=MIC_NOITEM) { } - } -} - -//This is unsure, Plunder could be just handling ground piles and not dead actors -void GameScript::Plunder(Scriptable *Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Scriptable* tar = GetStoredActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - Sender->ReleaseCurrentAction(); - return; - } - - //you must be joking - if (tar==Sender) { - Sender->ReleaseCurrentAction(); - return; - } - - if (tar->Type == ST_ACTOR) { - Actor *scr = (Actor *) tar; - //can plunder only dead actors - if (! (scr->BaseStats[IE_STATE_ID]&STATE_DEAD) ) { - Sender->ReleaseCurrentAction(); - return; - } - } - if (PersonalDistance(Sender, tar)>MAX_OPERATING_DISTANCE ) { - MoveNearerTo(Sender, tar->Pos, MAX_OPERATING_DISTANCE,0); - return; - } - //move all movable item from the target to the Sender - //the rest will be dropped at the feet of Sender - while(MoveItemCore(tar, Sender, "",0,0)!=MIC_NOITEM) { } - Sender->ReleaseCurrentAction(); -} - -void GameScript::MoveInventory(Scriptable *Sender, Action* parameters) -{ - Scriptable* src = GetActorFromObject( Sender, parameters->objects[1] ); - if (!src || src->Type!=ST_ACTOR) { - return; - } - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[2] ); - if (!tar || tar->Type!=ST_ACTOR) { - return; - } - //don't try to move to self, it would create infinite loop - if (src==tar) - return; - //move all movable item from the target to the Sender - //the rest will be dropped at the feet of Sender - while(MoveItemCore(src, tar, "",0,0)!=MIC_NOITEM) { } -} - -void GameScript::PickPockets(Scriptable *Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Scriptable* tar = GetStoredActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type!=ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Actor *snd = (Actor *) Sender; - Actor *scr = (Actor *) tar; - //for PP one must go REALLY close - Map *map=Sender->GetCurrentArea(); - if (!map) { - Sender->ReleaseCurrentAction(); - return; - } - - if (PersonalDistance(Sender, tar)>10 ) { - MoveNearerTo(Sender, tar, 10); - return; - } - - if (scr->GetStat(IE_EA)>EA_EVILCUTOFF) { - displaymsg->DisplayConstantString(STR_PICKPOCKET_EVIL,0xffffff); - Sender->ReleaseCurrentAction(); - return; - } - - int skill = snd->GetStat(IE_PICKPOCKET); - int tgt = scr->GetStat(IE_PICKPOCKET); - //the original engine has no random here - if (tgt != 255) { - skill -= tgt; - //if you want original behaviour: remove this - skill += core->Roll(1,100, snd->GetStat(IE_LUCK) ); - } else { - skill = 0; - } - //and change this 50 to 0. - if (skill<50) { - //noticed attempt - displaymsg->DisplayConstantString(STR_PICKPOCKET_FAIL,0xffffff); - if (core->HasFeature(GF_STEAL_IS_ATTACK) ) { - tar->AddTrigger(TriggerEntry(trigger_attackedby, snd->GetGlobalID())); - tar->LastAttacker = snd->GetGlobalID(); // FIXME - } else { - //pickpocket failed trigger - tar->AddTrigger(TriggerEntry(trigger_pickpocketfailed, snd->GetGlobalID())); - } - Sender->ReleaseCurrentAction(); - return; - } - - int ret = MIC_NOITEM; - if ((RandomNumValue&3) || (scr->GetStat(IE_GOLD)<=0) ) { - int slot = scr->inventory.FindStealableItem(); - if (slot) { - CREItem *item = scr->inventory.RemoveItem(slot); - ret = snd->inventory.AddSlotItem(item, SLOT_ONLYINVENTORY); - if (ret!=ASI_SUCCESS) { - map->AddItemToLocation(snd->Pos, item); - ret = MIC_FULL; - } - } - } - - if (ret==MIC_NOITEM) { - int money=0; - //go for money too - if (scr->GetStat(IE_GOLD)>0) { - money=RandomNumValue%(scr->GetStat(IE_GOLD)+1); - } - if (!money) { - //no stuff to steal - displaymsg->DisplayConstantString(STR_PICKPOCKET_NONE,0xffffff); - Sender->ReleaseCurrentAction(); - return; - } - CREItem *item = new CREItem(); - if (!CreateItemCore(item, core->GoldResRef, money, 0, 0)) { - abort(); - } - if ( ASI_SUCCESS == snd->inventory.AddSlotItem(item, SLOT_ONLYINVENTORY)) { - scr->SetBase(IE_GOLD,scr->GetBase(IE_GOLD)-money); - } else { - // drop it at my feet - map->AddItemToLocation(Sender->Pos, item); - if (((Actor *)Sender)->InParty) displaymsg->DisplayConstantString(STR_INVFULL_ITEMDROP, 0xbcefbc); - Sender->ReleaseCurrentAction(); - return; - } - } - - displaymsg->DisplayConstantString(STR_PICKPOCKET_DONE,0xffffff); - DisplayStringCore(snd, VB_PP_SUCC, DS_CONSOLE|DS_CONST ); - Sender->ReleaseCurrentAction(); -} - -void GameScript::TakeItemList(Scriptable * Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type!=ST_ACTOR) { - return; - } - AutoTable tab(parameters->string0Parameter); - if (!tab) { - return; - } - - int rows = tab->GetRowCount(); - for (int i=0;iQueryField(i,0), 0, IE_INV_ITEM_UNSTEALABLE); - } -} - -void GameScript::TakeItemListParty(Scriptable * Sender, Action* parameters) -{ - AutoTable tab(parameters->string0Parameter); - if (!tab) { - return; - } - Game *game = core->GetGame(); - int rows = tab->GetRowCount(); - for (int i=0;iGetPartySize(false); - while (j--) { - Actor *tar = game->GetPC(j, false); - MoveItemCore(tar, Sender, tab->QueryField(i,0), 0, IE_INV_ITEM_UNSTEALABLE); - } - } -} - -void GameScript::TakeItemListPartyNum(Scriptable * Sender, Action* parameters) -{ - AutoTable tab(parameters->string0Parameter); - if (!tab) { - return; - } - Game *game = core->GetGame(); - int rows = tab->GetRowCount(); - int count = parameters->int0Parameter; - for (int i=0;iGetPartySize(false); - while (j--) { - Actor *tar = game->GetPC(j, false); - int res=MoveItemCore(tar, Sender, tab->QueryField(i,0), 0, IE_INV_ITEM_UNSTEALABLE); - if (res==MIC_GOTITEM) { - j++; - count--; - } - if (!count) break; - } - } - if (count == 1) { - // grant the default table item to the Sender in regular games - Action *params = new Action(true); - sprintf(params->string0Parameter, "%s", tab->QueryField(9999,9999)); - CreateItem(Sender, params); - delete params; - } -} - -//bg2 -void GameScript::SetRestEncounterProbabilityDay(Scriptable* Sender, Action* parameters) -{ - Map *map=Sender->GetCurrentArea(); - map->RestHeader.DayChance = (ieWord) parameters->int0Parameter; -} - -void GameScript::SetRestEncounterProbabilityNight(Scriptable* Sender, Action* parameters) -{ - Map *map=Sender->GetCurrentArea(); - map->RestHeader.NightChance = (ieWord) parameters->int0Parameter; -} - -//iwd -void GameScript::SetRestEncounterChance(Scriptable * Sender, Action* parameters) -{ - Map *map=Sender->GetCurrentArea(); - map->RestHeader.DayChance = (ieWord) parameters->int0Parameter; - map->RestHeader.NightChance = (ieWord) parameters->int1Parameter; -} - -//easily hardcoded end sequence -void GameScript::EndCredits(Scriptable* /*Sender*/, Action* /*parameters*/) -{ - core->PlayMovie("credits"); -} - -//easily hardcoded end sequence -void GameScript::ExpansionEndCredits(Scriptable* /*Sender*/, Action* /*parameters*/) -{ - core->PlayMovie("ecredit"); -} - -//always quits game, but based on game it can play end animation, or display -//death text, etc -//this covers: -//QuitGame (play two of 3 movies in PST, display death screen with strref) -//EndGame (display death screen with strref) -void GameScript::QuitGame(Scriptable* Sender, Action* parameters) -{ - ClearAllActions(Sender, parameters); - core->GetDictionary()->SetAt("QuitGame1", (ieDword) parameters->int0Parameter); - core->GetDictionary()->SetAt("QuitGame2", (ieDword) parameters->int1Parameter); - core->GetDictionary()->SetAt("QuitGame3", (ieDword) parameters->int2Parameter); - core->SetNextScript("QuitGame"); -} - -//BG2 demo end, shows some pictures then goes to main screen -void GameScript::DemoEnd(Scriptable* Sender, Action* parameters) -{ - ClearAllActions(Sender, parameters); - core->GetDictionary()->SetAt("QuitGame1", (ieDword)0); - core->GetDictionary()->SetAt("QuitGame2", (ieDword)0); - core->GetDictionary()->SetAt("QuitGame3", (ieDword)-1); - core->SetNextScript("QuitGame"); -} - -void GameScript::StopMoving(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor *actor = (Actor *) Sender; - actor->ClearPath(); -} - -void GameScript::ApplyDamage(Scriptable* Sender, Action* parameters) -{ - Actor *damagee; - Actor *damager; - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type!=ST_ACTOR) { - return; - } - damagee = (Actor *) tar; - if (Sender->Type==ST_ACTOR) { - damager=(Actor *) Sender; - } else { - damager=damagee; - } - damagee->Damage(parameters->int0Parameter, parameters->int1Parameter, damager); -} - -void GameScript::ApplyDamagePercent(Scriptable* Sender, Action* parameters) -{ - Actor *damagee; - Actor *damager; - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type!=ST_ACTOR) { - return; - } - damagee = (Actor *) tar; - if (Sender->Type==ST_ACTOR) { - damager=(Actor *) Sender; - } else { - damager=damagee; - } - damagee->Damage(damagee->GetBase(IE_HITPOINTS)*parameters->int0Parameter/100, parameters->int1Parameter, damager); -} - -void GameScript::Damage(Scriptable* Sender, Action* parameters) -{ - Actor *damagee; - Actor *damager; - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type!=ST_ACTOR) { - return; - } - damagee = (Actor *) tar; - if (Sender->Type==ST_ACTOR) { - damager=(Actor *) Sender; - } else { - damager=damagee; - } - int damage = damagee->LuckyRoll( (parameters->int1Parameter>>12)&15, (parameters->int1Parameter>>4)&255, parameters->int1Parameter&15, LR_DAMAGELUCK, damager); - int type=MOD_ADDITIVE; - switch(parameters->int0Parameter) { - case 2: //raise - damage=-damage; - break; - case 3: //set - type=MOD_ABSOLUTE; - break; - case 4: // - type=MOD_PERCENT; - break; - } - damagee->Damage( damage, type, damager ); -} -/* -void GameScript::SetHomeLocation(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type!=ST_ACTOR) { - return; - } - Movable *movable = (Movable *) tar; //not actor, though it is the only moveable - movable->Destination = parameters->pointParameter; - //no movement should be started here, i think -} -*/ - -void GameScript::SetMasterArea(Scriptable* /*Sender*/, Action* parameters) -{ - core->GetGame()->SetMasterArea(parameters->string0Parameter); -} - -void GameScript::Berserk(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor *act = (Actor *) Sender; - act->SetBaseBit(IE_STATE_ID, STATE_BERSERK, true); - act->Panic(NULL, PANIC_BERSERK); -} - -void GameScript::Panic(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor *act = (Actor *) Sender; - act->Panic(NULL, PANIC_RANDOMWALK); -} - -/* as of now: removes panic and berserk */ -void GameScript::Calm(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor *act = (Actor *) Sender; - act->SetBaseBit(IE_STATE_ID, STATE_BERSERK|STATE_PANIC, false); -} - -void GameScript::RevealAreaOnMap(Scriptable* /*Sender*/, Action* parameters) -{ - WorldMap *worldmap = core->GetWorldMap(); - if (!worldmap) { - error("GameScript", "Can't find worldmap!\n"); - } - // WMP_ENTRY_ADJACENT because otherwise revealed bg2 areas are unreachable from city gates - worldmap->SetAreaStatus(parameters->string0Parameter, WMP_ENTRY_VISIBLE|WMP_ENTRY_ADJACENT, BM_OR); - displaymsg->DisplayConstantString(STR_WORLDMAPCHANGE, 0xc8ffc8); -} - -void GameScript::HideAreaOnMap( Scriptable* /*Sender*/, Action* parameters) -{ - WorldMap *worldmap = core->GetWorldMap(); - if (!worldmap) { - error("GameScript", "Can't find worldmap!\n"); - } - // WMP_ENTRY_ADJACENT because otherwise revealed bg2 areas are unreachable from city gates - worldmap->SetAreaStatus(parameters->string0Parameter, WMP_ENTRY_VISIBLE|WMP_ENTRY_ADJACENT, BM_NAND); -} - -void GameScript::SendTrigger(Scriptable* Sender, Action* parameters) -{ - Scriptable *tar = GetActorFromObject( Sender, parameters->objects[1], GA_NO_DEAD ); - if (!tar) { - return; - } - tar->AddTrigger(TriggerEntry(trigger_trigger, parameters->int0Parameter)); -} - -void GameScript::Shout( Scriptable* Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - //according to IESDP silenced creatures cannot use shout - Actor *actor = (Actor *) Sender; - if (actor->GetStat( IE_STATE_ID) & STATE_SILENCED) { - return; - } - Map *map=Sender->GetCurrentArea(); - //max. shouting distance, please adjust it if you know better - map->Shout(actor, parameters->int0Parameter, MAX_TRAVELING_DISTANCE); -} - -void GameScript::GlobalShout( Scriptable* Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - //according to IESDP silenced creatures cannot use shout - Actor *actor = (Actor *) Sender; - if (actor->GetStat( IE_STATE_ID) & STATE_SILENCED) { - return; - } - Map *map=Sender->GetCurrentArea(); - // 0 means unlimited shout distance - map->Shout(actor, parameters->int0Parameter, 0); -} - -void GameScript::Help( Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Map *map=Sender->GetCurrentArea(); - map->Shout((Actor *) Sender, 0, 40); -} - -void GameScript::GiveOrder(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (tar) { - tar->AddTrigger(TriggerEntry(trigger_receivedorder, Sender->GetGlobalID(), parameters->int0Parameter)); - } -} - -void GameScript::AddMapnote( Scriptable* Sender, Action* parameters) -{ - Map *map=Sender->GetCurrentArea(); - char *str = core->GetString( parameters->int0Parameter, 0); - map->AddMapNote(parameters->pointParameter, parameters->int1Parameter, str, parameters->int0Parameter); -} - -void GameScript::RemoveMapnote( Scriptable* Sender, Action* parameters) -{ - Map *map=Sender->GetCurrentArea(); - map->RemoveMapNote(parameters->pointParameter); -} - -void GameScript::AttackOneRound( Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - //using auto target! - Scriptable* tar; - /*if (!parameters->objects[1]) { - GameControl *gc = core->GetGameControl(); - tar = gc->GetTarget(); - } else {*/ - tar = GetStoredActorFromObject( Sender, parameters->objects[1], GA_NO_DEAD ); - /*}*/ - if (!tar || (tar->Type != ST_ACTOR && tar->Type !=ST_DOOR && tar->Type !=ST_CONTAINER) ) { - Sender->ReleaseCurrentAction(); - return; - } - - //actor is already incapable of attack - if (Sender->GetInternalFlag()&IF_STOPATTACK) { - Sender->ReleaseCurrentAction(); - return; - } - - if (!Sender->CurrentActionState) { - Sender->CurrentActionState = core->Time.round_size; - } - - AttackCore(Sender, tar, 0); - - if (Sender->CurrentActionState == 1) { - //this is the LastDisarmFailed field, but this is an actor - //Sender->LastTarget = 0; - Sender->ReleaseCurrentAction(); - } else { - Sender->CurrentActionState--; - } -} - -void GameScript::RunningAttackNoSound( Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - //using auto target! - Scriptable* tar; - /*if (!parameters->objects[1]) { - GameControl *gc = core->GetGameControl(); - tar = gc->GetTarget(); - } else {*/ - tar = GetStoredActorFromObject( Sender, parameters->objects[1], GA_NO_DEAD ); - /*}*/ - if (!tar || (tar->Type != ST_ACTOR && tar->Type !=ST_DOOR && tar->Type !=ST_CONTAINER) ) { - Sender->ReleaseCurrentAction(); - return; - } - - //actor is already incapable of attack - if (Sender->GetInternalFlag()&IF_STOPATTACK) { - Sender->ReleaseCurrentAction(); - return; - } - - AttackCore(Sender, tar, AC_NO_SOUND|AC_RUNNING); -} - -void GameScript::AttackNoSound( Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - //using auto target! - Scriptable* tar; - /*if (!parameters->objects[1]) { - GameControl *gc = core->GetGameControl(); - tar = gc->GetTarget(); - } else {*/ - tar = GetStoredActorFromObject( Sender, parameters->objects[1], GA_NO_DEAD ); - /*}*/ - if (!tar || (tar->Type != ST_ACTOR && tar->Type !=ST_DOOR && tar->Type !=ST_CONTAINER) ) { - Sender->ReleaseCurrentAction(); - return; - } - - //actor is already incapable of attack - if (Sender->GetInternalFlag()&IF_STOPATTACK) { - Sender->ReleaseCurrentAction(); - return; - } - - AttackCore(Sender, tar, AC_NO_SOUND); -} - -void GameScript::RunningAttack( Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - //using auto target! - Scriptable* tar; - /*if (!parameters->objects[1]) { - GameControl *gc = core->GetGameControl(); - tar = gc->GetTarget(); - } else {*/ - tar = GetStoredActorFromObject( Sender, parameters->objects[1], GA_NO_DEAD ); - /*}*/ - if (!tar || (tar->Type != ST_ACTOR && tar->Type !=ST_DOOR && tar->Type !=ST_CONTAINER) ) { - Sender->ReleaseCurrentAction(); - return; - } - - //actor is already incapable of attack - if (Sender->GetInternalFlag()&IF_STOPATTACK) { - Sender->ReleaseCurrentAction(); - return; - } - - AttackCore(Sender, tar, AC_RUNNING); -} - -void GameScript::Attack( Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - //using auto target! - Scriptable* tar; - tar = GetStoredActorFromObject( Sender, parameters->objects[1], GA_NO_DEAD ); - - if (!tar || (tar->Type != ST_ACTOR && tar->Type !=ST_DOOR && tar->Type !=ST_CONTAINER) || tar == Sender) { - Sender->ReleaseCurrentAction(); - return; - } - - //actor is already incapable of attack - if (Sender->GetInternalFlag()&IF_STOPATTACK) { - Sender->ReleaseCurrentAction(); - return; - } - - AttackCore(Sender, tar, 0); -} - -void GameScript::ForceAttack( Scriptable* Sender, Action* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objects[1], GA_NO_DEAD ); - if (!scr || scr->Type != ST_ACTOR) { - return; - } - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[2], GA_NO_DEAD ); - if (!tar || (tar->Type != ST_ACTOR && tar->Type !=ST_DOOR && tar->Type !=ST_CONTAINER) ) { - return; - } - //this is a hack, we use a gui variable for our own hideous reasons? - if (tar->Type==ST_ACTOR) { - GameControl *gc = core->GetGameControl(); - if (gc) { - //saving the target object ID from the gui variable - char Tmp[40]; - strncpy(Tmp,"NIDSpecial3()",sizeof(Tmp) ); - scr->AddAction( GenerateActionDirect(Tmp, (Actor *) tar) ); - } - } else { - char Tmp[80]; - snprintf(Tmp, sizeof(Tmp), "BashDoor(%s)", tar->GetScriptName()); - scr->AddAction ( GenerateAction(Tmp) ); - } -} - -void GameScript::AttackReevaluate( Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - - if (!Sender->CurrentActionState) { - Sender->CurrentActionState = parameters->int0Parameter; - // TODO: reevaluate target (set CurrentActionTarget to 0) if we are not actively in combat - } - - Scriptable* tar; - tar = GetStoredActorFromObject( Sender, parameters->objects[1], GA_NO_DEAD ); - if (!tar || (tar->Type != ST_ACTOR && tar->Type !=ST_DOOR && tar->Type !=ST_CONTAINER) ) { - Sender->ReleaseCurrentAction(); - return; - } - - //actor is already incapable of attack - if (Sender->GetInternalFlag()&IF_STOPATTACK) { - Sender->ReleaseCurrentAction(); - return; - } - - AttackCore(Sender, tar, 0); - - Sender->CurrentActionState--; -} - -void GameScript::Explore( Scriptable* Sender, Action* /*parameters*/) -{ - Sender->GetCurrentArea( )->Explore(-1); -} - -void GameScript::UndoExplore( Scriptable* Sender, Action* /*parameters*/) -{ - Sender->GetCurrentArea( )->Explore(0); -} - -void GameScript::ExploreMapChunk( Scriptable* Sender, Action* parameters) -{ - Map *map = Sender->GetCurrentArea(); - /* - There is a mode flag in int1Parameter, but i don't know what is it, - our implementation uses it for LOS=1, or no LOS=0 - ExploreMapChunk will reveal both visibility/explored map, but the - visibility will fade in the next update cycle (which is quite frequent) - */ - map->ExploreMapChunk(parameters->pointParameter, parameters->int0Parameter, parameters->int1Parameter); -} - -void GameScript::StartStore( Scriptable* Sender, Action* parameters) -{ - if (core->GetCurrentStore() ) { - return; - } - core->SetCurrentStore( parameters->string0Parameter, Sender->GetGlobalID()); - core->SetEventFlag(EF_OPENSTORE); - //sorry, i have absolutely no idea when i should do this :) - Sender->ReleaseCurrentAction(); -} - -//The integer parameter is a GemRB extension, if set to 1, the player -//gains experience for learning the spell -void GameScript::AddSpecialAbility( Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - Actor *actor = (Actor *) Sender; - actor->LearnSpell (parameters->string0Parameter, parameters->int0Parameter|LS_MEMO|LS_LEARN); - core->SetEventFlag(EF_ACTION); -} - -//actually this just depletes a spell, doesn't remove it from the book -//GemRB extension: the first/second int parameter can also make it removed -//from the spell memorization schedule (also from the spellbook) -void GameScript::RemoveSpell( Scriptable* Sender, Action* parameters) -{ - ieResRef spellres; - int type; - - if (Sender->Type!=ST_ACTOR) { - return; - } - if (!ResolveSpellName( spellres, parameters) ) { - return; - } - Actor *actor = (Actor *) Sender; - if (parameters->string0Parameter[0]) { - //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 - actor->spellbook.RemoveSpell(spellres); - return; - } - //type == 1 remove spell only from memorization - //type == 0 original behaviour: deplete only - actor->spellbook.UnmemorizeSpell(spellres, type); -} - -void GameScript::SetScriptName( Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type!=ST_ACTOR) { - return; - } - tar->SetScriptName(parameters->string0Parameter); -} - -//iwd2 -//advance time with a constant -//This is in seconds according to IESDP -void GameScript::AdvanceTime(Scriptable* /*Sender*/, Action* parameters) -{ - core->GetGame()->AdvanceTime(parameters->int0Parameter*1000/AI_UPDATE_TIME); -} - -//advance at least one day, then stop at next day/dusk/night/morning -//oops, not TimeODay is used but Time (this means we got hours) -//i'm not sure if we should add a whole day either, needs more research -void GameScript::DayNight(Scriptable* /*Sender*/, Action* parameters) -{ - // first, calculate the current number of hours. - int padding = ((core->GetGame()->GameTime / AI_UPDATE_TIME) % 7200) / 300; - // then, calculate the offset (in hours) required to take us to the desired hour. - padding = (24 + parameters->int0Parameter - padding) % 24; - // then, advance one day (7200), plus the desired number of hours. - core->GetGame()->AdvanceTime(AI_UPDATE_TIME*(7200 + padding*300)); -} - -//implement pst style parameters: -//suggested dream - unused -//if suggested dream is 0, then area flags determine the 'movie' -//hp - number of hps healed -//renting - crashes pst, we simply ignore it -void GameScript::RestParty(Scriptable* Sender, Action* parameters) -{ - Game *game = core->GetGame(); - game->RestParty(REST_NOAREA|REST_NOMOVE|REST_NOCRITTER, parameters->int0Parameter, parameters->int1Parameter); - Sender->ReleaseCurrentAction(); -} - -//doesn't advance game time, just refreshes spells of target -//this is a non-blocking action -void GameScript::Rest(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor *actor = (Actor *) Sender; - actor->spellbook.ChargeAllSpells(); - //check if this should be a full heal - actor->Heal(0); - actor->fxqueue.RemoveExpiredEffects(0xffffffff); -} - -//doesn't advance game time (unsure), just refreshes spells of target -void GameScript::RestNoSpells(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor *actor = (Actor *) Sender; - //check if this should be a full heal - actor->Heal(0); - actor->fxqueue.RemoveExpiredEffects(0xffffffff); -} - -//this is most likely advances time -void GameScript::RestUntilHealed(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor *actor = (Actor *) Sender; - actor->Heal(1); - //not sure if this should remove timed effects - //more like execute them hour by hour :> -} - -//iwd2 -//removes all delayed/duration/semi permanent effects (like a ctrl-r) -void GameScript::ClearPartyEffects(Scriptable* /*Sender*/, Action* /*parameters*/) -{ - Game *game = core->GetGame(); - int i = game->GetPartySize(false); - while (i--) { - Actor *tar = game->GetPC(i, false); - tar->fxqueue.RemoveExpiredEffects(0xffffffff); - } -} - -//iwd2 removes effects from a single sprite -void GameScript::ClearSpriteEffects(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type!=ST_ACTOR) { - return; - } - Actor *actor = (Actor *) tar; - actor->fxqueue.RemoveExpiredEffects(0xffffffff); -} - -//IWD2 special, can mark only actors, hope it is enough -void GameScript::MarkObject(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - //unsure, could mark dead objects? - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1], GA_NO_DEAD ); - if (!tar || tar->Type!=ST_ACTOR) { - return; - } - Actor *actor = (Actor *) Sender; - actor->LastMarked = tar->GetGlobalID(); - //if this doesn't modify LastSeen, then remove this line - actor->LastSeen = actor->LastMarked; -} - -void GameScript::MarkSpellAndObject(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - Actor *me = (Actor *) Sender; - if (me->LastMarkedSpell) { - return; - } - - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1]); - Actor *actor = NULL; - if (tar->Type == ST_ACTOR) { - actor = (Actor *) tar; - } - - int flags = parameters->int0Parameter; - if (!(flags & MSO_IGNORE_NULL) && !actor) { - return; - } - if (!(flags & MSO_IGNORE_INVALID) && actor && actor->InvalidSpellTarget() ) { - return; - } - if (!(flags & MSO_IGNORE_SEE) && actor && !CanSee(Sender, actor, true, 0) ) { - return; - } - int len = strlen(parameters->string0Parameter); - // - if (len&3) { - return; - } - len/=4; - int max = len; - int pos; - if (flags & MSO_RANDOM_SPELL) { - pos = core->Roll(1,len,0); - } else { - pos = 0; - } - while(len--) { - char spl[5]; - - memcpy(spl, parameters->string0Parameter+pos*4, 4); - spl[4]=0; - int splnum = atoi(spl); - - if (!(flags & MSO_IGNORE_HAVE) && !me->spellbook.HaveSpell(splnum, 0) ) { - goto end_mso_loop; - } - int range; - if ((flags & MSO_IGNORE_RANGE) || !actor) { - range = 0; - } else { - range = Distance(me, actor); - } - if (!(flags & MSO_IGNORE_INVALID) && actor->InvalidSpellTarget(splnum, me, range)) { - goto end_mso_loop; - } - //mark spell and target - me->LastMarkedSpell = splnum; - me->LastMarked = actor->GetGlobalID(); - break; -end_mso_loop: - pos++; - if (pos==max) { - pos = 0; - } - } -} - -void GameScript::ForceMarkedSpell(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - Actor *actor = (Actor *) Sender; - actor->LastMarkedSpell = parameters->int0Parameter; -} - -void GameScript::SetMarkedSpell(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - Actor *actor = (Actor *) Sender; - if (parameters->int0Parameter) { - if (actor->LastMarkedSpell) { - return; - } - if (!actor->spellbook.HaveSpell(parameters->int0Parameter, 0) ) { - return; - } - } - - //TODO: check if spell exists (not really important) - actor->LastMarkedSpell = parameters->int0Parameter; - return; -} - -void GameScript::SetDialogueRange(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - Actor *actor = (Actor *) Sender; - actor->SetBase( IE_DIALOGRANGE, parameters->int0Parameter ); -} - -void GameScript::SetGlobalTint(Scriptable* /*Sender*/, Action* parameters) -{ - core->GetVideoDriver()->SetFadeColor(parameters->int0Parameter, parameters->int1Parameter, parameters->int2Parameter); -} - -void GameScript::SetArmourLevel(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type!=ST_ACTOR) { - return; - } - Actor *actor = (Actor *) Sender; - actor->SetBase( IE_ARMOR_TYPE, parameters->int0Parameter ); -} - -void GameScript::RandomWalk(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Actor* actor = ( Actor* ) Sender; - actor->RandomWalk( true, false ); - Sender->ReleaseCurrentAction(); -} - -void GameScript::RandomRun(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Actor* actor = ( Actor* ) Sender; - actor->RandomWalk( true, true ); - Sender->ReleaseCurrentAction(); -} - -void GameScript::RandomWalkContinuous(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Actor* actor = ( Actor* ) Sender; - actor->RandomWalk( false, false ); -} - -void GameScript::RandomFly(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Actor* actor = ( Actor* ) Sender; - int x = rand()&31; - if (x<10) { - actor->SetOrientation(actor->GetOrientation()-1, false); - } else if (x>20) { - actor->SetOrientation(actor->GetOrientation()+1, false); - } - //fly in this direction for 5 steps - actor->MoveLine(5, GL_PASS, actor->GetOrientation() ); - //readding the action to the end of the queue - //Sender->AddAction( parameters ); - //Sender->ReleaseCurrentAction(); -} - -//UseContainer uses the predefined target (like Nidspecial1 dialog hack) -void GameScript::UseContainer(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type != ST_ACTOR) { - 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) { - printMessage("GameScript","No container selected!", YELLOW); - Sender->ReleaseCurrentAction(); - return; - } - - ieDword distance = PersonalDistance(Sender, container); - ieDword needed = MAX_OPERATING_DISTANCE; - if (container->Type==IE_CONTAINER_PILE) { - needed = 0; // less than a search square (width) - } - if (distance<=needed) - { - //check if the container is unlocked - if (!container->TryUnlock(actor)) { - //playsound can't open container - //display string, etc - displaymsg->DisplayConstantString(STR_CONTLOCKED,0xd7d7be,container); - Sender->ReleaseCurrentAction(); - return; - } - Actor *actor = (Actor *)Sender; - actor->SetModal(MS_NONE); - container->TriggerTrap(0, actor->GetGlobalID()); - core->SetCurrentContainer(actor, container, true); - Sender->ReleaseCurrentAction(); - return; - } - MoveNearerTo(Sender, container, needed); -} - -//call the usecontainer action in target (not used) -void GameScript::ForceUseContainer(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); //why blocking??? - return; - } - char Tmp[256]; - sprintf( Tmp, "UseContainer()"); - Action *newaction = GenerateAction(Tmp); - tar->AddActionInFront(newaction); - Sender->ReleaseCurrentAction(); //why blocking??? -} - -//these actions directly manipulate a game variable (as the original engine) -void GameScript::SetMazeEasier(Scriptable* Sender, Action* /*parameters*/) -{ - int value = CheckVariable( Sender, "MAZEDIFFICULTY","GLOBAL"); - if (value>0) { - SetVariable(Sender, "MAZEDIFFICULTY", "GLOBAL", value-1); - } -} - -void GameScript::SetMazeHarder(Scriptable* Sender, Action* /*parameters*/) -{ - int value = CheckVariable( Sender, "MAZEDIFFICULTY","GLOBAL"); - if (value<2) { - SetVariable(Sender, "MAZEDIFFICULTY", "GLOBAL", value+1); - } -} - -void GameScript::GenerateMaze(Scriptable* /*Sender*/, Action* /*parameters*/) -{ - core->SetEventFlag(EF_CREATEMAZE); -} - -void GameScript::FixEngineRoom(Scriptable* Sender, Action* /*parameters*/) -{ - int value = CheckVariable( Sender, "EnginInMaze","GLOBAL"); - if (value) { - SetVariable(Sender, "EnginInMaze", "GLOBAL", 0); - //this works only because the engine room exit depends only on the EnginInMaze variable - ScriptEngine *sE = core->GetGUIScriptEngine(); - sE->RunFunction("Maze", "CustomizeArea"); - } -} - -void GameScript::StartRainNow(Scriptable* /*Sender*/, Action* /*parameters*/) -{ - core->GetGame()->StartRainOrSnow( false, WB_RAIN|WB_LIGHTNING); -} - -void GameScript::Weather(Scriptable* /*Sender*/, Action* parameters) -{ - Game *game = core->GetGame(); - switch(parameters->int0Parameter & WB_FOG) { - case WB_NORMAL: - game->StartRainOrSnow( false, 0); - break; - case WB_RAIN: - game->StartRainOrSnow( true, WB_RAIN|WB_LIGHTNING); - break; - case WB_SNOW: - game->StartRainOrSnow( true, WB_SNOW); - break; - case WB_FOG: - game->StartRainOrSnow( true, WB_FOG); - break; - } -} - -void GameScript::CopyGroundPilesTo(Scriptable* Sender, Action* parameters) -{ - Map *map = Sender->GetCurrentArea(); - Map *othermap = core->GetGame()->GetMap( parameters->string0Parameter, false ); - if (!othermap) { - return; - } - map->CopyGroundPiles( othermap, parameters->pointParameter ); -} - -//iwd specific -void GameScript::PlayBardSong(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - //actually this one must use int0Parameter to set a bardsong - Actor *actor = (Actor *) Sender; - actor->SetModal( MS_BATTLESONG); -} - -void GameScript::BattleSong(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor *actor = (Actor *) Sender; - actor->SetModal( MS_BATTLESONG); -} - -void GameScript::FindTraps(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor *actor = (Actor *) Sender; - actor->SetModal( MS_DETECTTRAPS); -} - -void GameScript::Hide(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor *actor = (Actor *) Sender; - - if (actor->TryToHide()) { - actor->SetModal(MS_STEALTH); - } - //TODO: expiry isn't instant (skill based transition?) - -} - -void GameScript::Turn(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor *actor = (Actor *) Sender; - - if (actor->Modified[IE_DISABLEDBUTTON] & (1<GetStat(IE_TURNUNDEADLEVEL); - if (skill < 1) return; - - actor->SetModal(MS_TURNUNDEAD); - -} - -void GameScript::TurnAMT(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Actor *actor = (Actor *) Sender; - actor->SetOrientation(actor->GetOrientation()+parameters->int0Parameter, true); - actor->SetWait( 1 ); - Sender->ReleaseCurrentAction(); // todo, blocking? -} - -void GameScript::RandomTurn(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type!=ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Actor *actor = (Actor *) Sender; - actor->SetOrientation(rand() % MAX_ORIENT, true); - actor->SetWait( 1 ); - Sender->ReleaseCurrentAction(); // todo, blocking? -} - -void GameScript::AttachTransitionToDoor(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type != ST_DOOR) { - return; - } - Door* door = ( Door* ) tar; - strnspccpy(door->LinkedInfo, parameters->string0Parameter, 32); -} - -/*getting a handle of a temporary actor resource to copy its selected attributes*/ -void GameScript::ChangeAnimation(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - ChangeAnimationCore((Actor *) Sender, parameters->string0Parameter,1); -} - -void GameScript::ChangeAnimationNoEffect(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - ChangeAnimationCore((Actor *) Sender, parameters->string0Parameter,0); -} - -void GameScript::Polymorph(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor *act = (Actor *) Sender; - act->SetBase(IE_ANIMATION_ID, parameters->int0Parameter); -} - -void GameScript::PolymorphCopy(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type!=ST_ACTOR) { - return; - } - PolymorphCopyCore((Actor *) tar, (Actor *) Sender, false); -} - -/* according to IESDP this only copies the animation ID */ -void GameScript::PolymorphCopyBase(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type!=ST_ACTOR) { - return; - } - Actor *act = (Actor *) Sender; - Actor *actor = (Actor *) tar; - act->SetBase(IE_ANIMATION_ID, actor->GetBase(IE_ANIMATION_ID) ); -} - -void GameScript::ExportParty(Scriptable* /*Sender*/, Action* parameters) -{ - char FileName[_MAX_PATH]; - - Game *game = core->GetGame(); - int i = game->GetPartySize(false); - while (i--) { - Actor *actor = game->GetPC(i, false); - snprintf(FileName,_MAX_PATH,"%s%d",parameters->string0Parameter,i+1); - core->WriteCharacter(FileName, actor); - } - displaymsg->DisplayConstantString(STR_EXPORTED, 0xbcefbc); -} - -void GameScript::SaveGame(Scriptable* /*Sender*/, Action* parameters) -{ - if (core->HasFeature(GF_STRREF_SAVEGAME)) { - const char *basename = "Auto-Save"; - AutoTable tab("savegame"); - if (tab) { - basename = tab->QueryDefault(); - } - char * str = core->GetString( parameters->int0Parameter, IE_STR_STRREFOFF); - char FolderName[_MAX_PATH]; - snprintf (FolderName, sizeof(FolderName), "%s - %s", basename, str); - core->FreeString( str ); - - core->GetSaveGameIterator()->CreateSaveGame(core->GetSaveGameIterator()->GetSaveGame(FolderName), FolderName); - } else { - core->GetSaveGameIterator()->CreateSaveGame(parameters->int0Parameter); - } -} - -/*EscapeAreaMove(S:Area*,I:X*,I:Y*,I:Face*)*/ -void GameScript::EscapeArea(Scriptable* Sender, Action* parameters) -{ - if (InDebug&ID_ACTIONS) { - print("EscapeArea/EscapeAreaMove\n"); - } - if (Sender->Type!=ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Map *map = Sender->GetCurrentArea(); - if (!map) { - Sender->ReleaseCurrentAction(); - return; - } - - Point p = Sender->Pos; - map->TMap->AdjustNearestTravel(p); - - if (parameters->string0Parameter[0]) { - Point q((short) parameters->int0Parameter, (short) parameters->int1Parameter); - EscapeAreaCore( Sender, p, parameters->string0Parameter, q, 0, parameters->int2Parameter ); - } else { - EscapeAreaCore( Sender, p, parameters->string0Parameter, p, EA_DESTROY, parameters->int0Parameter ); - } - //EscapeAreaCore will do its ReleaseCurrentAction - //Sender->ReleaseCurrentAction(); -} - -void GameScript::EscapeAreaNoSee(Scriptable* Sender, Action* parameters) -{ - if (InDebug&ID_ACTIONS) { - print("EscapeAreaNoSee\n"); - } - if (Sender->Type!=ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Map *map = Sender->GetCurrentArea(); - if (!map) { - Sender->ReleaseCurrentAction(); - return; - } - - Point p = Sender->Pos; - map->TMap->AdjustNearestTravel(p); - - if (parameters->string0Parameter[0]) { - Point q((short) parameters->int0Parameter, (short) parameters->int1Parameter); - EscapeAreaCore( Sender, p, parameters->string0Parameter, q, 0, parameters->int2Parameter ); - } else { - EscapeAreaCore( Sender, p, parameters->string0Parameter, p, EA_DESTROY|EA_NOSEE, parameters->int0Parameter ); - } - //EscapeAreaCore will do its ReleaseCurrentAction - //Sender->ReleaseCurrentAction(); -} - -void GameScript::EscapeAreaDestroy(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Map *map = Sender->GetCurrentArea(); - if (!map) { - Sender->ReleaseCurrentAction(); - return; - } - - //find nearest exit - Point p = Sender->Pos; - map->TMap->AdjustNearestTravel(p); - //EscapeAreaCore will do its ReleaseCurrentAction - EscapeAreaCore( Sender, p, parameters->string0Parameter, p, EA_DESTROY, parameters->int0Parameter ); -} - -/*EscapeAreaObjectMove(S:Area*,I:X*,I:Y*,I:Face*)*/ -void GameScript::EscapeAreaObject(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Map *map = Sender->GetCurrentArea(); - if (!map) { - Sender->ReleaseCurrentAction(); - return; - } - - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - Sender->ReleaseCurrentAction(); - return; - } - Point p = tar->Pos; - if (parameters->string0Parameter[0]) { - Point q((short) parameters->int0Parameter, (short) parameters->int1Parameter); - EscapeAreaCore( Sender, p, parameters->string0Parameter, q, 0, parameters->int2Parameter ); - } else { - EscapeAreaCore( Sender, p, 0, p, EA_DESTROY, parameters->int0Parameter ); - } - //EscapeAreaCore will do its ReleaseCurrentAction -} - -//This one doesn't require the object to be seen? -//We don't have that feature yet, so this is the same as EscapeAreaObject -void GameScript::EscapeAreaObjectNoSee(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Map *map = Sender->GetCurrentArea(); - if (!map) { - Sender->ReleaseCurrentAction(); - return; - } - - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - Sender->ReleaseCurrentAction(); - return; - } - Point p = tar->Pos; - Sender->SetWait(parameters->int0Parameter); - if (parameters->string0Parameter[0]) { - Point q((short) parameters->int0Parameter, (short) parameters->int1Parameter); - EscapeAreaCore( Sender, p, parameters->string0Parameter, q, 0, parameters->int2Parameter ); - } else { - EscapeAreaCore( Sender, p, 0, p, EA_DESTROY|EA_NOSEE, parameters->int0Parameter ); - } - //EscapeAreaCore will do its ReleaseCurrentAction -} - -//takes first fitting item from container at feet, doesn't seem to be working in the original engines -void GameScript::PickUpItem(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor *scr = (Actor *) Sender; - Map *map = scr->GetCurrentArea(); - Container *c = map->GetPile(scr->Pos); - if (!c) { //this shouldn't happen, but lets prepare for the worst - return; - } - - //the following part is coming from GUISCript.cpp with trivial changes - int Slot = c->inventory.FindItem(parameters->string0Parameter, 0); - if (Slot<0) { - return; - } - int res = core->CanMoveItem(c->inventory.GetSlotItem(Slot) ); - if (!res) { //cannot move - return; - } - CREItem *item = c->RemoveItem(Slot,0); - if (!item) { - return; - } - if (res!=-1 && scr->InParty) { //it is gold and we got the party pool! - goto item_is_gold; - } - res = scr->inventory.AddSlotItem(item, SLOT_ONLYINVENTORY); - if (res !=ASI_SUCCESS) { //putting it back - c->AddItem(item); - } - return; -item_is_gold: //we take gold! - if (scr->InParty) { - core->GetGame()->PartyGold += res; - //if you want message here then use - //core->GetGame()->AddGold(res); - } else { - scr->SetBase( IE_GOLD, scr->GetBase(IE_GOLD) + res ); - } - delete item; -} - -void GameScript::ChangeStoreMarkup(Scriptable* /*Sender*/, Action* parameters) -{ - bool has_current = false; - ieResRef current; - ieDword owner; - - Store *store = core->GetCurrentStore(); - if (!store) { - store = core->SetCurrentStore(parameters->string0Parameter, 0); - } else { - if (strnicmp(store->Name, parameters->string0Parameter, 8) ) { - //not the current store, we need some dirty hack - has_current = true; - strnlwrcpy(current, store->Name, 8); - owner = store->GetOwnerID(); - } - } - store->BuyMarkup = parameters->int0Parameter; - store->SellMarkup = parameters->int1Parameter; - //additional markup, is this depreciation??? - store->DepreciationRate = parameters->int2Parameter; - if (has_current) { - //setting back old store (this will save our current store) - core->SetCurrentStore(current, owner); - } -} - -void GameScript::SetEncounterProbability(Scriptable* /*Sender*/, Action* parameters) -{ - WorldMap *wmap = core->GetWorldMap(parameters->string0Parameter); - if (!wmap) { - //no such starting area - return; - } - WMPAreaLink *link = wmap->GetLink(parameters->string0Parameter, parameters->string1Parameter); - if (!link) { - return; - } - link->EncounterChance = parameters->int0Parameter; -} - -void GameScript::SpawnPtActivate(Scriptable* Sender, Action* parameters) -{ - if (parameters->objects[1]) { - Map *map = Sender->GetCurrentArea(); - Spawn *spawn = map->GetSpawn(parameters->objects[1]->objectName); - if (spawn) { - spawn->Enabled = 1; - } - } -} - -void GameScript::SpawnPtDeactivate(Scriptable* Sender, Action* parameters) -{ - if (parameters->objects[1]) { - Map *map = Sender->GetCurrentArea(); - Spawn *spawn = map->GetSpawn(parameters->objects[1]->objectName); - if (spawn) { - spawn->Enabled = 0; - } - } -} - -void GameScript::SpawnPtSpawn(Scriptable* Sender, Action* parameters) -{ - if (parameters->objects[1]) { - Map *map = Sender->GetCurrentArea(); - Spawn *spawn = map->GetSpawn(parameters->objects[1]->objectName); - if (spawn) { - spawn->Enabled = 1; //??? maybe use an unconditionality flag - map->TriggerSpawn(spawn); - } - } -} - -void GameScript::ApplySpell(Scriptable* Sender, Action* parameters) -{ - ieResRef spellres; - - if (!ResolveSpellName( spellres, parameters) ) { - return; - } - - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - return; - } - if (tar->Type==ST_ACTOR) { - //apply spell on target -/* - Actor *owner; - - if (Sender->Type==ST_ACTOR) { - owner = (Actor *) Sender; - } else { - owner = (Actor *) tar; - } -*/ - //core->ApplySpell(spellres, (Actor *) tar, owner, parameters->int1Parameter); - core->ApplySpell(spellres, (Actor *) tar, Sender, parameters->int1Parameter); - } else { - //no idea about this one -/* - Actor *owner; - - if (Sender->Type==ST_ACTOR) { - owner = (Actor *) Sender; - } else { - owner = NULL; - } -*/ - //apply spell on point - Point d; - GetPositionFromScriptable(tar, d, false); - //core->ApplySpellPoint(spellres, tar->GetCurrentArea(), d, owner, parameters->int1Parameter); - core->ApplySpellPoint(spellres, tar->GetCurrentArea(), d, Sender, parameters->int1Parameter); - } -} - -void GameScript::ApplySpellPoint(Scriptable* Sender, Action* parameters) -{ - ieResRef spellres; - Actor *owner; - - if (!ResolveSpellName( spellres, parameters) ) { - return; - } - - if (Sender->Type==ST_ACTOR) { - owner = (Actor *) Sender; - } else { - owner = NULL; - } - core->ApplySpellPoint(spellres, Sender->GetCurrentArea(), parameters->pointParameter, owner, parameters->int1Parameter); -} - -//this is a gemrb extension -//sets a variable to the stat value -void GameScript::GetStat(Scriptable* Sender, Action* parameters) -{ - ieDword value; - - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type!=ST_ACTOR) { - value = 0; - } else { - Actor* actor = ( Actor* ) tar; - value = actor->GetStat( parameters->int0Parameter ); - } - SetVariable( Sender, parameters->string0Parameter, value ); -} - -void GameScript::BreakInstants(Scriptable* Sender, Action* /*parameters*/) -{ - //don't do anything, apparently the point of this action is to - //delay the execution of further actions to the next AI cycle - Sender->SetWait(1); - Sender->ReleaseCurrentAction(); // this doesn't really need to block -} - -//an interesting improvement would be to pause game for a given duration -void GameScript::PauseGame(Scriptable* Sender, Action* /*parameters*/) -{ - GameControl *gc = core->GetGameControl(); - if (gc) { - gc->SetDialogueFlags(DF_FREEZE_SCRIPTS, BM_OR); - displaymsg->DisplayConstantString(STR_SCRIPTPAUSED,0xff0000); - } - // releasing this action allows actions to continue executing, - // so we force a wait - Sender->SetWait(1); - Sender->ReleaseCurrentAction(); // does this need to block? -} - -void GameScript::SetNoOneOnTrigger(Scriptable* Sender, Action* parameters) -{ - Scriptable* ip; - - if (!parameters->objects[1]) { - ip=Sender; - } else { - ip = Sender->GetCurrentArea()->TMap->GetInfoPoint(parameters->objects[1]->objectName); - } - if (!ip || (ip->Type!=ST_TRIGGER && ip->Type!=ST_TRAVEL && ip->Type!=ST_PROXIMITY)) { - print("Script error: No Trigger Named \"%s\"\n", parameters->objects[1]->objectName); - return; - } - // FIXME: what does this do? clear triggers? - /*ip->LastEntered = 0; - ip->LastTrigger = 0; - ip->LastTriggerObject = 0;*/ -} - -void GameScript::UseDoor(Scriptable* Sender, Action* parameters) -{ - GameControl *gc = core->GetGameControl(); - if (!gc) { - Sender->ReleaseCurrentAction(); - return; - } - - gc->ResetTargetMode(); - OpenDoor(Sender, parameters); - - Sender->ReleaseCurrentAction(); // this is blocking, OpenDoor is not -} - -//this will force bashing the door -void GameScript::BashDoor(Scriptable* Sender, Action* parameters) -{ - GameControl *gc = core->GetGameControl(); - if (!gc) { - Sender->ReleaseCurrentAction(); - return; - } - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - - Scriptable *target = GetActorFromObject(Sender, parameters->objects[1]); - TileMap *tmap = Sender->GetCurrentArea()->TMap; - Door *door = NULL; - Container *container = NULL; - Point pos; - if (target->Type == ST_DOOR) { - // FIXME: actually it chooses from two possible points - pos = target->Pos; - door = tmap->GetDoorByPosition(pos); - } else if(target->Type == ST_CONTAINER) { - pos = target->Pos; - container = tmap->GetContainerByPosition(pos); - } else { - Sender->ReleaseCurrentAction(); - return; - } - - // TODO: "sets a field in the door/container to 1" - - if (SquaredPersonalDistance(pos, Sender) > MAX_OPERATING_DISTANCE*MAX_OPERATING_DISTANCE) { - MoveNearerTo(Sender, pos, MAX_OPERATING_DISTANCE, 0); - return; - } - - gc->SetTargetMode(TARGET_MODE_ATTACK); //for bashing doors too - - // try to bash it - if (door) { - door->TryBashLock((Actor *) Sender); - } else if (container) { - container->TryBashLock((Actor *) Sender); - } - - Sender->ReleaseCurrentAction(); -} - -//pst action -void GameScript::ActivatePortalCursor(Scriptable* Sender, Action* parameters) -{ - Scriptable* ip; - - if (!parameters->objects[1]) { - ip=Sender; - } else { - ip = Sender->GetCurrentArea()->TMap->GetInfoPoint(parameters->objects[1]->objectName); - } - if (!ip) { - return; - } - if (ip->Type!=ST_PROXIMITY && ip->Type!=ST_TRAVEL) { - return; - } - InfoPoint *tar = (InfoPoint *) ip; - if (parameters->int0Parameter) { - tar->Trapped|=PORTAL_CURSOR; - } else { - tar->Trapped&=~PORTAL_CURSOR; - } -} - -//pst action -void GameScript::EnablePortalTravel(Scriptable* Sender, Action* parameters) -{ - Scriptable* ip; - - if (!parameters->objects[1]) { - ip=Sender; - } else { - ip = Sender->GetCurrentArea()->TMap->GetInfoPoint(parameters->objects[1]->objectName); - } - if (!ip) { - return; - } - if (ip->Type!=ST_PROXIMITY && ip->Type!=ST_TRAVEL) { - return; - } - InfoPoint *tar = (InfoPoint *) ip; - if (parameters->int0Parameter) { - tar->Trapped|=PORTAL_TRAVEL; - } else { - tar->Trapped&=~PORTAL_TRAVEL; - } -} - -//unhardcoded iwd action (for the forge entrance change) -void GameScript::ChangeDestination(Scriptable* Sender, Action* parameters) -{ - InfoPoint *ip = Sender->GetCurrentArea()->TMap->GetInfoPoint(parameters->objects[1]->objectName); - if (ip && (ip->Type==ST_TRAVEL) ) { - //alter the destination area, don't touch the entrance variable link - strnlwrcpy(ip->Destination, parameters->string0Parameter, sizeof(ieResRef)-1 ); - } -} - -void GameScript::MoveCursorPoint(Scriptable* /*Sender*/, Action* parameters) -{ - core->GetVideoDriver()->MoveMouse(parameters->pointParameter.x, parameters->pointParameter.y); -} - -//false means, no talk -void GameScript::DialogueInterrupt(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) Sender; - if ( parameters->int0Parameter != 0 ) { - actor->SetMCFlag(MC_NO_TALK, BM_NAND); - } else { - actor->SetMCFlag(MC_NO_TALK, BM_OR); - } -} - -void GameScript::EquipMostDamagingMelee(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) Sender; - actor->inventory.EquipBestWeapon(EQUIP_MELEE); -} - -void GameScript::EquipRanged(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) Sender; - actor->inventory.EquipBestWeapon(EQUIP_RANGED); -} - -//will equip best weapon regardless of range considerations -void GameScript::EquipWeapon(Scriptable* Sender, Action* /*parameters*/) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) Sender; - actor->inventory.EquipBestWeapon(EQUIP_MELEE|EQUIP_RANGED); -} - -void GameScript::SetBestWeapon(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type!=ST_ACTOR) { - return; - } - Actor* actor = ( Actor* ) Sender; - - Actor *target = (Actor *) tar; - if (PersonalDistance(actor,target)>(unsigned int) parameters->int0Parameter) { - actor->inventory.EquipBestWeapon(EQUIP_RANGED); - } else { - actor->inventory.EquipBestWeapon(EQUIP_MELEE); - } -} - -void GameScript::FakeEffectExpiryCheck(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type!=ST_ACTOR) { - return; - } - Actor *target = (Actor *) tar; - target->fxqueue.RemoveExpiredEffects(parameters->int0Parameter); -} - -void GameScript::SetInterrupt(Scriptable* Sender, Action* parameters) -{ - if (parameters->int0Parameter) { - Sender->Interrupt(); - } else { - Sender->NoInterrupt(); - } -} - -void GameScript::SelectWeaponAbility(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor *scr = (Actor *) Sender; - int slot = parameters->int0Parameter; - int wslot = scr->inventory.GetWeaponSlot(); - //weapon - if (core->QuerySlotType(slot)&SLOT_WEAPON) { - slot-=wslot; - if (slot<0 || slot>=MAX_QUICKWEAPONSLOT) { - return; - } - scr->SetEquippedQuickSlot(slot, parameters->int1Parameter); - return; - } - //quick item - wslot = scr->inventory.GetQuickSlot(); - if (core->QuerySlotType(slot)&SLOT_ITEM) { - slot-=wslot; - if (slot<0 || slot>=MAX_QUICKITEMSLOT) { - return; - } - if (scr->PCStats) { - scr->PCStats->QuickItemHeaders[slot]=(ieWord) parameters->int1Parameter; - } - } -} - -void GameScript::UseItem(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Scriptable* tar = GetStoredActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - Sender->ReleaseCurrentAction(); - return; - } - Actor *act = (Actor *) Sender; - int Slot; - ieDword header, flags; - ieResRef itemres; - - if (parameters->string0Parameter[0]) { - Slot = act->inventory.FindItem(parameters->string0Parameter, 0); - //this IS in the original game code (ability) - header = parameters->int0Parameter; - flags = parameters->int1Parameter; - } else { - Slot = parameters->int0Parameter; - //this is actually not in the original game code - header = parameters->int1Parameter; - flags = parameters->int2Parameter; - } - - if (Slot == -1) { - Sender->ReleaseCurrentAction(); - return; - } - - if (!ResolveItemName( itemres, act, Slot) ) { - Sender->ReleaseCurrentAction(); - return; - } - - unsigned int dist = GetItemDistance(itemres, header); - - if (PersonalDistance(tar->Pos, Sender) > dist) { - MoveNearerTo(Sender, tar, dist); - return; - } - - act->UseItem(Slot, header, tar, flags); - Sender->ReleaseCurrentAction(); -} - -void GameScript::UseItemPoint(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - - Actor *act = (Actor *) Sender; - int Slot; - ieDword header; - ieResRef itemres; - ieDword flags; - - if (parameters->string0Parameter[0]) { - Slot = act->inventory.FindItem(parameters->string0Parameter, 0); - //this IS in the original game code (ability) - header = parameters->int0Parameter; - flags = parameters->int1Parameter; - } else { - Slot = parameters->int0Parameter; - //this is actually not in the original game code - header = parameters->int1Parameter; - flags = parameters->int2Parameter; - } - - if (Slot == -1) { - Sender->ReleaseCurrentAction(); - return; - } - - if (!ResolveItemName( itemres, act, Slot) ) { - Sender->ReleaseCurrentAction(); - return; - } - - unsigned int dist = GetItemDistance(itemres, header); - - if (PersonalDistance(parameters->pointParameter, Sender) > dist) { - MoveNearerTo(Sender, parameters->pointParameter, dist, 0); - return; - } - - act->UseItemPoint(Slot, header, parameters->pointParameter, flags); - Sender->ReleaseCurrentAction(); -} - -//addfeat will be able to remove feats too -//(the second int parameter is a bitmode) -void GameScript::AddFeat(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type!=ST_ACTOR) { - return; - } - Actor *actor = (Actor *)tar; - actor->SetFeat(parameters->int0Parameter, parameters->int1Parameter); -} - -void GameScript::MatchHP(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor *scr = (Actor *) Sender; - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type!=ST_ACTOR) { - return; - } - Actor *actor = (Actor *)tar; - switch (parameters->int0Parameter) { - case 1: //sadly the hpflags are not the same as stats - actor->SetBase(IE_HITPOINTS,scr->GetBase(IE_HITPOINTS)); - break; - case 0: - actor->SetBase(IE_MAXHITPOINTS, scr->GetBase(IE_MAXHITPOINTS)); - break; - default: //this is gemrb extension - actor->SetBase(parameters->int0Parameter, scr->GetBase(parameters->int0Parameter)); - break; - } -} - -void GameScript::ChangeColor(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor *scr = (Actor *) Sender; - ieDword stat = parameters->int0Parameter; - if (stat<9 || stat>14) { - return; - } - stat += IE_COLORS - 9; - scr->SetBase(stat, (scr->GetBase(stat)&~255)|(parameters->int1Parameter&255)); -} - -//removes previous kit, adds new -void GameScript::AddKit(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor *scr = (Actor *) Sender; - //remove previous kit stuff - scr->ApplyKit(true); - //this adds the current level abilities - scr->SetBase(IE_KIT, parameters->int0Parameter); - scr->ApplyKit(false); -} - -//doesn't remove old kit -void GameScript::AddSuperKit(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Actor *scr = (Actor *) Sender; - scr->SetBase(IE_KIT, parameters->int0Parameter); - scr->ApplyKit(false); -} - -void GameScript::SetSelection(Scriptable* /*Sender*/, Action* parameters) -{ - GameControl *gc = core->GetGameControl(); - if (!gc) { - return; - } - gc->SelectActor(parameters->int0Parameter, parameters->int1Parameter); -} - -//this action is weird in the original game, because it overwrites ALL -//IDS stats. -//in this version, if a stat is set to 0, it won't change -//it will alter only the main IDS stats -void GameScript::ChangeAIType(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return; - } - Object *ob = parameters->objects[1]; - if (!ob) { - return; - } - Actor *scr = (Actor *) Sender; - for (int i=0;iobjectFields[i]; - if (!val) continue; - if (!strnicmp(ObjectIDSTableNames[i],"ea",8)) { - scr->SetBase(IE_EA, val); - continue; - } - if (!strnicmp(ObjectIDSTableNames[i],"general",8)) { - scr->SetBase(IE_GENERAL, val); - continue; - } - if (!strnicmp(ObjectIDSTableNames[i],"race",8)) { - scr->SetBase(IE_RACE, val); - continue; - } - if (!strnicmp(ObjectIDSTableNames[i],"class",8)) { - scr->SetBase(IE_CLASS, val); - continue; - } - if (!strnicmp(ObjectIDSTableNames[i],"gender",8)) { - scr->SetBase(IE_SEX, val); - continue; - } - if (!strnicmp(ObjectIDSTableNames[i],"specific",8)) { - scr->SetBase(IE_SPECIFIC, val); - continue; - } - if (!strnicmp(ObjectIDSTableNames[i],"align",8)) { - scr->SetBase(IE_ALIGNMENT, val); - continue; - } - } -} - -//same as MoveToPoint, but not blocking -void GameScript::Leader(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - - char Tmp[256]; - - snprintf(Tmp, 256, "MoveToPoint([%d.%d])", parameters->pointParameter.x, parameters->pointParameter.y); - Action *newact = GenerateAction(Tmp); - Sender->AddAction(newact); -} - -//same as MoveToPointNoRecticle, but not blocking -void GameScript::Follow(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return; - } - - char Tmp[256]; - - snprintf(Tmp, 256, "MoveToPointNoRecticle([%d.%d])", parameters->pointParameter.x, parameters->pointParameter.y); - Action *newact = GenerateAction(Tmp); - Sender->AddAction(newact); -} - -void GameScript::FollowCreature(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - - Scriptable* tar = GetStoredActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type!=ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Actor *scr = (Actor *)Sender; - Actor *actor = (Actor *)tar; - scr->LastFollowed = actor->GetGlobalID(); - scr->FollowOffset.empty(); - if (!scr->InMove() || scr->Destination != actor->Pos) { - scr->WalkTo(actor->Pos, 0, 1); - } -} - -void GameScript::RunFollow(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - - Scriptable* tar = GetStoredActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type!=ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Actor *scr = (Actor *)Sender; - Actor *actor = (Actor *)tar; - scr->LastFollowed = actor->GetGlobalID(); - scr->FollowOffset.empty(); - if (!scr->InMove() || scr->Destination != actor->Pos) { - scr->WalkTo(actor->Pos, IF_RUNNING, 1); - } -} - -void GameScript::ProtectPoint(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Actor *scr = (Actor *)Sender; - if (!scr->InMove() || scr->Destination != parameters->pointParameter) { - scr->WalkTo( parameters->pointParameter, 0, 1 ); - } - // we should handle 'Protect' here rather than just unblocking - Sender->ReleaseCurrentAction(); -} - -void GameScript::ProtectObject(Scriptable* Sender, Action* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - - Scriptable* tar = GetStoredActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type!=ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Actor *scr = (Actor *)Sender; - Actor *actor = (Actor *)tar; - scr->LastFollowed = actor->GetGlobalID(); - scr->LastProtectee = actor->GetGlobalID(); - actor->LastProtector = scr->GetGlobalID(); - //not exactly range - scr->FollowOffset.x = parameters->int0Parameter; - scr->FollowOffset.y = parameters->int0Parameter; - if (!scr->InMove() || scr->Destination != tar->Pos) { - scr->WalkTo( tar->Pos, 0, MAX_OPERATING_DISTANCE ); - } - // we should handle 'Protect' here rather than just unblocking - Sender->ReleaseCurrentAction(); -} - -//keeps following the object in formation -void GameScript::FollowObjectFormation(Scriptable* Sender, Action* parameters) -{ - GameControl *gc = core->GetGameControl(); - if (!gc) { - Sender->ReleaseCurrentAction(); - return; - } - if (Sender->Type!=ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - - Scriptable* tar = GetStoredActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type!=ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Actor *scr = (Actor *)Sender; - Actor *actor = (Actor *)tar; - scr->LastFollowed = actor->GetGlobalID(); - ieDword formation = parameters->int0Parameter; - ieDword pos = parameters->int1Parameter; - scr->FollowOffset = gc->GetFormationOffset(formation, pos); - if (!scr->InMove() || scr->Destination != tar->Pos) { - scr->WalkTo( tar->Pos, 0, 1 ); - } - Sender->ReleaseCurrentAction(); -} - -//walks to a specific offset of target (quite like movetoobject) -void GameScript::Formation(Scriptable* Sender, Action* parameters) -{ - GameControl *gc = core->GetGameControl(); - if (!gc) { - Sender->ReleaseCurrentAction(); - return; - } - if (Sender->Type!=ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Scriptable* tar = GetStoredActorFromObject( Sender, parameters->objects[1] ); - if (!tar) { - Sender->ReleaseCurrentAction(); - return; - } - Actor *scr = (Actor *)Sender; - ieDword formation = parameters->int0Parameter; - ieDword pos = parameters->int1Parameter; - Point FollowOffset = gc->GetFormationOffset(formation, pos); - FollowOffset.x+=tar->Pos.x; - FollowOffset.y+=tar->Pos.y; - if (!scr->InMove() || scr->Destination != FollowOffset) { - scr->WalkTo( FollowOffset, 0, 1 ); - } -} - -void GameScript::TransformItem(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type!=ST_ACTOR) { - return; - } - TransformItemCore((Actor *)tar, parameters, true); -} - -void GameScript::TransformPartyItem(Scriptable* /*Sender*/, Action* parameters) -{ - Game *game = core->GetGame(); - int i = game->GetPartySize(false); - while (i--) { - Actor *tar = game->GetPC(i, false); - TransformItemCore(tar, parameters, true); - } -} - -void GameScript::TransformItemAll(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type!=ST_ACTOR) { - return; - } - TransformItemCore((Actor *)tar, parameters, false); -} - -void GameScript::TransformPartyItemAll(Scriptable* /*Sender*/, Action* parameters) -{ - Game *game = core->GetGame(); - int i = game->GetPartySize(false); - while (i--) { - Actor *tar = game->GetPC(i, false); - TransformItemCore(tar, parameters, false); - } -} - -void GameScript::GeneratePartyMember(Scriptable* /*Sender*/, Action* parameters) -{ - AutoTable pcs("bios"); - if (!pcs) { - return; - } - const char* string = pcs->QueryField( parameters->int0Parameter, 0 ); - int pos = gamedata->LoadCreature(string,0,false); - if (pos<0) { - return; - } - Actor *actor = core->GetGame()->GetNPC(pos); - if (!actor) { - return; - } - actor->SetOrientation(parameters->int1Parameter, false); - actor->MoveTo(parameters->pointParameter); -} - -void GameScript::EnableFogDither(Scriptable* /*Sender*/, Action* /*parameters*/) -{ - core->FogOfWar|=FOG_DRAWFOG; -} - -void GameScript::DisableFogDither(Scriptable* /*Sender*/, Action* /*parameters*/) -{ - core->FogOfWar&=~FOG_DRAWFOG; -} - -void DeleteAllSpriteCovers() -{ - Game *game = core->GetGame(); - int i = game->GetPartySize(false); - while (i--) { - Selectable *tar = (Selectable *) game->GetPC(i, false); - tar->SetSpriteCover(NULL); - } -} - -void GameScript::EnableSpriteDither(Scriptable* /*Sender*/, Action* /*parameters*/) -{ - core->FogOfWar&=~FOG_DITHERSPRITES; - DeleteAllSpriteCovers(); -} - -void GameScript::DisableSpriteDither(Scriptable* /*Sender*/, Action* /*parameters*/) -{ - core->FogOfWar|=~FOG_DITHERSPRITES; - DeleteAllSpriteCovers(); -} - -//the PST crew apparently loved hardcoding stuff -ieResRef RebusResRef={"DABUS1"}; - -void GameScript::FloatRebus(Scriptable* Sender, Action* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] ); - if (!tar || tar->Type!=ST_ACTOR) { - return; - } - Actor *actor = (Actor *)tar; - RebusResRef[5]=(char) core->Roll(1,5,'0'); - ScriptedAnimation *vvc = gamedata->GetScriptedAnimation(RebusResRef, 0); - if (vvc) { - //setting the height - vvc->ZPos=actor->size*20; - vvc->PlayOnce(); - //maybe this needs setting up some time - vvc->SetDefaultDuration(20); - actor->AddVVCell(vvc); - } -} - -void GameScript::IncrementKillStat(Scriptable* Sender, Action* parameters) -{ - DataFileMgr * ini = core->GetBeastsINI(); - if (!ini) { - return; - } - char key[5]; - sprintf(key,"%d", parameters->int0Parameter); - const char *variable = ini->GetKeyAsString( key, "killvar", NULL ); - if (!variable) { - return; - } - ieDword value = CheckVariable( Sender, variable, "GLOBAL" ) + 1; - SetVariable( Sender, variable, "GLOBAL", value ); -} - -void GameScript::SpellCastEffect(Scriptable* Sender, Action* parameters) -{ - Scriptable* src = GetActorFromObject( Sender, parameters->objects[1] ); - if (!src) { - return; - } - //TODO: finish this -} - -//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 -static EffectRef fx_iwd_visual_spell_hit_ref = { "IWDVisualSpellHit", -1 }; - -void GameScript::SpellHitEffectSprite(Scriptable* Sender, Action* parameters) -{ - Scriptable* src = GetActorFromObject( Sender, parameters->objects[1] ); - if (!src) { - return; - } - Scriptable* tar = GetActorFromObject( Sender, parameters->objects[2] ); - if (!tar || tar->Type!=ST_ACTOR) { - return; - } - int opcode = EffectQueue::ResolveEffect(fx_iwd_visual_spell_hit_ref); - Effect *fx = core->GetEffect(opcode); - if (!fx) { - //invalid effect name didn't resolve to opcode - return; - } - - //vvc type - fx->Parameter2 = parameters->int0Parameter; - //height (not sure if this is in the opcode, but seems acceptable) - fx->Parameter1 = parameters->int1Parameter; - fx->Probability1=100; - fx->TimingMode=FX_DURATION_INSTANT_PERMANENT_AFTER_BONUSES; - core->ApplyEffect(fx, (Actor *) tar, src); -} - -void GameScript::SpellHitEffectPoint(Scriptable* Sender, Action* parameters) -{ - Scriptable* src = GetActorFromObject( Sender, parameters->objects[1] ); - if (!src) { - return; - } - - int opcode = EffectQueue::ResolveEffect(fx_iwd_visual_spell_hit_ref); - Effect *fx = core->GetEffect(opcode); - if (!fx) { - //invalid effect name didn't resolve to opcode - return; - } - - //vvc type - fx->Parameter2 = parameters->int0Parameter; - //height (not sure if this is in the opcode, but seems acceptable) - fx->Parameter1 = parameters->int1Parameter; - fx->Probability1=100; - fx->TimingMode=FX_DURATION_INSTANT_PERMANENT_AFTER_BONUSES; - fx->PosX=parameters->pointParameter.x; - fx->PosY=parameters->pointParameter.y; - core->ApplyEffect(fx, NULL, src); -} - - -void GameScript::ClickLButtonObject(Scriptable* Sender, Action* parameters) -{ - Scriptable *tar = GetActorFromObject(Sender, parameters->objects[1] ); - if (!tar) { - Sender->ReleaseCurrentAction(); // this is blocking for some reason? - return; - } - ClickCore(Sender, tar->Pos, GEM_MB_ACTION, parameters->int0Parameter); -} - -void GameScript::ClickLButtonPoint(Scriptable* Sender, Action* parameters) -{ - ClickCore(Sender, parameters->pointParameter, GEM_MB_ACTION, parameters->int0Parameter); -} - -void GameScript::ClickRButtonObject(Scriptable* Sender, Action* parameters) -{ - Scriptable *tar = GetActorFromObject(Sender, parameters->objects[1] ); - if (!tar) { - Sender->ReleaseCurrentAction(); // this is blocking for some reason? - return; - } - ClickCore(Sender, tar->Pos, GEM_MB_MENU, parameters->int0Parameter); -} - -void GameScript::ClickRButtonPoint(Scriptable* Sender, Action* parameters) -{ - ClickCore(Sender, parameters->pointParameter, GEM_MB_MENU, parameters->int0Parameter); -} - -void GameScript::DoubleClickLButtonObject(Scriptable* Sender, Action* parameters) -{ - Scriptable *tar = GetActorFromObject(Sender, parameters->objects[1] ); - if (!tar) { - Sender->ReleaseCurrentAction(); // this is blocking for some reason? - return; - } - ClickCore(Sender, tar->Pos, GEM_MB_ACTION|GEM_MB_DOUBLECLICK, parameters->int0Parameter); -} - -void GameScript::DoubleClickLButtonPoint(Scriptable* Sender, Action* parameters) -{ - ClickCore(Sender, parameters->pointParameter, GEM_MB_ACTION|GEM_MB_DOUBLECLICK, parameters->int0Parameter); -} - -void GameScript::DoubleClickRButtonObject(Scriptable* Sender, Action* parameters) -{ - Scriptable *tar = GetActorFromObject(Sender, parameters->objects[1] ); - if (!tar) { - Sender->ReleaseCurrentAction(); // this is blocking for some reason? - return; - } - ClickCore(Sender, tar->Pos, GEM_MB_MENU|GEM_MB_DOUBLECLICK, parameters->int0Parameter); -} - -void GameScript::DoubleClickRButtonPoint(Scriptable* Sender, Action* parameters) -{ - ClickCore(Sender, parameters->pointParameter, GEM_MB_MENU|GEM_MB_DOUBLECLICK, parameters->int0Parameter); -} - -//Picks 5 lines from wish.2da -//Gets the 5 values (column is int0parameter) from the table. -//Sets the five wishpowerNN to 1, while resets the rest to 0. -//TODO: investigate what happens with * values -void GameScript::SetupWish(Scriptable* Sender, Action* parameters) -{ - SetupWishCore(Sender, parameters->int0Parameter, parameters->int1Parameter); -} - -//The same as the previous action, except that the column parameter comes from -//the target object's wisdom directly (this action is not used in the original) -void GameScript::SetupWishObject(Scriptable* Sender, Action* parameters) -{ - Scriptable *tar = GetActorFromObject(Sender, parameters->objects[1] ); - if (!tar || tar->Type!=ST_ACTOR) { - return; - } - SetupWishCore(Sender, ((Actor *)tar)->GetStat(IE_WIS), parameters->int0Parameter); -} - -//GemRB specific action -//Sets up multiple tokens randomly (one per 2da row) -//the row label column sets the token names -void GameScript::SetToken2DA(Scriptable* /*Sender*/, Action* parameters) -{ - int count; - int i,j; - ieVariable tokenname; - - AutoTable tm(parameters->string0Parameter); - if (!tm) { - printStatus( "ERROR", LIGHT_RED ); - print( "Cannot find %s.2da.\n", parameters->string0Parameter); - return; - } - - count = tm->GetRowCount(); - for(i=0;iRoll(1,tm->GetColumnCount(i),-1); - strnuprcpy(tokenname, tm->GetRowName(i), 32); - core->GetTokenDictionary()->SetAtCopy( tokenname, tm->QueryField(i, j) ); - } -} - -//this is a gemrb extension for scriptable tracks -void GameScript::SetTrackString(Scriptable* Sender, Action* parameters) -{ - Map *map = Sender->GetCurrentArea(); - if (!map) return; - map->SetTrackString(parameters->int0Parameter, parameters->int1Parameter, parameters->int2Parameter); -} - -void GameScript::StateOverrideFlag(Scriptable* /*Sender*/, Action* parameters) -{ - core->GetGame()->StateOverrideFlag = parameters->int0Parameter; -} - -void GameScript::StateOverrideTime(Scriptable* /*Sender*/, Action* parameters) -{ - core->GetGame()->StateOverrideTime = parameters->int0Parameter; -} - -void GameScript::BanterBlockFlag(Scriptable* /*Sender*/, Action* parameters) -{ - core->GetGame()->BanterBlockFlag = parameters->int0Parameter; -} - -void GameScript::BanterBlockTime(Scriptable* /*Sender*/, Action* parameters) -{ - core->GetGame()->BanterBlockTime = parameters->int0Parameter; -} - -void GameScript::SetNamelessDeath(Scriptable* Sender, Action* parameters) -{ - ieResRef area; - - snprintf(area,8,"AR%04d", parameters->int0Parameter); - IniSpawn *sp = Sender->GetCurrentArea()->INISpawn; - if (!sp) { - return; - } - sp->SetNamelessDeath(area, parameters->pointParameter, parameters->int1Parameter); -} diff --git a/project/jni/application/gemrb/gemrb/core/GameScript/GSUtils.cpp b/project/jni/application/gemrb/gemrb/core/GameScript/GSUtils.cpp deleted file mode 100644 index 26fa7fc43..000000000 --- a/project/jni/application/gemrb/gemrb/core/GameScript/GSUtils.cpp +++ /dev/null @@ -1,2285 +0,0 @@ -/* 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 "GameScript/GSUtils.h" -#include "GameScript/Matching.h" - -#include "strrefs.h" -#include "defsounds.h" - -#include "Audio.h" -#include "CharAnimations.h" -#include "DialogHandler.h" -#include "DisplayMessage.h" -#include "Game.h" -#include "GameData.h" -#include "GlobalTimer.h" -#include "Interface.h" -#include "Item.h" -#include "Map.h" -#include "Spell.h" -#include "StringMgr.h" -#include "TableMgr.h" -#include "TileMap.h" -#include "Video.h" -#include "GUI/GameControl.h" -#include "Scriptable/Container.h" -#include "Scriptable/Door.h" -#include "Scriptable/InfoPoint.h" - -#include - -//these tables will get freed by Core -Holder triggersTable; -Holder actionsTable; -Holder overrideActionsTable; -Holder objectsTable; -TriggerFunction triggers[MAX_TRIGGERS]; -ActionFunction actions[MAX_ACTIONS]; -short actionflags[MAX_ACTIONS]; -short triggerflags[MAX_TRIGGERS]; -ObjectFunction objects[MAX_OBJECTS]; -IDSFunction idtargets[MAX_OBJECT_FIELDS]; -Cache SrcCache; //cache for string resources (pst) -Cache BcsCache; //cache for scripts -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; -int ExtraParametersCount = 0; -int InDebug = 0; -int happiness[3][20]; -int RandomNumValue; -// reaction modifiers (by reputation and charisma) -int rmodrep[20]; -int rmodchr[25]; -Gem_Polygon **polygons; - -void InitScriptTables() -{ - //initializing the happiness table - { - AutoTable tab("happy"); - if (tab) { - for (int alignment=0;alignment<3;alignment++) { - for (int reputation=0;reputation<20;reputation++) { - happiness[alignment][reputation]=strtol(tab->QueryField(reputation,alignment), NULL, 0); - } - } - } - } - - //initializing the reaction mod. reputation table - AutoTable rmr("rmodrep"); - if (rmr) { - for (int reputation=0; reputation<20; reputation++) { - rmodrep[reputation] = strtol(rmr->QueryField(0, reputation), NULL, 0); - } - } - - //initializing the reaction mod. charisma table - AutoTable rmc("rmodchr"); - if (rmc) { - for (int charisma=0; charisma<25; charisma++) { - rmodchr[charisma] = strtol(rmc->QueryField(0, charisma), NULL, 0); - } - } -} - -int GetReaction(Actor *target, Scriptable *Sender) -{ - int chr, rep, reaction; - chr = target->GetStat(IE_CHR)-1; - if (target->GetStat(IE_EA) == EA_PC) { - rep = core->GetGame()->Reputation/10; - } else { - rep = target->GetStat(IE_REPUTATION); - } - reaction = 10 + rmodrep[rep] + rmodchr[chr]; - - // add -4 penalty when dealing with racial enemies - if (Sender && target->GetRangerLevel() && Sender->Type == ST_ACTOR && target->IsRacialEnemy((Actor *)Sender)) { - reaction -= 4; - } - - return reaction; -} - -int GetHappiness(Scriptable* Sender, int reputation) -{ - if (Sender->Type != ST_ACTOR) { - return 0; - } - Actor* ab = ( Actor* ) Sender; - int alignment = ab->GetStat(IE_ALIGNMENT)&AL_GE_MASK; //good / evil - if (reputation > 200) { - reputation = 200; - } - return happiness[alignment][reputation/10-1]; -} - -int GetHPPercent(Scriptable* Sender) -{ - if (Sender->Type != ST_ACTOR) { - return 0; - } - Actor* ab = ( Actor* ) Sender; - int hp1 = ab->GetStat(IE_MAXHITPOINTS); - if (hp1<1) { - return 0; - } - int hp2 = ab->GetBase(IE_HITPOINTS); - if (hp2<1) { - return 0; - } - return hp2*100/hp1; -} - -void HandleBitMod(ieDword &value1, ieDword value2, int opcode) -{ - switch(opcode) { - case BM_AND: - value1 = ( value1& value2 ); - break; - case BM_OR: - value1 = ( value1| value2 ); - break; - case BM_XOR: - value1 = ( value1^ value2 ); - break; - case BM_NAND: //this is a GemRB extension - value1 = ( value1& ~value2 ); - break; - case BM_SET: //this is a GemRB extension - value1 = value2; - break; - } -} - -// SPIT is not in the original engine spec, it is reserved for the -// enchantable items feature -// 0 1 2 3 4 -static const char *spell_suffices[]={"SPIT","SPPR","SPWI","SPIN","SPCL"}; - -//this function handles the polymorphism of Spell[RES] actions -//it returns spellres -bool ResolveSpellName(ieResRef spellres, Action *parameters) -{ - if (parameters->string0Parameter[0]) { - strnlwrcpy(spellres, parameters->string0Parameter, 8); - } else { - //resolve spell - int type = parameters->int0Parameter/1000; - int spellid = parameters->int0Parameter%1000; - if (type>4) { - return false; - } - sprintf(spellres, "%s%03d", spell_suffices[type], spellid); - } - return gamedata->Exists(spellres, IE_SPL_CLASS_ID); -} - -void ResolveSpellName(ieResRef spellres, ieDword number) -{ - //resolve spell - unsigned int type = number/1000; - int spellid = number%1000; - if (type>4) { - type=0; - } - sprintf(spellres, "%s%03d", spell_suffices[type], spellid); -} - -ieDword ResolveSpellNumber(const ieResRef spellres) -{ - int i; - - for(i=0;i<5;i++) { - if(!strnicmp(spellres, spell_suffices[i], 4)) { - int n = -1; - sscanf(spellres+4,"%d", &n); - if (n<0) { - return 0xffffffff; - } - return i*1000+n; - } - } - return 0xffffffff; -} - -bool ResolveItemName(ieResRef itemres, Actor *act, ieDword Slot) -{ - CREItem *itm = act->inventory.GetSlotItem(Slot); - if(itm) { - strnlwrcpy(itemres, itm->ItemResRef, 8); - return gamedata->Exists(itemres, IE_ITM_CLASS_ID); - } - return false; -} - -bool StoreHasItemCore(const ieResRef storename, const ieResRef itemname) -{ - CREItem item; - - Store* store = gamedata->GetStore(storename); - if (!store) { - printMessage("GameScript","Store cannot be opened!\n", LIGHT_RED); - return false; - } - - bool ret = false; - //don't use triggers (pst style), it would be possible to create infinite loops - if (store->FindItem(itemname, false) != (unsigned int)-1) { - ret=true; - } - // Don't call gamedata->SaveStore, we don't change it, and it remains cached. - return ret; -} - -//don't pass this point by reference, it is subject to change -void ClickCore(Scriptable *Sender, Point point, int type, int speed) -{ - Map *map = Sender->GetCurrentArea(); - if (!map) { - Sender->ReleaseCurrentAction(); - return; - } - Point p=map->TMap->GetMapSize(); - if (!p.PointInside(point)) { - Sender->ReleaseCurrentAction(); - return; - } - Video *video = core->GetVideoDriver(); - GlobalTimer *timer = core->timer; - timer->SetMoveViewPort( point.x, point.y, speed, true ); - timer->DoStep(0); - if (timer->ViewportIsMoving()) { - Sender->AddActionInFront( Sender->GetCurrentAction() ); - Sender->SetWait(1); - Sender->ReleaseCurrentAction(); - return; - } - - video->ConvertToScreen(point.x, point.y); - GameControl *win = core->GetGameControl(); - - point.x+=win->XPos; - point.y+=win->YPos; - video->MoveMouse(point.x, point.y); - video->ClickMouse(type); - Sender->ReleaseCurrentAction(); -} - -void TransformItemCore(Actor *actor, Action *parameters, bool onlyone) -{ - int i = actor->inventory.GetSlotCount(); - while(i--) { - CREItem *item = actor->inventory.GetSlotItem(i); - if (!item) { - continue; - } - if (strnicmp(item->ItemResRef, parameters->string0Parameter, 8) ) { - continue; - } - actor->inventory.SetSlotItemRes(parameters->string1Parameter,i,parameters->int0Parameter,parameters->int1Parameter,parameters->int2Parameter); - if (onlyone) { - break; - } - } -} - -//check if an inventory (container or actor) has item (could be recursive ?) -bool HasItemCore(Inventory *inventory, const ieResRef itemname, ieDword flags) -{ - if (inventory->HasItem(itemname, flags)) { - return true; - } - int i=inventory->GetSlotCount(); - while (i--) { - //maybe we could speed this up if we mark bag items with a flags bit - CREItem *itemslot = inventory->GetSlotItem(i); - if (!itemslot) - continue; - Item *item = gamedata->GetItem(itemslot->ItemResRef); - if (!item) - continue; - bool ret = false; - if (core->CanUseItemType(SLOT_BAG,item,NULL) ) { - //the store is the same as the item's name - ret = StoreHasItemCore(itemslot->ItemResRef, itemname); - } - gamedata->FreeItem(item, itemslot->ItemResRef); - if (ret) { - return true; - } - } - return false; -} - -void DisplayStringCore(Scriptable* Sender, int Strref, int flags) -{ - StringBlock sb; - char Sound[_MAX_PATH]; - - //no one hears you when you are in the Limbo! - if (!Sender->GetCurrentArea()) { - return; - } - - memset(&sb,0,sizeof(sb)); - Sound[0]=0; - print( "Displaying string on: %s\n", Sender->GetScriptName() ); - if (flags & DS_CONST) { - if (Sender->Type!=ST_ACTOR) { - printMessage("GameScript","Verbal constant not supported for non actors!\n", LIGHT_RED); - return; - } - Actor* actor = ( Actor* ) Sender; - if ((ieDword) Strref>=VCONST_COUNT) { - printMessage("GameScript","Invalid verbal constant!\n", LIGHT_RED); - return; - } - - int tmp=(int) actor->GetVerbalConstant(Strref); - if (tmp <= 0 || (actor->GetStat(IE_MC_FLAGS) & MC_EXPORTABLE)) { - //get soundset based string constant - actor->ResolveStringConstant( sb.Sound, (unsigned int) Strref); - if (actor->PCStats && actor->PCStats->SoundFolder[0]) { - snprintf(Sound, _MAX_PATH, "%s/%s", - actor->PCStats->SoundFolder, sb.Sound); - } else { - memcpy(Sound, sb.Sound, sizeof(ieResRef) ); - } - } - Strref = tmp; - - //display the verbal constants in the console - ieDword charactersubtitles = 0; - core->GetDictionary()->Lookup("Subtitles", charactersubtitles); - if (charactersubtitles) { - flags |= DS_CONSOLE; - } - } - - if ((Strref != -1) && !sb.Sound[0]) { - sb = core->strings->GetStringBlock( Strref ); - memcpy(Sound, sb.Sound, sizeof(ieResRef) ); - if (sb.text[0] && strcmp(sb.text," ") && (flags & DS_CONSOLE)) { - //can't play the sound here, we have to delay action - //and for that, we have to know how long the text takes - if(flags&DS_NONAME) { - displaymsg->DisplayString( sb.text ); - } else { - displaymsg->DisplayStringName( Strref, 0xf0f0f0, Sender, 0); - } - } - if (sb.text[0] && strcmp(sb.text," ") && (flags & (DS_HEAD | DS_AREA))) { - Sender->DisplayHeadText( sb.text ); - //don't free sb.text, it is residing in Sender - if (flags & DS_AREA) { - Sender->FixHeadTextPos(); - } - } else { - core->FreeString( sb.text ); - } - } - if (Sound[0] && !(flags&DS_SILENT) ) { - ieDword speech = GEM_SND_RELATIVE; //disable position - if (flags&DS_SPEECH) speech|=GEM_SND_SPEECH; - unsigned int len = 0; - core->GetAudioDrv()->Play( Sound,0,0,speech,&len ); - ieDword counter = ( AI_UPDATE_TIME * len ) / 1000; - if ((counter != 0) && (flags &DS_WAIT) ) - Sender->SetWait( counter ); - } -} - -int CanSee(Scriptable* Sender, Scriptable* target, bool range, int seeflag) -{ - Map *map; - - if (target->Type==ST_ACTOR) { - Actor *tar = (Actor *) target; - - if (!tar->ValidTarget(seeflag)) { - return 0; - } - } - - map = target->GetCurrentArea(); - //if (!(seeflag&GA_GLOBAL)) { - if (!map || map!=Sender->GetCurrentArea() ) { - return 0; - } - //} - - if (range) { - unsigned int dist; - - if (Sender->Type == ST_ACTOR) { - Actor* snd = ( Actor* ) Sender; - dist = snd->Modified[IE_VISUALRANGE]; - } else { - dist = 30; - } - - if (Distance(target->Pos, Sender->Pos) > dist * 15) { - return 0; - } - } - - return map->IsVisible(target->Pos, Sender->Pos); -} - -//non actors can see too (reducing function to LOS) -//non actors can be seen too (reducing function to LOS) -int SeeCore(Scriptable* Sender, Trigger* parameters, int justlos) -{ - //see dead - int flags; - - if (parameters->int0Parameter) { - flags = GA_DETECT; - } else { - flags = GA_NO_DEAD; - } - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter, flags ); - /* don't set LastSeen if this isn't an actor */ - if (!tar) { - return 0; - } - //both are actors - if (CanSee(Sender, tar, true, flags) ) { - if (justlos) { - return 1; - } - if (Sender->Type==ST_ACTOR && tar->Type==ST_ACTOR) { - Actor* snd = ( Actor* ) Sender; - //additional checks for invisibility? - snd->LastSeen = tar->GetGlobalID(); - } - return 1; - } - return 0; -} - -//transfering item from Sender to target -//if target has no inventory, the item will be destructed -//if target can't get it, it will be dropped at its feet -int MoveItemCore(Scriptable *Sender, Scriptable *target, const char *resref, int flags, int setflag) -{ - Inventory *myinv; - Map *map; - // track whether we are dealing with our party and need to display feedback - bool lostitem = false; - bool gotitem = false; - - if (!target) { - return MIC_INVALID; - } - map=Sender->GetCurrentArea(); - switch(Sender->Type) { - case ST_ACTOR: - myinv=&((Actor *) Sender)->inventory; - if (((Actor *)Sender)->InParty) lostitem = true; - break; - case ST_CONTAINER: - myinv=&((Container *) Sender)->inventory; - break; - default: - return MIC_INVALID; - } - CREItem *item; - myinv->RemoveItem(resref, flags, &item); - if (!item) { - // nothing was removed - return MIC_NOITEM; - } - - item->Flags|=setflag; - - switch(target->Type) { - case ST_ACTOR: - myinv=&((Actor *) target)->inventory; - if (((Actor *) target)->InParty) gotitem = true; - break; - case ST_CONTAINER: - myinv=&((Container *) target)->inventory; - break; - default: - myinv = NULL; - break; - } - if (!myinv) { - delete item; - if (lostitem) displaymsg->DisplayConstantString(STR_LOSTITEM, 0xbcefbc); - return MIC_GOTITEM; // actually it was lost, not gained - } - if ( myinv->AddSlotItem(item, SLOT_ONLYINVENTORY) !=ASI_SUCCESS) { - // drop it at my feet - map->AddItemToLocation(target->Pos, item); - if (gotitem) displaymsg->DisplayConstantString(STR_INVFULL_ITEMDROP, 0xbcefbc); - return MIC_FULL; - } - if (gotitem) displaymsg->DisplayConstantString(STR_GOTITEM, 0xbcefbc); - return MIC_GOTITEM; -} - -/*FIXME: what is 'base'*/ -void PolymorphCopyCore(Actor *src, Actor *tar, bool base) -{ - tar->SetBase(IE_ANIMATION_ID, src->GetStat(IE_ANIMATION_ID) ); - if (!base) { - tar->SetBase(IE_ARMOR_TYPE, src->GetStat(IE_ARMOR_TYPE) ); - for (int i=0;i<7;i++) { - tar->SetBase(IE_COLORS+i, src->GetStat(IE_COLORS+i) ); - } - } - tar->SetName(src->GetName(0),0); - tar->SetName(src->GetName(1),1); - //add more attribute copying -} - -void CreateCreatureCore(Scriptable* Sender, Action* parameters, int flags) -{ - Scriptable *tmp = GetActorFromObject( Sender, parameters->objects[1] ); - //if there is nothing to copy, don't spawn anything - if (flags & CC_COPY) { - if (!tmp || tmp->Type != ST_ACTOR) { - return; - } - } - - Actor* ab; - if (flags & CC_STRING1) { - ab = gamedata->GetCreature(parameters->string1Parameter); - } - else { - ab = gamedata->GetCreature(parameters->string0Parameter); - } - - if (!ab) { - printMessage("GameScript", "Failed to create creature! (missing creature file %s?)\n", LIGHT_RED, - parameters->string0Parameter); - // maybe this should abort()? - return; - } - - //iwd2 allows an optional scriptname to be set - //but bg2 doesn't have this feature - //this way it works for both games - if ((flags & CC_SCRIPTNAME) && parameters->string1Parameter[0]) { - ab->SetScriptName(parameters->string1Parameter); - } - - int radius; - Point pnt; - - radius=0; - switch (flags & CC_MASK) { - //creates creature just off the screen - case CC_OFFSCREEN: - { - Region vp = core->GetVideoDriver()->GetViewport(); - radius=vp.w/2; //actually it must be further divided by the tile size, hmm 16? - } - //falling through - case CC_OBJECT://use object + offset - if (tmp) Sender=tmp; - //falling through - case CC_OFFSET://use sender + offset - pnt.x = parameters->pointParameter.x+Sender->Pos.x; - pnt.y = parameters->pointParameter.y+Sender->Pos.y; - break; - default: //absolute point, but -1,-1 means AtFeet - pnt.x = parameters->pointParameter.x; - pnt.y = parameters->pointParameter.y; - if (pnt.isempty()) { - pnt.x = Sender->Pos.x; - pnt.y = Sender->Pos.y; - } - break; - } - - Map *map = Sender->GetCurrentArea(); - map->AddActor( ab ); - ab->SetPosition( pnt, flags&CC_CHECK_IMPASSABLE, radius ); - ab->SetOrientation(parameters->int0Parameter, false ); - - //if string1 is animation, then we can't use it for a DV too - if (flags & CC_PLAY_ANIM) { - CreateVisualEffectCore( ab, ab->Pos, parameters->string1Parameter, 1); - } else { - //setting the deathvariable if it exists (iwd2) - if (parameters->string1Parameter[0]) { - ab->SetScriptName(parameters->string1Parameter); - } - } - - if (flags & CC_COPY) { - PolymorphCopyCore ( (Actor *) tmp, ab, false); - } -} - -static ScriptedAnimation *GetVVCEffect(const char *effect, int iterations) -{ - if (effect[0]) { - ScriptedAnimation* vvc = gamedata->GetScriptedAnimation(effect, false); - if (!vvc) { - printMessage("GameScript","Failed to create effect.",LIGHT_RED); - return NULL; - } - if (iterations) { - vvc->SetDefaultDuration( vvc->GetSequenceDuration(AI_UPDATE_TIME * iterations)); - } else { - vvc->PlayOnce(); - } - return vvc; - } - return NULL; -} - -void CreateVisualEffectCore(Actor *target, const char *effect, int iterations) -{ - ScriptedAnimation *vvc = GetVVCEffect(effect, iterations); - if (vvc) { - target->AddVVCell( vvc ); - } -} - -void CreateVisualEffectCore(Scriptable *Sender, const Point &position, const char *effect, int iterations) -{ - ScriptedAnimation *vvc = GetVVCEffect(effect, iterations); - if (vvc) { - vvc->XPos +=position.x; - vvc->YPos +=position.y; - Sender->GetCurrentArea( )->AddVVCell( vvc ); - } -} - -//this destroys the current actor and replaces it with another -void ChangeAnimationCore(Actor *src, const char *resref, bool effect) -{ - Actor *tar = gamedata->GetCreature(resref); - if (tar) { - Map *map = src->GetCurrentArea(); - 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); - if (effect) { - CreateVisualEffectCore(tar, tar->Pos,"smokepuffeffect",1); - } - } -} - -void EscapeAreaCore(Scriptable* Sender, const Point &p, const char* area, const Point &enter, int flags, int wait) -{ - char Tmp[256]; - - if ( !p.isempty() && PersonalDistance(p, Sender)>MAX_OPERATING_DISTANCE) { - //MoveNearerTo will return 0, if the actor is in move - //it will return 1 (the fourth parameter) if the target is unreachable - if (!MoveNearerTo(Sender, p, MAX_OPERATING_DISTANCE,1) ) { - if (!Sender->InMove()) print("At least it said so...\n"); - return; - } - } - - if (flags &EA_DESTROY) { - //this must be put into a non-const variable - sprintf( Tmp, "DestroySelf()" ); - } else { - // last parameter is 'face', which should be passed from relevant action parameter.. - sprintf( Tmp, "MoveBetweenAreas(\"%s\",[%hd.%hd],%d)", area, enter.x, enter.y, 0 ); - } - printMessage("GSUtils", "Executing %s in EscapeAreaCore\n", WHITE, Tmp); - //drop this action, but add another (destroyself or movebetweenareas) - //between the arrival and the final escape, there should be a wait time - //that wait time could be handled here - if (wait) { - print("But wait a bit... (%d)\n", wait); - Sender->SetWait(wait); - } - Sender->ReleaseCurrentAction(); - Action * action = GenerateAction( Tmp); - Sender->AddActionInFront( action ); -} - -void GetTalkPositionFromScriptable(Scriptable* scr, Point &position) -{ - switch (scr->Type) { - case ST_AREA: case ST_GLOBAL: - position = scr->Pos; //fake - break; - case ST_ACTOR: - //if there are other moveables, put them here - position = ((Movable *) scr)->GetMostLikelyPosition(); - break; - case ST_TRIGGER: case ST_PROXIMITY: case ST_TRAVEL: - if (((InfoPoint *) scr)->Flags & TRAP_USEPOINT) { - position=((InfoPoint *) scr)->UsePoint; - break; - } - position=((InfoPoint *) scr)->TrapLaunch; - break; - case ST_DOOR: case ST_CONTAINER: - position=((Highlightable *) scr)->TrapLaunch; - break; - } -} - -void GetPositionFromScriptable(Scriptable* scr, Point &position, bool dest) -{ - if (!dest) { - position = scr->Pos; - return; - } - switch (scr->Type) { - case ST_AREA: case ST_GLOBAL: - position = scr->Pos; //fake - break; - case ST_ACTOR: - //if there are other moveables, put them here - position = ((Movable *) scr)->GetMostLikelyPosition(); - break; - case ST_TRIGGER: case ST_PROXIMITY: case ST_TRAVEL: - if (((InfoPoint *) scr)->Flags & TRAP_USEPOINT) { - position=((InfoPoint *) scr)->UsePoint; - break; - } - case ST_DOOR: case ST_CONTAINER: - position=((Highlightable *) scr)->TrapLaunch; - } -} - -int CheckInteract(const char *talker, const char *target) -{ - AutoTable interact("interact"); - if(!interact) - return 0; - const char *value = interact->QueryField(talker, target); - if(!value) - return 0; - switch(value[0]) { - case 's': - return I_SPECIAL; - case 'c': - return I_COMPLIMENT; - case 'i': - return I_INSULT; - } - return 0; -} - -static ieResRef PlayerDialogRes = "PLAYERx\0"; - -void BeginDialog(Scriptable* Sender, Action* parameters, int Flags) -{ - Scriptable* tar, *scr; - int seeflag = GA_NO_DEAD; - - if (InDebug&ID_VARIABLES) { - print("BeginDialog core\n"); - } - if (Flags & BD_OWN) { - tar = GetStoredActorFromObject( Sender, parameters->objects[1], seeflag); - scr = tar; - } else { - tar = GetStoredActorFromObject( Sender, parameters->objects[1], seeflag); - scr = Sender; - } - if (!scr) { - printMessage("GameScript", "Speaker for dialog couldn't be found (Sender: %s, Type: %d) Flags:%d.\n", LIGHT_RED, - Sender->GetScriptName(), Sender->Type, Flags); - Sender->ReleaseCurrentAction(); - return; - } - - if (!tar || tar->Type!=ST_ACTOR) { - printMessage("GameScript", "Target for dialog couldn't be found (Sender: %s, Type: %d).\n", LIGHT_RED, - Sender->GetScriptName(), Sender->Type); - if (Sender->Type == ST_ACTOR) { - ((Actor *) Sender)->DebugDump(); - } - print ("Target object: "); - if (parameters->objects[1]) { - parameters->objects[1]->Dump(); - } else { - print("\n"); - } - Sender->ReleaseCurrentAction(); - return; - } - - Actor *speaker, *target; - - speaker = NULL; - target = (Actor *) tar; - if ((Flags & BD_CHECKDIST) && !CanSee(scr, target, false, seeflag) ) { - printMessage("GameScript", "CanSee returned false! Speaker (%s, type %d) and target are:\n", LIGHT_RED, - scr->GetScriptName(), scr->Type); - if (scr->Type == ST_ACTOR) { - ((Actor *) scr)->DebugDump(); - } - ((Actor *) tar)->DebugDump(); - Sender->ReleaseCurrentAction(); - return; - } - bool swap = false; - if (scr->Type==ST_ACTOR) { - speaker = (Actor *) scr; - if (speaker->GetStat(IE_STATE_ID)&STATE_DEAD) { - printMessage("GameScript"," ",LIGHT_RED); - print("Speaker is dead, cannot start dialogue. Speaker and target are:\n"); - speaker->DebugDump(); - target->DebugDump(); - Sender->ReleaseCurrentAction(); - return; - } - //DialogueRange is set in IWD - ieDword range = MAX_OPERATING_DISTANCE + speaker->GetBase(IE_DIALOGRANGE); - //making sure speaker is the protagonist, player, actor - if ( target->InParty == 1) swap = true; - else if ( speaker->InParty !=1 && target->InParty) swap = true; - //CHECKDIST works only for mobile scriptables - if (Flags&BD_CHECKDIST) { - if ( scr->GetCurrentArea()!=target->GetCurrentArea() || - PersonalDistance(scr, target)>range) { - MoveNearerTo(Sender, target, MAX_OPERATING_DISTANCE); - return; - } - } - } else { - //pst style dialog with trigger points - swap=true; - if (Flags&BD_CHECKDIST) { - Point TalkPos; - - if (target->InMove()) { - //waiting for target - Sender->AddActionInFront( Sender->GetCurrentAction() ); - Sender->ReleaseCurrentAction(); - Sender->SetWait(1); - return; - } - GetTalkPositionFromScriptable(scr, TalkPos); - if (PersonalDistance(TalkPos, target)>MAX_OPERATING_DISTANCE ) { - //try to force the target to come closer??? - GoNear(target, TalkPos); - Sender->AddActionInFront( Sender->GetCurrentAction() ); - Sender->ReleaseCurrentAction(); - Sender->SetWait(1); - return; - } - } - } - - GameControl* gc = core->GetGameControl(); - if (!gc) { - printMessage( "GameScript","Dialog cannot be initiated because there is no GameControl.", YELLOW ); - Sender->ReleaseCurrentAction(); - return; - } - //can't initiate dialog, because it is already there - if (gc->GetDialogueFlags()&DF_IN_DIALOG) { - if (Flags & BD_INTERRUPT) { - //break the current dialog if possible - gc->dialoghandler->EndDialog(true); - } - //check if we could manage to break it, not all dialogs are breakable! - if (gc->GetDialogueFlags()&DF_IN_DIALOG) { - printMessage( "GameScript","Dialog cannot be initiated because there is already one.", YELLOW ); - Sender->ReleaseCurrentAction(); - return; - } - } - - // starting a dialog ends cutscenes! - core->SetCutSceneMode(false); - - const char* Dialog = NULL; - AutoTable pdtable; - - switch (Flags & BD_LOCMASK) { - case BD_STRING0: - Dialog = parameters->string0Parameter; - if (Flags & BD_SETDIALOG) { - scr->SetDialog( Dialog ); - } - break; - case BD_SOURCE: - case BD_TARGET: - if (swap) Dialog = scr->GetDialog(); - else Dialog = target->GetDialog(GD_FEEDBACK); - break; - case BD_RESERVED: - //what if playerdialog was initiated from Player2? - PlayerDialogRes[5] = '1'; - Dialog = ( const char * ) PlayerDialogRes; - break; - case BD_INTERACT: //using the source for the dialog - const char* scriptingname = scr->GetScriptName(); - - /* use interact.2da for short, inlined dialogue */ - int type = CheckInteract(scriptingname, target->GetScriptName()); - if(type) { - //TODO increase interact counter in scr - speaker->Interact(type); - target->Response(type); - Sender->ReleaseCurrentAction(); - return; - } - /* banter dialogue */ - pdtable.load("interdia"); - //Dialog is a borrowed reference, we cannot free pdtable while it is being used - if (pdtable) { - Dialog = pdtable->QueryField( scriptingname, "FILE" ); - } - break; - } - - - //dialog is not meaningful - if (!Dialog || Dialog[0]=='*') { - Sender->ReleaseCurrentAction(); - return; - } - - //maybe we should remove the action queue, but i'm unsure - //no, we shouldn't even call this! - //Sender->ReleaseCurrentAction(); - - // moved this here from InitDialog, because InitDialog doesn't know which side is which - // post-swap (and non-actors always have IF_NOINT set) .. also added a check that it's - // actually busy doing something, for the same reason - if (target->GetInternalFlag()&IF_NOINT && (target->GetCurrentAction() || target->GetNextAction())) { - displaymsg->DisplayConstantString(STR_TARGETBUSY,0xff0000); - Sender->ReleaseCurrentAction(); - return; - } - - if (speaker!=target) { - if (swap) { - Scriptable *tmp = tar; - tar = scr; - scr = tmp; - } else { - if (!(Flags & BD_INTERRUPT)) { - // added CurrentAction as part of blocking action fixes - if (tar->GetCurrentAction() || tar->GetNextAction()) { - displaymsg->DisplayConstantString(STR_TARGETBUSY,0xff0000); - Sender->ReleaseCurrentAction(); - return; - } - } - } - } - - //don't clear target's actions, because a sequence like this will be broken: - //StartDialog([PC]); SetGlobal("Talked","LOCALS",1); - if (scr!=tar) { - if (scr->Type==ST_ACTOR) { - ((Actor *) scr)->SetOrientation(GetOrient( tar->Pos, scr->Pos), true); - } - if (tar->Type==ST_ACTOR) { - ((Actor *) tar)->SetOrientation(GetOrient( scr->Pos, tar->Pos), true); - } - } - - bool ret; - - if (Dialog[0]) { - //increasing NumTimesTalkedTo or NumTimesInteracted - if (Flags & BD_TALKCOUNT) { - gc->SetDialogueFlags(DF_TALKCOUNT, BM_OR); - } else if ((Flags & BD_LOCMASK) == BD_INTERACT) { - gc->SetDialogueFlags(DF_INTERACT, BM_OR); - } - - core->GetDictionary()->SetAt("DialogChoose",(ieDword) -1); - ret = gc->dialoghandler->InitDialog( scr, tar, Dialog); - } - else { - ret = false; - } - - Sender->ReleaseCurrentAction(); - - if (!ret) { - if (Flags & BD_NOEMPTY) { - return; - } - displaymsg->DisplayConstantStringName(STR_NOTHINGTOSAY,0xff0000,tar); - return; - } -} - -void MoveBetweenAreasCore(Actor* actor, const char *area, const Point &position, int face, bool adjust) -{ - printMessage("GameScript", "MoveBetweenAreas: %s to %s [%d.%d] face: %d\n", WHITE, - actor->GetName(0), area,position.x,position.y, face); - Map* map2; - Game* game = core->GetGame(); - if (area[0]) { //do we need to switch area? - Map* map1 = actor->GetCurrentArea(); - //we have to change the pathfinder - //to the target area if adjust==true - map2 = game->GetMap(area, false); - if ( map1!=map2 ) { - if (map1) { - map1->RemoveActor( actor ); - } - map2->AddActor( actor ); - } - } - actor->SetPosition(position, adjust); - if (face !=-1) { - actor->SetOrientation( face, false ); - } - // should this perhaps be a 'selected' check or similar instead? - if (actor->InParty) { - GameControl *gc=core->GetGameControl(); - gc->SetScreenFlags(SF_CENTERONACTOR,BM_OR); - game->ChangeSong(false, true); - } -} - -//repeat movement, until goal isn't reached -//if int0parameter is !=0, then it will try only x times -void MoveToObjectCore(Scriptable *Sender, Action *parameters, ieDword flags, bool untilsee) -{ - if (Sender->Type != ST_ACTOR) { - Sender->ReleaseCurrentAction(); - return; - } - Scriptable* target = GetStoredActorFromObject( Sender, parameters->objects[1] ); - if (!target) { - Sender->ReleaseCurrentAction(); - return; - } - Actor* actor = ( Actor* ) Sender; - if (untilsee && CanSee(actor, target, true, 0) ) { - Sender->ReleaseCurrentAction(); - return; - } else { - if (PersonalDistance(actor, target)ReleaseCurrentAction(); - return; - } - } - if (!actor->InMove() || actor->Destination != target->Pos) { - actor->WalkTo( target->Pos, flags, 0 ); - } - //hopefully this hack will prevent lockups - if (!actor->InMove()) { - Sender->ReleaseCurrentAction(); - return; - } - - //repeat movement... - Action *newaction = ParamCopyNoOverride(parameters); - if (newaction->int0Parameter!=1) { - if (newaction->int0Parameter) { - newaction->int0Parameter--; - } - actor->AddActionInFront(newaction); - actor->SetWait(1); - } - - Sender->ReleaseCurrentAction(); -} - -bool CreateItemCore(CREItem *item, const char *resref, int a, int b, int c) -{ - //copy the whole resref, including the terminating zero - strnuprcpy(item->ItemResRef, resref, 8); - if (!core->ResolveRandomItem(item)) - return false; - if (a==-1) { - //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); - } - } else { - item->Usages[0]=(ieWord) a; - item->Usages[1]=(ieWord) b; - item->Usages[2]=(ieWord) c; - } - item->Flags=0; - return true; -} - -//It is possible to attack CONTAINERS/DOORS as well!!! -void AttackCore(Scriptable *Sender, Scriptable *target, int flags) -{ - //this is a dangerous cast, make sure actor is Actor * !!! - Actor *actor = (Actor *) Sender; - - WeaponInfo wi; - ITMExtHeader *header = NULL; - ITMExtHeader *hittingheader = NULL; - int tohit; - ieDword Flags; - int DamageBonus, CriticalBonus; - int speed, style; - - //bool leftorright = (bool) ((attacksperround-attackcount)&1); - bool leftorright = false; - Actor *tar = NULL; - ieDword targetID = 0; - if (target->Type==ST_ACTOR) { - tar = (Actor *) target; - targetID = tar->GetGlobalID(); - } - if (actor == tar) { - Sender->ReleaseCurrentAction(); - return; - } - - //will return false on any errors (eg, unusable weapon) - if (!actor->GetCombatDetails(tohit, leftorright, wi, header, hittingheader, Flags, DamageBonus, speed, CriticalBonus, style, tar)) { - actor->SetStance(IE_ANI_READY); - Sender->ReleaseCurrentAction(); - return; - } - - if (header) wi.range *= 10; - else wi.range = 0; - - if ( target->Type == ST_DOOR || target->Type == ST_CONTAINER) { - wi.range += 10; - } - if (!(flags&AC_NO_SOUND) ) { - if (actor->LastTarget != targetID) { - //play attack sound for party members - if (actor->InParty) { - //pick from all 5 possible verbal constants - actor->VerbalConstant(VB_ATTACK, 5); - //DisplayStringCore(Sender, VB_ATTACK, DS_CONSOLE|DS_CONST ); - } - //display attack message - displaymsg->DisplayConstantStringAction(STR_ACTION_ATTACK,0xf0f0f0, Sender, target); - } - } - //action performed - if(target->Type == ST_ACTOR) { - actor->SetTarget( target ); - } - if ( Sender->GetCurrentArea()!=target->GetCurrentArea() || - (PersonalDistance(Sender, target) > wi.range) || - (!Sender->GetCurrentArea()->IsVisible(Sender->Pos, target->Pos))) { - MoveNearerTo(Sender, target, wi.range); - return; - } else if (target->Type == ST_DOOR) { - //Forcing a lock does not launch the trap... - Door* door = (Door*) target; - if(door->Flags & DOOR_LOCKED) { - door->TryBashLock(actor); - } - Sender->ReleaseCurrentAction(); - return; - } else if (target->Type == ST_CONTAINER) { - Container* cont = (Container*) target; - if(cont->Flags & CONT_LOCKED) { - cont->TryBashLock(actor); - } - Sender->ReleaseCurrentAction(); - return; - } - - actor->PerformAttack(core->GetGame()->GameTime); -} - -//we need this because some special characters like _ or * are also accepted -inline bool ismysymbol(const char letter) -{ - if (letter==']') return false; - if (letter=='[') return false; - if (letter==')') return false; - if (letter=='(') return false; - if (letter=='.') return false; - if (letter==',') return false; - return true; -} - -//this function returns a value, symbol could be a numeric string or -//a symbol from idsname -static int GetIdsValue(const char *&symbol, const char *idsname) -{ - int idsfile=core->LoadSymbol(idsname); - Holder valHook = core->GetSymbol(idsfile); - if (!valHook) { - //FIXME:missing ids file!!! - if (InDebug&ID_TRIGGERS) { - printMessage("GameScript", "Missing IDS file %s for symbol %s!\n", LIGHT_RED, - idsname, symbol); - } - return -1; - } - char *newsymbol; - int value=strtol(symbol, &newsymbol, 0); - if (symbol!=newsymbol) { - symbol=newsymbol; - return value; - } - char symbolname[64]; - int x; - for (x=0;ismysymbol(*symbol) && x<(int) sizeof(symbolname)-1;x++) { - symbolname[x]=*symbol; - symbol++; - } - symbolname[x]=0; - return valHook->GetValue(symbolname); -} - -static void ParseIdsTarget(const char *&src, Object *&object) -{ - for (int i=0;iobjectFields[i]=GetIdsValue(src, ObjectIDSTableNames[i]); - if (*src!='.') { - break; - } - src++; - } - src++; //skipping ] -} - -//this will skip to the next element in the prototype of an action/trigger -#define SKIP_ARGUMENT() while (*str && ( *str != ',' ) && ( *str != ')' )) str++ - -static void ParseObject(const char *&str,const char *&src, Object *&object) -{ - SKIP_ARGUMENT(); - object = new Object(); - switch (*src) { - case '"': - //Scriptable Name - src++; - int i; - for (i=0;i<(int) sizeof(object->objectName)-1 && *src && *src!='"';i++) - { - object->objectName[i] = *src; - src++; - } - object->objectName[i] = 0; - src++; - break; - case '[': - src++; //skipping [ - ParseIdsTarget(src, object); - break; - default: //nested object filters - int Nesting=0; - - while (NestingobjectFilters+1, object->objectFilters, (int) sizeof(int) *(MaxObjectNesting-1) ); - object->objectFilters[0]=GetIdsValue(src,"object"); - if (*src!='(') { - break; - } - src++; //skipping ( - if (*src==')') { - break; - } - Nesting++; - } - if (*src=='[') { - ParseIdsTarget(src, object); - } - src+=Nesting; //skipping ) - } -} - -/* this function was lifted from GenerateAction, to make it clearer */ -Action* GenerateActionCore(const char *src, const char *str, unsigned short actionID) -{ - Action *newAction = new Action(true); - newAction->actionID = actionID; - //this flag tells us to merge 2 consecutive strings together to get - //a variable (context+variablename) - int mergestrings = actionflags[newAction->actionID]&AF_MERGESTRINGS; - int objectCount = ( newAction->actionID == 1 ) ? 0 : 1; - int stringsCount = 0; - int intCount = 0; - if (actionflags[newAction->actionID]&AF_DIRECT) { - Object *tmp = new Object(); - tmp->objectFields[0] = -1; - //tmp->objectFields[1] = core->GetGameControl()->targetID; - newAction->objects[objectCount++] = tmp; - } - //Here is the Action; Now we need to evaluate the parameters, if any - if (*str!=')') while (*str) { - if (*(str+1)!=':') { - print("Warning, parser was sidetracked: %s\n",str); - } - switch (*str) { - default: - print("Invalid type: %s\n",str); - //str++; - delete newAction; - return NULL; - break; - - case 'p': //Point - SKIP_ARGUMENT(); - src++; //Skip [ - newAction->pointParameter.x = (short) strtol( src, (char **) &src, 10 ); - src++; //Skip . - newAction->pointParameter.y = (short) strtol( src, (char **) &src, 10 ); - src++; //Skip ] - break; - - case 'i': //Integer - { - //going to the variable name - while (*str != '*' && *str !=',' && *str != ')' ) { - str++; - } - int value; - if (*str=='*') { //there may be an IDS table - str++; - ieVariable idsTabName; - char* tmp = idsTabName; - while (( *str != ',' ) && ( *str != ')' )) { - *tmp = *str; - tmp++; - str++; - } - *tmp = 0; - if (idsTabName[0]) { - value = GetIdsValue(src, idsTabName); - } - else { - value = strtol( src, (char **) &src, 0); - } - } - else { //no IDS table - value = strtol( src, (char **) &src, 0); - } - if (!intCount) { - newAction->int0Parameter = value; - } else if (intCount == 1) { - newAction->int1Parameter = value; - } else { - newAction->int2Parameter = value; - } - intCount++; - } - break; - - case 'a': - //Action - { - SKIP_ARGUMENT(); - char action[257]; - int i = 0; - int openParenthesisCount = 0; - while (true) { - if (*src == ')') { - if (!openParenthesisCount) - break; - openParenthesisCount--; - } else { - if (*src == '(') { - openParenthesisCount++; - } else { - if (( *src == ',' ) && - !openParenthesisCount) - break; - } - } - action[i] = *src; - i++; - src++; - } - action[i] = 0; - Action* act = GenerateAction( action); - if (!act) { - delete newAction; - return NULL; - } - act->objects[0] = newAction->objects[0]; - newAction->objects[0] = NULL; //avoid freeing of object - delete newAction; //freeing action - newAction = act; - } - break; - - case 'o': //Object - if (objectCount==3) { - print("Invalid object count!\n"); - //abort(); - delete newAction; - return NULL; - } - ParseObject(str, src, newAction->objects[objectCount++]); - break; - - case 's': //String - { - SKIP_ARGUMENT(); - src++; - int i; - char* dst; - if (!stringsCount) { - dst = newAction->string0Parameter; - } else { - dst = newAction->string1Parameter; - } - //if there are 3 strings, the first 2 will be merged, - //the last one will be left alone - if (*str==')') { - mergestrings = 0; - } - //skipping the context part, which - //is to be readed later - if (mergestrings) { - for (i=0;i<6;i++) { - *dst++='*'; - } - } - else { - i=0; - } - //breaking on ',' in case of a monkey attack - //fixes bg1:melicamp.dlg, bg1:sharte.dlg - //if strings ever need a , inside, this is a FIXME - while (*src != '"' && *src !=',') { - if (*src == 0) { - delete newAction; - return NULL; - } - //sizeof(context+name) = 40 - if (i<40) { - *dst++ = (char) tolower(*src); - i++; - } - src++; - } - *dst = 0; - //reading the context part - if (mergestrings) { - str++; - if (*str!='s') { - print("Invalid mergestrings:%s\n",str); - //abort(); - delete newAction; - return NULL; - } - SKIP_ARGUMENT(); - if (!stringsCount) { - dst = newAction->string0Parameter; - } else { - dst = newAction->string1Parameter; - } - - //this works only if there are no spaces - if (*src++!='"' || *src++!=',' || *src++!='"') { - break; - } - //reading the context string - i=0; - while (*src != '"') { - if (*src == 0) { - delete newAction; - return NULL; - } - if (i++<6) { - *dst++ = (char) tolower(*src); - } - src++; - } - } - src++; //skipping " - stringsCount++; - } - break; - } - str++; - if (*src == ',' || *src==')') - src++; - } - return newAction; -} - -void GoNear(Scriptable *Sender, const Point &p) -{ - if (Sender->GetCurrentAction()) { - printMessage("GameScript","Target busy???\n",LIGHT_RED); - return; - } - char Tmp[256]; - sprintf( Tmp, "MoveToPoint([%hd.%hd])", p.x, p.y ); - Action * action = GenerateAction( Tmp); - Sender->AddActionInFront( action ); -} - -void MoveNearerTo(Scriptable *Sender, Scriptable *target, int distance) -{ - Point p; - Map *myarea, *hisarea; - - if (Sender->Type != ST_ACTOR) { - printMessage("GameScript","MoveNearerTo only works with actors\n",LIGHT_RED); - Sender->ReleaseCurrentAction(); - return; - } - - myarea = Sender->GetCurrentArea(); - hisarea = target->GetCurrentArea(); - if (hisarea && hisarea!=myarea) { - target = myarea->GetTileMap()->GetTravelTo(hisarea->GetScriptName()); - - if (!target) { - printMessage("GameScript", "MoveNearerTo failed to find an exit\n", YELLOW); - Sender->ReleaseCurrentAction(); - return; - } - ((Actor *) Sender)->UseExit(target->GetGlobalID()); - } else { - ((Actor *) Sender)->UseExit(0); - } - // we deliberately don't try GetLikelyPosition here for now, - // maybe a future idea if we have a better implementation - // (the old code used it - by passing true not 0 below - when target was a movable) - GetPositionFromScriptable(target, p, 0); - - // account for PersonalDistance (which caller uses, but pathfinder doesn't) - if (distance && Sender->Type == ST_ACTOR) { - distance += ((Actor *)Sender)->size*10; - } - if (distance && target->Type == ST_ACTOR) { - distance += ((Actor *)target)->size*10; - } - - MoveNearerTo(Sender, p, distance, 0); -} - -//It is not always good to release the current action if target is unreachable -//we should also raise the trigger TargetUnreachable (if this is an Attack, at least) -//i hacked only this low level function, didn't need the higher ones so far -int MoveNearerTo(Scriptable *Sender, const Point &p, int distance, int dont_release) -{ - if (Sender->Type != ST_ACTOR) { - printMessage("GameScript","MoveNearerTo only works with actors\n",LIGHT_RED); - Sender->ReleaseCurrentAction(); - return 0; - } - - //chasing is unbreakable - //TODO: is this true? - Sender->CurrentActionInterruptable = false; - - Actor *actor = (Actor *)Sender; - - if (!actor->InMove() || actor->Destination != p) { - actor->WalkTo(p, 0, distance); - } - - if (!actor->InMove()) { - //didn't release - if (dont_release) { - return dont_release; - } - // we can't walk any nearer to destination, give up - Sender->ReleaseCurrentAction(); - } - return 0; -} - -void FreeSrc(SrcVector *poi, const ieResRef key) -{ - int res = SrcCache.DecRef((void *) poi, key, true); - if (res<0) { - error("GameScript", "Corrupted Src cache encountered (reference count went below zero), Src name is: %.8s\n", key); - } - if (!res) { - delete poi; - } -} - -SrcVector *LoadSrc(const ieResRef resname) -{ - SrcVector *src = (SrcVector *) SrcCache.GetResource(resname); - if (src) { - return src; - } - DataStream* str = gamedata->GetResource( resname, IE_SRC_CLASS_ID ); - if ( !str) { - return NULL; - } - ieDword size=0; - str->ReadDword(&size); - src = new SrcVector(size); - SrcCache.SetAt( resname, (void *) src ); - while (size--) { - ieDword tmp; - str->ReadDword(&tmp); - src->at(size)=tmp; - str->ReadDword(&tmp); - } - delete ( str ); - return src; -} - -#define MEMCPY(a,b) memcpy((a),(b),sizeof(a) ) - -static Object *ObjectCopy(Object *object) -{ - if (!object) return NULL; - Object *newObject = new Object(); - MEMCPY( newObject->objectFields, object->objectFields ); - MEMCPY( newObject->objectFilters, object->objectFilters ); - MEMCPY( newObject->objectRect, object->objectRect ); - MEMCPY( newObject->objectName, object->objectName ); - return newObject; -} - -Action *ParamCopy(Action *parameters) -{ - Action *newAction = new Action(true); - newAction->actionID = parameters->actionID; - newAction->int0Parameter = parameters->int0Parameter; - newAction->int1Parameter = parameters->int1Parameter; - newAction->int2Parameter = parameters->int2Parameter; - newAction->pointParameter = parameters->pointParameter; - MEMCPY( newAction->string0Parameter, parameters->string0Parameter ); - MEMCPY( newAction->string1Parameter, parameters->string1Parameter ); - for (int c=0;c<3;c++) { - newAction->objects[c]= ObjectCopy( parameters->objects[c] ); - } - return newAction; -} - -Action *ParamCopyNoOverride(Action *parameters) -{ - Action *newAction = new Action(true); - newAction->actionID = parameters->actionID; - newAction->int0Parameter = parameters->int0Parameter; - newAction->int1Parameter = parameters->int1Parameter; - newAction->int2Parameter = parameters->int2Parameter; - newAction->pointParameter = parameters->pointParameter; - MEMCPY( newAction->string0Parameter, parameters->string0Parameter ); - MEMCPY( newAction->string1Parameter, parameters->string1Parameter ); - newAction->objects[0]= NULL; - newAction->objects[1]= ObjectCopy( parameters->objects[1] ); - newAction->objects[2]= ObjectCopy( parameters->objects[2] ); - return newAction; -} - -Trigger *GenerateTriggerCore(const char *src, const char *str, int trIndex, int negate) -{ - Trigger *newTrigger = new Trigger(); - newTrigger->triggerID = (unsigned short) triggersTable->GetValueIndex( trIndex )&0x3fff; - newTrigger->flags = (unsigned short) negate; - int mergestrings = triggerflags[newTrigger->triggerID]&TF_MERGESTRINGS; - int stringsCount = 0; - int intCount = 0; - //Here is the Trigger; Now we need to evaluate the parameters - if (*str!=')') while (*str) { - if (*(str+1)!=':') { - print("Warning, parser was sidetracked: %s\n",str); - } - switch (*str) { - default: - print("Invalid type: %s\n",str); - //str++; - delete newTrigger; - return NULL; - break; - - case 'p': //Point - SKIP_ARGUMENT(); - src++; //Skip [ - newTrigger->pointParameter.x = (short) strtol( src, (char **) &src, 10 ); - src++; //Skip . - newTrigger->pointParameter.y = (short) strtol( src, (char **) &src, 10 ); - src++; //Skip ] - break; - - case 'i': //Integer - { - //going to the variable name - while (*str != '*' && *str !=',' && *str != ')' ) { - str++; - } - int value; - if (*str=='*') { //there may be an IDS table - str++; - ieVariable idsTabName; - char* tmp = idsTabName; - while (( *str != ',' ) && ( *str != ')' )) { - *tmp = *str; - tmp++; - str++; - } - *tmp = 0; - if (idsTabName[0]) { - value = GetIdsValue(src, idsTabName); - } - else { - value = strtol( src, (char **) &src, 0); - } - } - else { //no IDS table - value = strtol( src, (char **) &src, 0); - } - if (!intCount) { - newTrigger->int0Parameter = value; - } else if (intCount == 1) { - newTrigger->int1Parameter = value; - } else { - newTrigger->int2Parameter = value; - } - intCount++; - } - break; - - case 'o': //Object - ParseObject(str, src, newTrigger->objectParameter); - break; - - case 's': //String - { - SKIP_ARGUMENT(); - src++; - int i; - char* dst; - if (!stringsCount) { - dst = newTrigger->string0Parameter; - } else { - dst = newTrigger->string1Parameter; - } - //skipping the context part, which - //is to be readed later - if (mergestrings) { - for (i=0;i<6;i++) { - *dst++='*'; - } - } - else { - i=0; - } - while (*src != '"') { - if (*src == 0) { - delete newTrigger; - return NULL; - } - - //sizeof(context+name) = 40 - if (i<40) { - *dst++ = (char) tolower(*src); - i++; - } - src++; - } - *dst = 0; - //reading the context part - if (mergestrings) { - str++; - if (*str!='s') { - print("Invalid mergestrings:%s\n",str); - //abort(); - delete newTrigger; - return NULL; - } - SKIP_ARGUMENT(); - if (!stringsCount) { - dst = newTrigger->string0Parameter; - } else { - dst = newTrigger->string1Parameter; - } - - //this works only if there are no spaces - if (*src++!='"' || *src++!=',' || *src++!='"') { - break; - } - //reading the context string - i=0; - while (*src != '"') { - if (*src == 0) { - delete newTrigger; - return NULL; - } - - if (i++<6) { - *dst++ = (char) tolower(*src); - } - src++; - } - } - src++; //skipping " - stringsCount++; - } - break; - } - str++; - if (*src == ',' || *src==')') - src++; - } - return newTrigger; -} - -void SetVariable(Scriptable* Sender, const char* VarName, const char* Context, ieDword value) -{ - char newVarName[8+33]; - - if (InDebug&ID_VARIABLES) { - print( "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, NoCreate ); - return; - } - if (strnicmp( newVarName, "LOCALS", 6 ) == 0) { - Sender->locals->SetAt( VarName, value, NoCreate ); - return; - } - Game *game = core->GetGame(); - if (HasKaputz && !strnicmp(newVarName,"KAPUTZ",6) ) { - game->kaputz->SetAt( VarName, value ); - return; - } - - if (strnicmp(newVarName,"GLOBAL",6) ) { - Map *map=game->GetMap(game->FindMap(newVarName)); - if (map) { - map->locals->SetAt( VarName, value, NoCreate); - } - else if (InDebug&ID_VARIABLES) { - printMessage("GameScript", "Invalid variable %s %s in setvariable\n", YELLOW, - Context, VarName); - } - } - else { - game->locals->SetAt( VarName, ( ieDword ) value, NoCreate ); - } -} - -void SetVariable(Scriptable* Sender, const char* VarName, ieDword value) -{ - char newVarName[8]; - const char *poi; - - poi = &VarName[6]; - //some HoW triggers use a : to separate the scope from the variable name - if (*poi==':') { - poi++; - } - - if (InDebug&ID_VARIABLES) { - print( "Setting variable(\"%s\", %d)\n", VarName, value ); - } - strncpy( newVarName, VarName, 6 ); - newVarName[6]=0; - if (strnicmp( newVarName, "MYAREA", 6 ) == 0) { - Sender->GetCurrentArea()->locals->SetAt( poi, value, NoCreate ); - return; - } - if (strnicmp( newVarName, "LOCALS", 6 ) == 0) { - Sender->locals->SetAt( poi, value, NoCreate ); - return; - } - Game *game = core->GetGame(); - 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, NoCreate); - } - else if (InDebug&ID_VARIABLES) { - printMessage("GameScript", "Invalid variable %s in setvariable\n", YELLOW, - VarName); - } - } - else { - game->locals->SetAt( poi, ( ieDword ) value, NoCreate ); - } -} - -ieDword CheckVariable(Scriptable* Sender, const char* VarName, bool *valid) -{ - char newVarName[8]; - const char *poi; - ieDword value = 0; - - strncpy( newVarName, VarName, 6 ); - newVarName[6]=0; - poi = &VarName[6]; - //some HoW triggers use a : to separate the scope from the variable name - if (*poi==':') { - poi++; - } - - if (strnicmp( newVarName, "MYAREA", 6 ) == 0) { - Sender->GetCurrentArea()->locals->Lookup( poi, value ); - if (InDebug&ID_VARIABLES) { - print("CheckVariable %s: %d\n",VarName, value); - } - return value; - } - if (strnicmp( newVarName, "LOCALS", 6 ) == 0) { - Sender->locals->Lookup( poi, value ); - if (InDebug&ID_VARIABLES) { - print("CheckVariable %s: %d\n",VarName, value); - } - return value; - } - Game *game = core->GetGame(); - if (HasKaputz && !strnicmp(newVarName,"KAPUTZ",6) ) { - game->kaputz->Lookup( poi, value ); - if (InDebug&ID_VARIABLES) { - print("CheckVariable %s: %d\n",VarName, value); - } - return value; - } - if (strnicmp(newVarName,"GLOBAL",6) ) { - Map *map=game->GetMap(game->FindMap(newVarName)); - if (map) { - map->locals->Lookup( poi, value); - } else { - if (valid) { - *valid=false; - } - if (InDebug&ID_VARIABLES) { - printMessage("GameScript", "Invalid variable %s in checkvariable\n", YELLOW, - VarName); - } - } - } else { - game->locals->Lookup( poi, value ); - } - if (InDebug&ID_VARIABLES) { - print("CheckVariable %s: %d\n",VarName, value); - } - return value; -} - -ieDword CheckVariable(Scriptable* Sender, const char* VarName, const char* Context, bool *valid) -{ - char newVarName[8]; - ieDword value = 0; - - strncpy(newVarName, Context, 6); - newVarName[6]=0; - if (strnicmp( newVarName, "MYAREA", 6 ) == 0) { - Sender->GetCurrentArea()->locals->Lookup( VarName, value ); - if (InDebug&ID_VARIABLES) { - print("CheckVariable %s%s: %d\n",Context, VarName, value); - } - return value; - } - if (strnicmp( newVarName, "LOCALS", 6 ) == 0) { - Sender->locals->Lookup( VarName, value ); - if (InDebug&ID_VARIABLES) { - print("CheckVariable %s%s: %d\n",Context, VarName, value); - } - return value; - } - Game *game = core->GetGame(); - if (HasKaputz && !strnicmp(newVarName,"KAPUTZ",6) ) { - game->kaputz->Lookup( VarName, value ); - if (InDebug&ID_VARIABLES) { - print("CheckVariable %s%s: %d\n",Context, VarName, value); - } - return value; - } - if (strnicmp(newVarName,"GLOBAL",6) ) { - Map *map=game->GetMap(game->FindMap(newVarName)); - if (map) { - map->locals->Lookup( VarName, value); - } else { - if (valid) { - *valid=false; - } - if (InDebug&ID_VARIABLES) { - printMessage("GameScript", "Invalid variable %s %s in checkvariable\n", YELLOW, - Context, VarName); - } - } - } else { - game->locals->Lookup( VarName, value ); - } - if (InDebug&ID_VARIABLES) { - print("CheckVariable %s%s: %d\n",Context, VarName, value); - } - return value; -} - -int DiffCore(ieDword a, ieDword b, int diffmode) -{ - switch (diffmode) { - case LESS_THAN: - if (ab) { - return 1; - } - break; - case GREATER_OR_EQUALS: - if (a>=b) { - return 1; - } - break; - case NOT_EQUALS: - if (a!=b) { - return 1; - } - break; - case BINARY_LESS_OR_EQUALS: - if ((a&b) == a) { - return 1; - } - break; - case BINARY_MORE: - if ((a&b) != a) { - return 1; - } - break; - case BINARY_MORE_OR_EQUALS: - if ((a&b) == b) { - return 1; - } - break; - case BINARY_LESS: - if ((a&b) != b) { - return 1; - } - break; - case BINARY_INTERSECT: - if (a&b) { - return 1; - } - break; - case BINARY_NOT_INTERSECT: - if (!(a&b)) { - return 1; - } - break; - default: //less or equals - if (a<=b) { - return 1; - } - break; - } - return 0; -} - -int GetGroup(Actor *actor) -{ - int type = 2; //neutral, has no enemies - if (actor->GetStat(IE_EA) <= EA_GOODCUTOFF) { - type = 1; //PC - } - if (actor->GetStat(IE_EA) >= EA_EVILCUTOFF) { - type = 0; - } - return type; -} - -Point GetEntryPoint(const char *areaname, const char *entryname) -{ - Point p; - - AutoTable tab("entries"); - if (!tab) { - return p; - } - const char *tmpstr = tab->QueryField(areaname, entryname); - int x=-1; - int y=-1; - sscanf(tmpstr, "%d.%d", &x, &y); - p.x=(short) x; - p.y=(short) y; - return p; -} - -/* 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 */ -unsigned int GetSpellDistance(const ieResRef spellres, Scriptable *Sender) -{ - unsigned int dist; - - Spell* spl = gamedata->GetSpell( spellres ); - if (!spl) { - printMessage("GameScript", "Spell couldn't be found:%.8s.\n", LIGHT_RED, spellres); - return 0; - } - dist = spl->GetCastingDistance(Sender); - //make possible special return values (like 0xffffffff means the spell doesn't need distance) - //this is used with special targeting mode (3) - if (dist>0xff000000) { - return dist; - } - - gamedata->FreeSpell(spl, spellres, false); - 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 */ -unsigned int GetItemDistance(const ieResRef itemres, int header) -{ - unsigned int dist; - - Item* itm = gamedata->GetItem( itemres ); - if (!itm) { - printMessage("GameScript", "Item couldn't be found:%.8s.\n", LIGHT_RED, itemres); - return 0; - } - dist=itm->GetCastingDistance(header); - //make possible special return values (like 0xffffffff means the item doesn't need distance) - //this is used with special targeting mode (3) - if (dist>0xff000000) { - return dist; - } - - gamedata->FreeItem(itm, itemres, false); - return dist*15; -} - -//read the wish 2da -void SetupWishCore(Scriptable *Sender, int column, int picks) -{ - int count; - ieVariable varname; - int *selects; - int i,j; - - //FIXME: find out what the original really used the picks parameter for - if (picks == 1) picks = 5; - - AutoTable tm("wish"); - if (!tm) { - printStatus( "ERROR", LIGHT_RED ); - print( "Cannot find wish.2da.\n"); - return; - } - - selects = (int *) malloc(picks*sizeof(int)); - count = tm->GetRowCount(); - - for(i=0;i<99;i++) { - snprintf(varname,32, "wishpower%02d", i); - if(CheckVariable(Sender, varname, "GLOBAL") ) { - SetVariable(Sender, varname, "GLOBAL", 0); - } - } - - if (countQueryField( selects[i], column-1 ) ); - snprintf(varname,32,"wishpower%02d", spnum); - SetVariable(Sender, varname, "GLOBAL",1); - } - free(selects); -} - -#define MAX_ISLAND_POLYGONS 10 - -//read a polygon 2da -Gem_Polygon *GetPolygon2DA(ieDword index) -{ - ieResRef resref; - - if (index>=MAX_ISLAND_POLYGONS) { - return NULL; - } - - if (!polygons) { - polygons = (Gem_Polygon **) calloc(MAX_ISLAND_POLYGONS, sizeof(Gem_Polygon *) ); - } - if (polygons[index]) { - return polygons[index]; - } - snprintf(resref, sizeof(ieResRef), "ISLAND%02d", index); - AutoTable tm(resref); - if (!tm) { - return NULL; - } - int cnt = tm->GetRowCount(); - if (!cnt) { - return NULL; - } - Point *p = new Point[cnt]; - - int i = cnt; - while(i--) { - p[i].x = atoi(tm->QueryField(i, 0)); - p[i].y = atoi(tm->QueryField(i, 1)); - } - - polygons[index] = new Gem_Polygon(p, cnt, NULL); - delete [] p; - return polygons[index]; -} - diff --git a/project/jni/application/gemrb/gemrb/core/GameScript/GSUtils.h b/project/jni/application/gemrb/gemrb/core/GameScript/GSUtils.h deleted file mode 100644 index 1bcffd738..000000000 --- a/project/jni/application/gemrb/gemrb/core/GameScript/GSUtils.h +++ /dev/null @@ -1,140 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ -#ifndef GSUTILS_H -#define GSUTILS_H - -#include "GameScript/GameScript.h" - -#include "defsounds.h" -#include "exports.h" -#include "strrefs.h" - -#include "Interface.h" - -//indebug flags -#define ID_REFERENCE 1 -#define ID_CUTSCENE 2 -#define ID_VARIABLES 4 -#define ID_ACTIONS 8 -#define ID_TRIGGERS 16 - -extern Holder triggersTable; -extern Holder actionsTable; -extern Holder overrideActionsTable; -extern Holder objectsTable; -extern TriggerFunction triggers[MAX_TRIGGERS]; -extern ActionFunction actions[MAX_ACTIONS]; -extern short actionflags[MAX_ACTIONS]; -extern short triggerflags[MAX_TRIGGERS]; -extern ObjectFunction objects[MAX_OBJECTS]; -extern IDSFunction idtargets[MAX_OBJECT_FIELDS]; -extern Cache SrcCache; //cache for string resources (pst) -extern Cache BcsCache; //cache for scripts -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; -extern int InDebug; -extern Gem_Polygon **polygons; - -#define MIC_INVALID -2 -#define MIC_FULL -1 -#define MIC_NOITEM 0 -#define MIC_GOTITEM 1 - -GEM_EXPORT int GetReaction(Actor *target, Scriptable *Sender); -int GetHappiness(Scriptable *Sender, int reputation); -int GetHPPercent(Scriptable *Sender); -bool StoreHasItemCore(const ieResRef storename, const ieResRef itemname); -bool HasItemCore(Inventory *inventory, const ieResRef itemname, ieDword flags); -void ClickCore(Scriptable *Sender, Point point, int type, int speed); -void TransformItemCore(Actor *actor, Action *parameters, bool onlyone); -void CreateVisualEffectCore(Actor *target, const char *effect, int iterations); -void CreateVisualEffectCore(Scriptable *Sender, const Point &position, const char *effect, int iterations); -void GetPositionFromScriptable(Scriptable* scr, Point &position, bool trap); -void BeginDialog(Scriptable* Sender, Action* parameters, int flags); -void ChangeAnimationCore(Actor *src, const char *resref, bool effect); -void PolymorphCopyCore(Actor *src, Actor *tar, bool base); -void CreateCreatureCore(Scriptable* Sender, Action* parameters, int flags); -int MoveItemCore(Scriptable *Sender, Scriptable *target, const char *resref, int flags, int setflag); -void MoveToObjectCore(Scriptable *Sender, Action *parameters, ieDword flags, bool untilsee); -bool CreateItemCore(CREItem *item, const char *resref, int a, int b, int c); -void AttackCore(Scriptable *Sender, Scriptable *target, int flags); -void InitScriptTables(); -void HandleBitMod(ieDword &value1, ieDword value2, int opcode); -bool ResolveSpellName(ieResRef spellres, Action *parameter); -GEM_EXPORT void ResolveSpellName(ieResRef spellres, ieDword number); -GEM_EXPORT ieDword ResolveSpellNumber(const ieResRef spellres); -bool ResolveItemName(ieResRef itemres, Actor *act, ieDword Slot); -void EscapeAreaCore(Scriptable *Sender, const Point &p, const char *area, const Point &enter, int flags, int wait); -void GoNear(Scriptable *Sender, const Point &p); -void MoveNearerTo(Scriptable *Sender, Scriptable *target, int distance); -int MoveNearerTo(Scriptable *Sender, const Point &p, int distance, int no_release); - -#define NO_OPERATION -1 -#define LESS_OR_EQUALS 0 -//iwd2 diffmode with gemrb enhancements -#define EQUALS 1 -#define LESS_THAN 2 -#define GREATER_THAN 3 -#define GREATER_OR_EQUALS 4 -#define NOT_EQUALS 5 -#define BINARY_LESS_OR_EQUALS 6 //(left has only bits in right) -#define BINARY_MORE_OR_EQUALS 7 //(left has equal or more bits than right) -#define BINARY_INTERSECT 8 //(left and right has at least one common bit) -#define BINARY_NOT_INTERSECT 9 //(no common bits) -#define BINARY_MORE 10 //left has more bits than right -#define BINARY_LESS 11 //left has less bits than right - -GEM_EXPORT int GetGroup(Actor *actor); - -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); -Point GetEntryPoint(const char *areaname, const char *entryname); -//these are used from other plugins -GEM_EXPORT int CanSee(Scriptable* Sender, Scriptable* target, bool range, int nodead); -GEM_EXPORT int SeeCore(Scriptable* Sender, Trigger* parameters, int justlos); -GEM_EXPORT int DiffCore(ieDword a, ieDword b, int diffmode); -GEM_EXPORT void DisplayStringCore(Scriptable* Sender, int Strref, int flags); -GEM_EXPORT void SetVariable(Scriptable* Sender, const char* VarName, const char* Context, ieDword value); -GEM_EXPORT void MoveBetweenAreasCore(Actor* actor, const char *area, const Point &position, int face, bool adjust); -GEM_EXPORT ieDword CheckVariable(Scriptable* Sender, const char* VarName, bool *valid = NULL); -GEM_EXPORT ieDword CheckVariable(Scriptable* Sender, const char* VarName, const char* Context, bool *valid = NULL); -Action* GenerateActionCore(const char *src, const char *str, unsigned short actionID); -Trigger *GenerateTriggerCore(const char *src, const char *str, int trIndex, int negate); -unsigned int GetSpellDistance(const ieResRef spellres, Scriptable *Sender); -unsigned int GetItemDistance(const ieResRef itemres, int header); -void SetupWishCore(Scriptable *Sender, int column, int picks); -Gem_Polygon *GetPolygon2DA(ieDword index); - -inline int Bones(ieDword value) -{ - return core->Roll((value&0xf000)>>12, (value&0xff0)>>8, value&15); -} - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/GameScript/GameScript.cpp b/project/jni/application/gemrb/gemrb/core/GameScript/GameScript.cpp deleted file mode 100644 index 55ea267fc..000000000 --- a/project/jni/application/gemrb/gemrb/core/GameScript/GameScript.cpp +++ /dev/null @@ -1,2357 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "GameScript/GameScript.h" - -#include "GameScript/GSUtils.h" -#include "GameScript/Matching.h" - -#include "win32def.h" - -#include "Game.h" -#include "GameData.h" -#include "Interface.h" -#include "PluginMgr.h" -#include "TableMgr.h" - -//debug flags -// 1 - cache -// 2 - cutscene ID -// 4 - globals -// 8 - action execution -//16 - trigger evaluation - -//Make this an ordered list, so we could use bsearch! -static const TriggerLink triggernames[] = { - {"actionlistempty", GameScript::ActionListEmpty, 0}, - {"actuallyincombat", GameScript::ActuallyInCombat, 0}, - {"acquired", GameScript::Acquired, 0}, - {"alignment", GameScript::Alignment, 0}, - {"allegiance", GameScript::Allegiance, 0}, - {"animstate", GameScript::AnimState, 0}, - {"anypconmap", GameScript::AnyPCOnMap, 0}, - {"anypcseesenemy", GameScript::AnyPCSeesEnemy, 0}, - {"areacheck", GameScript::AreaCheck, 0}, - {"areacheckobject", GameScript::AreaCheckObject, 0}, - {"areaflag", GameScript::AreaFlag, 0}, - {"arearestdisabled", GameScript::AreaRestDisabled, 0}, - {"areatype", GameScript::AreaType, 0}, - {"atlocation", GameScript::AtLocation, 0}, - {"assaltedby", GameScript::AttackedBy, 0},//pst - {"attackedby", GameScript::AttackedBy, 0}, - {"becamevisible", GameScript::BecameVisible, 0}, - {"bitcheck", GameScript::BitCheck,TF_MERGESTRINGS}, - {"bitcheckexact", GameScript::BitCheckExact,TF_MERGESTRINGS}, - {"bitglobal", GameScript::BitGlobal_Trigger,TF_MERGESTRINGS}, - {"breakingpoint", GameScript::BreakingPoint, 0}, - {"calanderday", GameScript::CalendarDay, 0}, //illiterate developers O_o - {"calendarday", GameScript::CalendarDay, 0}, - {"calanderdaygt", GameScript::CalendarDayGT, 0}, - {"calendardaygt", GameScript::CalendarDayGT, 0}, - {"calanderdaylt", GameScript::CalendarDayLT, 0}, - {"calendardaylt", GameScript::CalendarDayLT, 0}, - {"calledbyname", GameScript::CalledByName, 0}, //this is still a question - {"chargecount", GameScript::ChargeCount, 0}, - {"charname", GameScript::CharName, 0}, //not scripting name - {"checkareadifflevel", GameScript::DifficultyLT, 0},//iwd2 guess - {"checkdoorflags", GameScript::CheckDoorFlags, 0}, - {"checkpartyaveragelevel", GameScript::CheckPartyAverageLevel, 0}, - {"checkpartylevel", GameScript::CheckPartyLevel, 0}, - {"checkskill", GameScript::CheckSkill, 0}, - {"checkskillgt", GameScript::CheckSkillGT, 0}, - {"checkskilllt", GameScript::CheckSkillLT, 0}, - {"checkspellstate", GameScript::CheckSpellState, 0}, - {"checkstat", GameScript::CheckStat, 0}, - {"checkstatgt", GameScript::CheckStatGT, 0}, - {"checkstatlt", GameScript::CheckStatLT, 0}, - {"class", GameScript::Class, 0}, - {"classex", GameScript::ClassEx, 0}, //will return true for multis - {"classlevel", GameScript::ClassLevel, 0}, //pst - {"classlevelgt", GameScript::ClassLevelGT, 0}, - {"classlevellt", GameScript::ClassLevelLT, 0}, - {"clicked", GameScript::Clicked, 0}, - {"closed", GameScript::Closed, 0}, - {"combatcounter", GameScript::CombatCounter, 0}, - {"combatcountergt", GameScript::CombatCounterGT, 0}, - {"combatcounterlt", GameScript::CombatCounterLT, 0}, - {"contains", GameScript::Contains, 0}, - {"currentareais", GameScript::CurrentAreaIs, 0},//checks object - {"creaturehidden", GameScript::CreatureHidden, 0},//this is the engine level hiding feature, not the skill - {"creatureinarea", GameScript::AreaCheck, 0}, //pst, checks this object - {"damagetaken", GameScript::HPLost, 0}, - {"damagetakengt", GameScript::HPLostGT, 0}, - {"damagetakenlt", GameScript::HPLostLT, 0}, - {"dead", GameScript::Dead, 0}, - {"delay", GameScript::Delay, 0}, - {"detect", GameScript::Detect, 0}, //so far i see no difference - {"die", GameScript::Die, 0}, - {"died", GameScript::Died, 0}, - {"difficulty", GameScript::Difficulty, 0}, - {"difficultygt", GameScript::DifficultyGT, 0}, - {"difficultylt", GameScript::DifficultyLT, 0}, - {"disarmed", GameScript::Disarmed, 0}, - {"disarmfailed", GameScript::DisarmFailed, 0}, - {"entered", GameScript::Entered, 0}, - {"entirepartyonmap", GameScript::EntirePartyOnMap, 0}, - {"exists", GameScript::Exists, 0}, - {"extendedstatecheck", GameScript::ExtendedStateCheck, 0}, - {"extraproficiency", GameScript::ExtraProficiency, 0}, - {"extraproficiencygt", GameScript::ExtraProficiencyGT, 0}, - {"extraproficiencylt", GameScript::ExtraProficiencyLT, 0}, - {"faction", GameScript::Faction, 0}, - {"failedtoopen", GameScript::OpenFailed, 0}, - {"fallenpaladin", GameScript::FallenPaladin, 0}, - {"fallenranger", GameScript::FallenRanger, 0}, - {"false", GameScript::False, 0}, - {"forcemarkedspell", GameScript::ForceMarkedSpell_Trigger, 0}, - {"frame", GameScript::Frame, 0}, - {"g", GameScript::G_Trigger, 0}, - {"gender", GameScript::Gender, 0}, - {"general", GameScript::General, 0}, - {"ggt", GameScript::GGT_Trigger, 0}, - {"glt", GameScript::GLT_Trigger, 0}, - {"global", GameScript::Global,TF_MERGESTRINGS}, - {"globalandglobal", GameScript::GlobalAndGlobal_Trigger,TF_MERGESTRINGS}, - {"globalband", GameScript::BitCheck,TF_MERGESTRINGS}, - {"globalbandglobal", GameScript::GlobalBAndGlobal_Trigger,TF_MERGESTRINGS}, - {"globalbandglobalexact", GameScript::GlobalBAndGlobalExact,TF_MERGESTRINGS}, - {"globalbitglobal", GameScript::GlobalBitGlobal_Trigger,TF_MERGESTRINGS}, - {"globalequalsglobal", GameScript::GlobalsEqual,TF_MERGESTRINGS}, //this is the same - {"globalgt", GameScript::GlobalGT,TF_MERGESTRINGS}, - {"globalgtglobal", GameScript::GlobalGTGlobal,TF_MERGESTRINGS}, - {"globallt", GameScript::GlobalLT,TF_MERGESTRINGS}, - {"globalltglobal", GameScript::GlobalLTGlobal,TF_MERGESTRINGS}, - {"globalorglobal", GameScript::GlobalOrGlobal_Trigger,TF_MERGESTRINGS}, - {"globalsequal", GameScript::GlobalsEqual, 0}, - {"globalsgt", GameScript::GlobalsGT, 0}, - {"globalslt", GameScript::GlobalsLT, 0}, - {"globaltimerexact", GameScript::GlobalTimerExact, 0}, - {"globaltimerexpired", GameScript::GlobalTimerExpired, 0}, - {"globaltimernotexpired", GameScript::GlobalTimerNotExpired, 0}, - {"globaltimerstarted", GameScript::GlobalTimerStarted, 0}, - {"happiness", GameScript::Happiness, 0}, - {"happinessgt", GameScript::HappinessGT, 0}, - {"happinesslt", GameScript::HappinessLT, 0}, - {"harmlessclosed", GameScript::Closed, 0}, //pst, not sure - {"harmlessentered", GameScript::HarmlessEntered, 0}, //??? - {"harmlessopened", GameScript::Opened, 0}, //pst, not sure - {"hasbounceeffects", GameScript::HasBounceEffects, 0}, - {"hasimmunityeffects", GameScript::HasImmunityEffects, 0}, - {"hasinnateability", GameScript::HaveSpell, 0}, //these must be the same - {"hasitem", GameScript::HasItem, 0}, - {"hasitemequiped", GameScript::HasItemEquipped, 0}, //typo in bg2 - {"hasitemequipedreal", GameScript::HasItemEquipped, 0}, //not sure - {"hasitemequipped", GameScript::HasItemEquipped, 0}, - {"hasitemequippedreal", GameScript::HasItemEquipped, 0}, //not sure - {"hasiteminslot", GameScript::HasItemSlot, 0}, - {"hasitemslot", GameScript::HasItemSlot, 0}, - {"hasitemtypeslot", GameScript::HasItemTypeSlot, 0},//gemrb extension - {"hasweaponequiped", GameScript::HasWeaponEquipped, 0},//a typo again - {"hasweaponequipped", GameScript::HasWeaponEquipped, 0}, - {"haveanyspells", GameScript::HaveAnySpells, 0}, - {"havespell", GameScript::HaveSpell, 0}, //these must be the same - {"havespellparty", GameScript::HaveSpellParty, 0}, - {"havespellres", GameScript::HaveSpell, 0}, //they share the same ID - {"haveusableweaponequipped", GameScript::HaveUsableWeaponEquipped, 0}, - {"heard", GameScript::Heard, 0}, - {"help", GameScript::Help_Trigger, 0}, - {"helpex", GameScript::HelpEX, 0}, - {"hitby", GameScript::HitBy, 0}, - {"hotkey", GameScript::HotKey, 0}, - {"hp", GameScript::HP, 0}, - {"hpgt", GameScript::HPGT, 0}, - {"hplost", GameScript::HPLost, 0}, - {"hplostgt", GameScript::HPLostGT, 0}, - {"hplostlt", GameScript::HPLostLT, 0}, - {"hplt", GameScript::HPLT, 0}, - {"hppercent", GameScript::HPPercent, 0}, - {"hppercentgt", GameScript::HPPercentGT, 0}, - {"hppercentlt", GameScript::HPPercentLT, 0}, - {"inactivearea", GameScript::InActiveArea, 0}, - {"incutscenemode", GameScript::InCutSceneMode, 0}, - {"inline", GameScript::InLine, 0}, - {"inmyarea", GameScript::InMyArea, 0}, - {"inmygroup", GameScript::InMyGroup, 0}, - {"inparty", GameScript::InParty, 0}, - {"inpartyallowdead", GameScript::InPartyAllowDead, 0}, - {"inpartyslot", GameScript::InPartySlot, 0}, - {"internal", GameScript::Internal, 0}, - {"internalgt", GameScript::InternalGT, 0}, - {"internallt", GameScript::InternalLT, 0}, - {"interactingwith", GameScript::InteractingWith, 0}, - {"intrap", GameScript::InTrap, 0}, - {"inventoryfull", GameScript::InventoryFull, 0}, - {"inview", GameScript::LOS, 0}, //it seems the same, needs research - {"inwatcherskeep", GameScript::AreaStartsWith, 0}, - {"inweaponrange", GameScript::InWeaponRange, 0}, - {"isaclown", GameScript::IsAClown, 0}, - {"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}, - {"isheartoffurymodeon", GameScript::NightmareModeOn, 0}, - {"islocked", GameScript::IsLocked, 0}, - {"isextendednight", GameScript::IsExtendedNight, 0}, - {"ismarkedspell", GameScript::IsMarkedSpell, 0}, - {"isoverme", GameScript::IsOverMe, 0}, - {"ispathcriticalobject", GameScript::IsPathCriticalObject, 0}, - {"isplayernumber", GameScript::IsPlayerNumber, 0}, - {"isrotation", GameScript::IsRotation, 0}, - {"isscriptname", GameScript::CalledByName, 0}, //seems the same - {"isspelltargetvalid", GameScript::IsSpellTargetValid, 0}, - {"isteambiton", GameScript::IsTeamBitOn, 0}, - {"isvalidforpartydialog", GameScript::IsValidForPartyDialog, 0}, - {"isvalidforpartydialogue", GameScript::IsValidForPartyDialog, 0}, - {"isweaponranged", GameScript::IsWeaponRanged, 0}, - {"isweather", GameScript::IsWeather, 0}, //gemrb extension - {"itemisidentified", GameScript::ItemIsIdentified, 0}, - {"joins", GameScript::Joins, 0}, - {"killed", GameScript::Killed, 0}, - {"kit", GameScript::Kit, 0}, - {"knowspell", GameScript::KnowSpell, 0}, //gemrb specific - {"lastmarkedobject", GameScript::LastMarkedObject_Trigger, 0}, - {"lastpersontalkedto", GameScript::LastPersonTalkedTo, 0}, //pst - {"leaves", GameScript::Leaves, 0}, - {"level", GameScript::Level, 0}, - {"levelgt", GameScript::LevelGT, 0}, - {"levelinclass", GameScript::LevelInClass, 0}, //iwd2 - {"levelinclassgt", GameScript::LevelInClassGT, 0}, - {"levelinclasslt", GameScript::LevelInClassLT, 0}, - {"levellt", GameScript::LevelLT, 0}, - {"levelparty", GameScript::LevelParty, 0}, - {"levelpartygt", GameScript::LevelPartyGT, 0}, - {"levelpartylt", GameScript::LevelPartyLT, 0}, - {"localsequal", GameScript::LocalsEqual, 0}, - {"localsgt", GameScript::LocalsGT, 0}, - {"localslt", GameScript::LocalsLT, 0}, - {"los", GameScript::LOS, 0}, - {"modalstate", GameScript::ModalState, 0}, - {"morale", GameScript::Morale, 0}, - {"moralegt", GameScript::MoraleGT, 0}, - {"moralelt", GameScript::MoraleLT, 0}, - {"name", GameScript::CalledByName, 0}, //this is the same too? - {"namelessbitthedust", GameScript::NamelessBitTheDust, 0}, - {"nearbydialog", GameScript::NearbyDialog, 0}, - {"nearbydialogue", GameScript::NearbyDialog, 0}, - {"nearlocation", GameScript::NearLocation, 0}, - {"nearsavedlocation", GameScript::NearSavedLocation, 0}, - {"nightmaremodeon", GameScript::NightmareModeOn, 0}, - {"notstatecheck", GameScript::NotStateCheck, 0}, - {"nulldialog", GameScript::NullDialog, 0}, - {"nulldialogue", GameScript::NullDialog, 0}, - {"numcreature", GameScript::NumCreatures, 0}, - {"numcreaturegt", GameScript::NumCreaturesGT, 0}, - {"numcreaturelt", GameScript::NumCreaturesLT, 0}, - {"numcreaturesatmylevel", GameScript::NumCreaturesAtMyLevel, 0}, - {"numcreaturesgtmylevel", GameScript::NumCreaturesGTMyLevel, 0}, - {"numcreaturesltmylevel", GameScript::NumCreaturesLTMyLevel, 0}, - {"numcreaturevsparty", GameScript::NumCreatureVsParty, 0}, - {"numcreaturevspartygt", GameScript::NumCreatureVsPartyGT, 0}, - {"numcreaturevspartylt", GameScript::NumCreatureVsPartyLT, 0}, - {"numdead", GameScript::NumDead, 0}, - {"numdeadgt", GameScript::NumDeadGT, 0}, - {"numdeadlt", GameScript::NumDeadLT, 0}, - {"numinparty", GameScript::PartyCountEQ, 0}, - {"numinpartyalive", GameScript::PartyCountAliveEQ, 0}, - {"numinpartyalivegt", GameScript::PartyCountAliveGT, 0}, - {"numinpartyalivelt", GameScript::PartyCountAliveLT, 0}, - {"numinpartygt", GameScript::PartyCountGT, 0}, - {"numinpartylt", GameScript::PartyCountLT, 0}, - {"numitems", GameScript::NumItems, 0}, - {"numitemsgt", GameScript::NumItemsGT, 0}, - {"numitemslt", GameScript::NumItemsLT, 0}, - {"numitemsparty", GameScript::NumItemsParty, 0}, - {"numitemspartygt", GameScript::NumItemsPartyGT, 0}, - {"numitemspartylt", GameScript::NumItemsPartyLT, 0}, - {"numtimesinteracted", GameScript::NumTimesInteracted, 0}, - {"numtimesinteractedgt", GameScript::NumTimesInteractedGT, 0}, - {"numtimesinteractedlt", GameScript::NumTimesInteractedLT, 0}, - {"numtimesinteractedobject", GameScript::NumTimesInteractedObject, 0},//gemrb - {"numtimesinteractedobjectgt", GameScript::NumTimesInteractedObjectGT, 0},//gemrb - {"numtimesinteractedobjectlt", GameScript::NumTimesInteractedObjectLT, 0},//gemrb - {"numtimestalkedto", GameScript::NumTimesTalkedTo, 0}, - {"numtimestalkedtogt", GameScript::NumTimesTalkedToGT, 0}, - {"numtimestalkedtolt", GameScript::NumTimesTalkedToLT, 0}, - {"objectactionlistempty", GameScript::ObjectActionListEmpty, 0}, //same function - {"objitemcounteq", GameScript::NumItems, 0}, - {"objitemcountgt", GameScript::NumItemsGT, 0}, - {"objitemcountlt", GameScript::NumItemsLT, 0}, - {"oncreation", GameScript::OnCreation, 0}, - {"onisland", GameScript::OnIsland, 0}, - {"onscreen", GameScript::OnScreen, 0}, - {"opened", GameScript::Opened, 0}, - {"openfailed", GameScript::OpenFailed, 0}, - {"openstate", GameScript::OpenState, 0}, - {"or", GameScript::Or, 0}, - {"outofammo", GameScript::OutOfAmmo, 0}, - {"ownsfloatermessage", GameScript::OwnsFloaterMessage, 0}, - {"partycounteq", GameScript::PartyCountEQ, 0}, - {"partycountgt", GameScript::PartyCountGT, 0}, - {"partycountlt", GameScript::PartyCountLT, 0}, - {"partygold", GameScript::PartyGold, 0}, - {"partygoldgt", GameScript::PartyGoldGT, 0}, - {"partygoldlt", GameScript::PartyGoldLT, 0}, - {"partyhasitem", GameScript::PartyHasItem, 0}, - {"partyhasitemidentified", GameScript::PartyHasItemIdentified, 0}, - {"partyitemcounteq", GameScript::NumItemsParty, 0}, - {"partyitemcountgt", GameScript::NumItemsPartyGT, 0}, - {"partyitemcountlt", GameScript::NumItemsPartyLT, 0}, - {"partymemberdied", GameScript::PartyMemberDied, 0}, - {"partyrested", GameScript::PartyRested, 0}, - {"pccanseepoint", GameScript::PCCanSeePoint, 0}, - {"pcinstore", GameScript::PCInStore, 0}, - {"personalspacedistance", GameScript::PersonalSpaceDistance, 0}, - {"picklockfailed", GameScript::PickLockFailed, 0}, - {"pickpocketfailed", GameScript::PickpocketFailed, 0}, - {"proficiency", GameScript::Proficiency, 0}, - {"proficiencygt", GameScript::ProficiencyGT, 0}, - {"proficiencylt", GameScript::ProficiencyLT, 0}, - {"race", GameScript::Race, 0}, - {"randomnum", GameScript::RandomNum, 0}, - {"randomnumgt", GameScript::RandomNumGT, 0}, - {"randomnumlt", GameScript::RandomNumLT, 0}, - {"randomstatcheck", GameScript::RandomStatCheck, 0}, - {"range", GameScript::Range, 0}, - {"reaction", GameScript::Reaction, 0}, - {"reactiongt", GameScript::ReactionGT, 0}, - {"reactionlt", GameScript::ReactionLT, 0}, - {"realglobaltimerexact", GameScript::RealGlobalTimerExact, 0}, - {"realglobaltimerexpired", GameScript::RealGlobalTimerExpired, 0}, - {"realglobaltimernotexpired", GameScript::RealGlobalTimerNotExpired, 0}, - {"receivedorder", GameScript::ReceivedOrder, 0}, - {"reputation", GameScript::Reputation, 0}, - {"reputationgt", GameScript::ReputationGT, 0}, - {"reputationlt", GameScript::ReputationLT, 0}, - {"school", GameScript::School, 0}, //similar to kit - {"see", GameScript::See, 0}, - {"sequence", GameScript::Sequence, 0}, - {"setlastmarkedobject", GameScript::SetLastMarkedObject, 0}, - {"setmarkedspell", GameScript::SetMarkedSpell_Trigger, 0}, - {"specifics", GameScript::Specifics, 0}, - {"spellcast", GameScript::SpellCast, 0}, - {"spellcastinnate", GameScript::SpellCastInnate, 0}, - {"spellcastonme", GameScript::SpellCastOnMe, 0}, - {"spellcastpriest", GameScript::SpellCastPriest, 0}, - {"statecheck", GameScript::StateCheck, 0}, - {"stealfailed", GameScript::StealFailed, 0}, - {"storehasitem", GameScript::StoreHasItem, 0}, - {"stuffglobalrandom", GameScript::StuffGlobalRandom, 0},//hm, this is a trigger - {"subrace", GameScript::SubRace, 0}, - {"systemvariable", GameScript::SystemVariable_Trigger, 0}, //gemrb - {"targetunreachable", GameScript::TargetUnreachable, 0}, - {"team", GameScript::Team, 0}, - {"time", GameScript::Time, 0}, - {"timegt", GameScript::TimeGT, 0}, - {"timelt", GameScript::TimeLT, 0}, - {"timeofday", GameScript::TimeOfDay, 0}, - {"timeractive", GameScript::TimerActive, 0}, - {"timerexpired", GameScript::TimerExpired, 0}, - {"tookdamage", GameScript::TookDamage, 0}, - {"totalitemcnt", GameScript::TotalItemCnt, 0}, //iwd2 - {"totalitemcntexclude", GameScript::TotalItemCntExclude, 0}, //iwd2 - {"totalitemcntexcludegt", GameScript::TotalItemCntExcludeGT, 0}, //iwd2 - {"totalitemcntexcludelt", GameScript::TotalItemCntExcludeLT, 0}, //iwd2 - {"totalitemcntgt", GameScript::TotalItemCntGT, 0}, //iwd2 - {"totalitemcntlt", GameScript::TotalItemCntLT, 0}, //iwd2 - {"traptriggered", GameScript::TrapTriggered, 0}, - {"trigger", GameScript::TriggerTrigger, 0}, - {"triggerclick", GameScript::Clicked, 0}, //not sure - {"triggersetglobal", GameScript::TriggerSetGlobal,0}, //iwd2, but never used - {"true", GameScript::True, 0}, - {"turnedby", GameScript::TurnedBy, 0}, - {"unlocked", GameScript::Unlocked, 0}, - {"unselectablevariable", GameScript::UnselectableVariable, 0}, - {"unselectablevariablegt", GameScript::UnselectableVariableGT, 0}, - {"unselectablevariablelt", GameScript::UnselectableVariableLT, 0}, - {"unusable",GameScript::Unusable, 0}, - {"vacant",GameScript::Vacant, 0}, - {"walkedtotrigger", GameScript::WalkedToTrigger, 0}, - {"wasindialog", GameScript::WasInDialog, 0}, - {"xor", GameScript::Xor,TF_MERGESTRINGS}, - {"xp", GameScript::XP, 0}, - {"xpgt", GameScript::XPGT, 0}, - {"xplt", GameScript::XPLT, 0}, - { NULL,NULL,0} -}; - -//Make this an ordered list, so we could use bsearch! -static const ActionLink actionnames[] = { - {"actionoverride",NULL, AF_INVALID}, //will this function ever be reached - {"activate", GameScript::Activate, 0}, - {"activateportalcursor", GameScript::ActivatePortalCursor, 0}, - {"addareaflag", GameScript::AddAreaFlag, 0}, - {"addareatype", GameScript::AddAreaType, 0}, - {"addexperienceparty", GameScript::AddExperienceParty, 0}, - {"addexperiencepartycr", GameScript::AddExperiencePartyCR, 0}, - {"addexperiencepartyglobal", GameScript::AddExperiencePartyGlobal, 0}, - {"addfeat", GameScript::AddFeat, 0}, - {"addglobals", GameScript::AddGlobals, 0}, - {"addhp", GameScript::AddHP, 0}, - {"addjournalentry", GameScript::AddJournalEntry, 0}, - {"addkit", GameScript::AddKit, 0}, - {"addmapnote", GameScript::AddMapnote, 0}, - {"addpartyexperience", GameScript::AddExperienceParty, 0}, - {"addspecialability", GameScript::AddSpecialAbility, 0}, - {"addsuperkit", GameScript::AddSuperKit, 0}, - {"addwaypoint", GameScript::AddWayPoint,AF_BLOCKING}, - {"addxp2da", GameScript::AddXP2DA, 0}, - {"addxpobject", GameScript::AddXPObject, 0}, - {"addxpvar", GameScript::AddXP2DA, 0}, - {"advancetime", GameScript::AdvanceTime, 0}, - {"allowarearesting", GameScript::SetAreaRestFlag, 0},//iwd2 - {"ally", GameScript::Ally, 0}, - {"ambientactivate", GameScript::AmbientActivate, 0}, - {"ankhegemerge", GameScript::AnkhegEmerge, AF_ALIVE}, - {"ankheghide", GameScript::AnkhegHide, AF_ALIVE}, - {"applydamage", GameScript::ApplyDamage, 0}, - {"applydamagepercent", GameScript::ApplyDamagePercent, 0}, - {"applyspell", GameScript::ApplySpell, 0}, - {"applyspellpoint", GameScript::ApplySpellPoint, 0}, //gemrb extension - {"attachtransitiontodoor", GameScript::AttachTransitionToDoor, 0}, - {"attack", GameScript::Attack,AF_BLOCKING|AF_ALIVE}, - {"attacknosound", GameScript::AttackNoSound,AF_BLOCKING|AF_ALIVE}, //no sound yet anyway - {"attackoneround", GameScript::AttackOneRound,AF_BLOCKING|AF_ALIVE}, - {"attackreevaluate", GameScript::AttackReevaluate,AF_BLOCKING|AF_ALIVE}, - {"backstab", GameScript::Attack,AF_BLOCKING|AF_ALIVE},//actually hide+attack - {"banterblockflag", GameScript::BanterBlockFlag,0}, - {"banterblocktime", GameScript::BanterBlockTime,0}, - {"bashdoor", GameScript::BashDoor,AF_BLOCKING|AF_ALIVE}, //the same until we know better - {"battlesong", GameScript::BattleSong, AF_ALIVE}, - {"berserk", GameScript::Berserk, AF_ALIVE}, - {"bitclear", GameScript::BitClear,AF_MERGESTRINGS}, - {"bitglobal", GameScript::BitGlobal,AF_MERGESTRINGS}, - {"bitset", GameScript::GlobalBOr,AF_MERGESTRINGS}, //probably the same - {"breakinstants", GameScript::BreakInstants, AF_BLOCKING},//delay execution of instants to the next AI cycle??? - {"calllightning", GameScript::Kill, 0}, //TODO: call lightning projectile - {"calm", GameScript::Calm, 0}, - {"changeaiscript", GameScript::ChangeAIScript, 0}, - {"changeaitype", GameScript::ChangeAIType, 0}, - {"changealignment", GameScript::ChangeAlignment, 0}, - {"changeallegiance", GameScript::ChangeAllegiance, 0}, - {"changeanimation", GameScript::ChangeAnimation, 0}, - {"changeanimationnoeffect", GameScript::ChangeAnimationNoEffect, 0}, - {"changeclass", GameScript::ChangeClass, 0}, - {"changecolor", GameScript::ChangeColor, 0}, - {"changecurrentscript", GameScript::ChangeAIScript,AF_SCRIPTLEVEL}, - {"changedestination", GameScript::ChangeDestination,0}, //gemrb extension (iwd hack) - {"changedialog", GameScript::ChangeDialogue, 0}, - {"changedialogue", GameScript::ChangeDialogue, 0}, - {"changegender", GameScript::ChangeGender, 0}, - {"changegeneral", GameScript::ChangeGeneral, 0}, - {"changeenemyally", GameScript::ChangeAllegiance, 0}, //this is the same - {"changefaction", GameScript::SetFaction, 0}, //pst - {"changerace", GameScript::ChangeRace, 0}, - {"changespecifics", GameScript::ChangeSpecifics, 0}, - {"changestat", GameScript::ChangeStat, 0}, - {"changestatglobal", GameScript::ChangeStatGlobal, 0}, - {"changestoremarkup", GameScript::ChangeStoreMarkup, 0},//iwd2 - {"changeteam", GameScript::SetTeam, 0}, //pst - {"changetilestate", GameScript::ChangeTileState, 0}, //bg2 - {"chunkcreature", GameScript::Kill, 0}, //should be more graphical - {"clearactions", GameScript::ClearActions, 0}, - {"clearallactions", GameScript::ClearAllActions, 0}, - {"clearpartyeffects", GameScript::ClearPartyEffects, 0}, - {"clearspriteeffects", GameScript::ClearSpriteEffects, 0}, - {"clicklbuttonobject", GameScript::ClickLButtonObject, AF_BLOCKING}, - {"clicklbuttonpoint", GameScript::ClickLButtonPoint, AF_BLOCKING}, - {"clickrbuttonobject", GameScript::ClickLButtonObject, AF_BLOCKING}, - {"clickrbuttonpoint", GameScript::ClickLButtonPoint, AF_BLOCKING}, - {"closedoor", GameScript::CloseDoor,0}, - {"containerenable", GameScript::ContainerEnable, 0}, - {"continue", GameScript::Continue,AF_IMMEDIATE | AF_CONTINUE}, - {"copygroundpilesto", GameScript::CopyGroundPilesTo, 0}, - {"createcreature", GameScript::CreateCreature, 0}, //point is relative to Sender - {"createcreaturecopypoint", GameScript::CreateCreatureCopyPoint, 0}, //point is relative to Sender - {"createcreaturedoor", GameScript::CreateCreatureDoor, 0}, - {"createcreatureatfeet", GameScript::CreateCreatureAtFeet, 0}, - {"createcreatureatlocation", GameScript::CreateCreatureAtLocation, 0}, - {"createcreatureimpassable", GameScript::CreateCreatureImpassable, 0}, - {"createcreatureimpassableallowoverlap", GameScript::CreateCreatureImpassableAllowOverlap, 0}, - {"createcreatureobject", GameScript::CreateCreatureObjectOffset, 0}, //the same - {"createcreatureobjectcopy", GameScript::CreateCreatureObjectCopy, 0}, - {"createcreatureobjectcopyeffect", GameScript::CreateCreatureObjectCopy, 0}, //the same - {"createcreatureobjectdoor", GameScript::CreateCreatureObjectDoor, 0},//same as createcreatureobject, but with dimension door animation - {"createcreatureobjectoffscreen", GameScript::CreateCreatureObjectOffScreen, 0}, //same as createcreature object, but starts looking for a place far away from the player - {"createcreatureobjectoffset", GameScript::CreateCreatureObjectOffset, 0}, //the same - {"createcreatureoffscreen", GameScript::CreateCreatureOffScreen, 0}, - {"createitem", GameScript::CreateItem, 0}, - {"createitemglobal", GameScript::CreateItemNumGlobal, 0}, - {"createitemnumglobal", GameScript::CreateItemNumGlobal, 0}, - {"createpartygold", GameScript::CreatePartyGold, 0}, - {"createvisualeffect", GameScript::CreateVisualEffect, 0}, - {"createvisualeffectobject", GameScript::CreateVisualEffectObject, 0}, - {"createvisualeffectobjectSticky", GameScript::CreateVisualEffectObjectSticky, 0}, - {"cutsceneid", GameScript::CutSceneID,0}, - {"damage", GameScript::Damage, 0}, - {"daynight", GameScript::DayNight, 0}, - {"deactivate", GameScript::Deactivate, 0}, - {"debug", GameScript::Debug, 0}, - {"debugoutput", GameScript::Debug, 0}, - {"deletejournalentry", GameScript::RemoveJournalEntry, 0}, - {"demoend", GameScript::DemoEnd, 0}, //same for now - {"destroyalldestructableequipment", GameScript::DestroyAllDestructableEquipment, 0}, - {"destroyallequipment", GameScript::DestroyAllEquipment, 0}, - {"destroygold", GameScript::DestroyGold, 0}, - {"destroyitem", GameScript::DestroyItem, 0}, - {"destroypartygold", GameScript::DestroyPartyGold, 0}, - {"destroypartyitem", GameScript::DestroyPartyItem, 0}, - {"destroyself", GameScript::DestroySelf, 0}, - {"detectsecretdoor", GameScript::DetectSecretDoor, 0}, - {"dialog", GameScript::Dialogue,AF_BLOCKING}, - {"dialogforceinterrupt", GameScript::DialogueForceInterrupt,AF_BLOCKING}, - {"dialoginterrupt", GameScript::DialogueInterrupt,0}, - {"dialogue", GameScript::Dialogue,AF_BLOCKING}, - {"dialogueforceinterrupt", GameScript::DialogueForceInterrupt,AF_BLOCKING}, - {"dialogueinterrupt", GameScript::DialogueInterrupt,0}, - {"disablefogdither", GameScript::DisableFogDither, 0}, - {"disablespritedither", GameScript::DisableSpriteDither, 0}, - {"displaymessage", GameScript::DisplayMessage, 0}, - {"displaystring", GameScript::DisplayString, 0}, - {"displaystringhead", GameScript::DisplayStringHead, 0}, - {"displaystringheadowner", GameScript::DisplayStringHeadOwner, 0}, - {"displaystringheaddead", GameScript::DisplayStringHead, 0}, //same? - {"displaystringnoname", GameScript::DisplayStringNoName, 0}, - {"displaystringnonamehead", GameScript::DisplayStringNoNameHead, 0}, - {"displaystringwait", GameScript::DisplayStringWait,AF_BLOCKING}, - {"doubleclicklbuttonobject", GameScript::DoubleClickLButtonObject, AF_BLOCKING}, - {"doubleclicklbuttonpoint", GameScript::DoubleClickLButtonPoint, AF_BLOCKING}, - {"doubleclickrbuttonobject", GameScript::DoubleClickLButtonObject, AF_BLOCKING}, - {"doubleclickrbuttonpoint", GameScript::DoubleClickLButtonPoint, AF_BLOCKING}, - {"dropinventory", GameScript::DropInventory, 0}, - {"dropinventoryex", GameScript::DropInventoryEX, 0}, - {"dropinventoryexexclude", GameScript::DropInventoryEX, 0}, //same - {"dropitem", GameScript::DropItem, AF_BLOCKING}, - {"enablefogdither", GameScript::EnableFogDither, 0}, - {"enableportaltravel", GameScript::EnablePortalTravel, 0}, - {"enablespritedither", GameScript::EnableSpriteDither, 0}, - {"endcredits", GameScript::EndCredits, 0},//movie - {"endcutscenemode", GameScript::EndCutSceneMode, 0}, - {"endgame", GameScript::QuitGame, 0}, //ending in iwd2 - {"enemy", GameScript::Enemy, 0}, - {"equipitem", GameScript::EquipItem, 0}, - {"equipmostdamagingmelee",GameScript::EquipMostDamagingMelee,0}, - {"equipranged", GameScript::EquipRanged,0}, - {"equipweapon", GameScript::EquipWeapon,0}, - {"erasejournalentry", GameScript::RemoveJournalEntry, 0}, - {"escapearea", GameScript::EscapeArea, AF_BLOCKING}, - {"escapeareadestroy", GameScript::EscapeAreaDestroy, AF_BLOCKING}, - {"escapeareanosee", GameScript::EscapeAreaNoSee, AF_BLOCKING}, - {"escapeareaobject", GameScript::EscapeAreaObject, AF_BLOCKING}, - {"escapeareaobjectnosee", GameScript::EscapeAreaObjectNoSee, AF_BLOCKING}, - {"exitpocketplane", GameScript::ExitPocketPlane, 0}, - {"expansionendcredits", GameScript::QuitGame, 0},//ends game too - {"explore", GameScript::Explore, 0}, - {"exploremapchunk", GameScript::ExploreMapChunk, 0}, - {"exportparty", GameScript::ExportParty, 0}, - {"face", GameScript::Face,AF_BLOCKING}, - {"faceobject", GameScript::FaceObject, AF_BLOCKING}, - {"facesavedlocation", GameScript::FaceSavedLocation, AF_BLOCKING}, - {"fadefromblack", GameScript::FadeFromColor, AF_BLOCKING}, //probably the same - {"fadefromcolor", GameScript::FadeFromColor, AF_BLOCKING}, - {"fadetoandfromcolor", GameScript::FadeToAndFromColor, AF_BLOCKING}, - {"fadetoblack", GameScript::FadeToColor, AF_BLOCKING}, //probably the same - {"fadetocolor", GameScript::FadeToColor, AF_BLOCKING}, - {"fakeeffectexpirycheck", GameScript::FakeEffectExpiryCheck, 0}, - {"fillslot", GameScript::FillSlot, 0}, - {"finalsave", GameScript::SaveGame, 0}, //synonym - {"findtraps", GameScript::FindTraps, 0}, - {"fixengineroom", GameScript::FixEngineRoom, 0}, - {"floatmessage", GameScript::DisplayStringHead, 0}, - {"floatmessagefixed", GameScript::FloatMessageFixed, 0}, - {"floatmessagefixedrnd", GameScript::FloatMessageFixedRnd, 0}, - {"floatmessagernd", GameScript::FloatMessageRnd, 0}, - {"floatrebus", GameScript::FloatRebus, 0}, - {"follow", GameScript::Follow, AF_ALIVE}, - {"followcreature", GameScript::FollowCreature, AF_BLOCKING|AF_ALIVE}, //pst - {"followobjectformation", GameScript::FollowObjectFormation, AF_BLOCKING|AF_ALIVE}, - {"forceaiscript", GameScript::ForceAIScript, 0}, - {"forceattack", GameScript::ForceAttack, 0}, - {"forcefacing", GameScript::ForceFacing, 0}, - {"forcehide", GameScript::ForceHide, 0}, - {"forceleavearealua", GameScript::ForceLeaveAreaLUA, 0}, - {"forcemarkedspell", GameScript::ForceMarkedSpell, 0}, - {"forcespell", GameScript::ForceSpell, AF_BLOCKING}, - {"forcespellpoint", GameScript::ForceSpellPoint, AF_BLOCKING}, - {"forceusecontainer", GameScript::ForceUseContainer,AF_BLOCKING}, - {"formation", GameScript::Formation, AF_BLOCKING}, - {"fullheal", GameScript::FullHeal, 0}, - {"fullhealex", GameScript::FullHeal, 0}, //pst, not sure what's different - {"generatemodronmaze", GameScript::GenerateMaze, 0}, - {"generatepartymember", GameScript::GeneratePartyMember, 0}, - {"getitem", GameScript::GetItem, 0}, - {"getstat", GameScript::GetStat, 0}, //gemrb specific - {"giveexperience", GameScript::AddXPObject, 0}, - {"givegoldforce", GameScript::CreatePartyGold, 0}, //this is the same - {"giveitem", GameScript::GiveItem, 0}, - {"giveitemcreate", GameScript::CreateItem, 0}, //actually this is a targeted createitem - {"giveorder", GameScript::GiveOrder, 0}, - {"givepartyallequipment", GameScript::GivePartyAllEquipment, 0}, - {"givepartygold", GameScript::GivePartyGold, 0}, - {"givepartygoldglobal", GameScript::GivePartyGoldGlobal,0},//no mergestrings! - {"globaladdglobal", GameScript::GlobalAddGlobal,AF_MERGESTRINGS}, - {"globalandglobal", GameScript::GlobalAndGlobal,AF_MERGESTRINGS}, - {"globalband", GameScript::GlobalBAnd,AF_MERGESTRINGS}, - {"globalbandglobal", GameScript::GlobalBAndGlobal,AF_MERGESTRINGS}, - {"globalbitglobal", GameScript::GlobalBitGlobal, AF_MERGESTRINGS}, - {"globalbor", GameScript::GlobalBOr,AF_MERGESTRINGS}, - {"globalborglobal", GameScript::GlobalBOrGlobal,AF_MERGESTRINGS}, - {"globalmax", GameScript::GlobalMax,AF_MERGESTRINGS}, - {"globalmaxglobal", GameScript::GlobalMaxGlobal,AF_MERGESTRINGS}, - {"globalmin", GameScript::GlobalMin,AF_MERGESTRINGS}, - {"globalminglobal", GameScript::GlobalMinGlobal,AF_MERGESTRINGS}, - {"globalorglobal", GameScript::GlobalOrGlobal,AF_MERGESTRINGS}, - {"globalset", GameScript::SetGlobal,AF_MERGESTRINGS}, - {"globalsetglobal", GameScript::GlobalSetGlobal,AF_MERGESTRINGS}, - {"globalshl", GameScript::GlobalShL,AF_MERGESTRINGS}, - {"globalshlglobal", GameScript::GlobalShLGlobal,AF_MERGESTRINGS}, - {"globalshout", GameScript::GlobalShout, 0}, - {"globalshr", GameScript::GlobalShR,AF_MERGESTRINGS}, - {"globalshrglobal", GameScript::GlobalShRGlobal,AF_MERGESTRINGS}, - {"globalsubglobal", GameScript::GlobalSubGlobal,AF_MERGESTRINGS}, - {"globalxor", GameScript::GlobalXor,AF_MERGESTRINGS}, - {"globalxorglobal", GameScript::GlobalXorGlobal,AF_MERGESTRINGS}, - {"gotostartscreen", GameScript::QuitGame, 0},//ending - {"help", GameScript::Help, 0}, - {"hide", GameScript::Hide, 0}, - {"hideareaonmap", GameScript::HideAreaOnMap, 0}, - {"hidecreature", GameScript::HideCreature, 0}, - {"hidegui", GameScript::HideGUI, 0}, - {"incinternal", GameScript::IncInternal, 0}, //pst - {"incrementinternal", GameScript::IncInternal, 0},//iwd - {"incmoraleai", GameScript::IncMoraleAI, 0}, - {"incrementchapter", GameScript::IncrementChapter, AF_BLOCKING}, - {"incrementextraproficiency", GameScript::IncrementExtraProficiency, 0}, - {"incrementglobal", GameScript::IncrementGlobal,AF_MERGESTRINGS}, - {"incrementglobalonce", GameScript::IncrementGlobalOnce,AF_MERGESTRINGS}, - {"incrementkillstat", GameScript::IncrementKillStat, 0}, - {"incrementproficiency", GameScript::IncrementProficiency, 0}, - {"interact", GameScript::Interact, 0}, - {"joinparty", GameScript::JoinParty, 0}, //this action appears to be blocking in bg2 - {"journalentrydone", GameScript::SetQuestDone, 0}, - {"jumptoobject", GameScript::JumpToObject, 0}, - {"jumptopoint", GameScript::JumpToPoint, 0}, - {"jumptopointinstant", GameScript::JumpToPointInstant, 0}, - {"jumptosavedlocation", GameScript::JumpToSavedLocation, 0}, - {"kill", GameScript::Kill, 0}, - {"killfloatmessage", GameScript::KillFloatMessage, 0}, - {"leader", GameScript::Leader, AF_ALIVE}, - {"leavearea", GameScript::LeaveAreaLUA, 0}, //so far the same - {"leavearealua", GameScript::LeaveAreaLUA, 0}, - {"leavearealuaentry", GameScript::LeaveAreaLUAEntry,AF_BLOCKING}, - {"leavearealuapanic", GameScript::LeaveAreaLUAPanic, 0}, - {"leavearealuapanicentry", GameScript::LeaveAreaLUAPanicEntry,AF_BLOCKING}, - {"leaveparty", GameScript::LeaveParty, 0}, - {"lock", GameScript::Lock, 0},//key not checked at this time! - {"lockscroll", GameScript::LockScroll, 0}, - {"log", GameScript::Debug, 0}, //the same until we know better - {"makeglobal", GameScript::MakeGlobal, 0}, - {"makeunselectable", GameScript::MakeUnselectable, 0}, - {"markobject", GameScript::MarkObject, 0}, - {"markspellandobject", GameScript::MarkSpellAndObject, 0}, - {"moraledec", GameScript::MoraleDec, 0}, - {"moraleinc", GameScript::MoraleInc, 0}, - {"moraleset", GameScript::MoraleSet, 0}, - {"matchhp", GameScript::MatchHP, 0}, - {"movebetweenareas", GameScript::MoveBetweenAreas, 0}, - {"movebetweenareaseffect", GameScript::MoveBetweenAreas, 0}, - {"movecursorpoint", GameScript::MoveCursorPoint, 0},//immediate move - {"moveglobal", GameScript::MoveGlobal, 0}, - {"moveglobalobject", GameScript::MoveGlobalObject, 0}, - {"moveglobalobjectoffscreen", GameScript::MoveGlobalObjectOffScreen, 0}, - {"moveglobalsto", GameScript::MoveGlobalsTo, 0}, - {"transferinventory", GameScript::MoveInventory, 0}, - {"movetocenterofscreen", GameScript::MoveToCenterOfScreen,AF_BLOCKING}, - {"movetoexpansion", GameScript::MoveToExpansion,AF_BLOCKING}, - {"movetoobject", GameScript::MoveToObject,AF_BLOCKING|AF_ALIVE}, - {"movetoobjectfollow", GameScript::MoveToObjectFollow,AF_BLOCKING|AF_ALIVE}, - {"movetoobjectnointerrupt", GameScript::MoveToObjectNoInterrupt,AF_BLOCKING|AF_ALIVE}, - {"movetoobjectuntilsee", GameScript::MoveToObjectUntilSee,AF_BLOCKING|AF_ALIVE}, - {"movetooffset", GameScript::MoveToOffset,AF_BLOCKING|AF_ALIVE}, - {"movetopoint", GameScript::MoveToPoint,AF_BLOCKING|AF_ALIVE}, - {"movetopointnointerrupt", GameScript::MoveToPointNoInterrupt,AF_BLOCKING|AF_ALIVE}, - {"movetopointnorecticle", GameScript::MoveToPointNoRecticle,AF_BLOCKING|AF_ALIVE},//the same until we know better - {"movetosavedlocation", GameScript::MoveToSavedLocation,AF_MERGESTRINGS|AF_BLOCKING}, - //take care of the typo in the original bg2 action.ids - //FIXME: why doesn't this have MERGESTRINGS like the above entry? - {"movetosavedlocationn", GameScript::MoveToSavedLocation,AF_BLOCKING}, - {"moveviewobject", GameScript::MoveViewObject, AF_BLOCKING}, - {"moveviewpoint", GameScript::MoveViewPoint, AF_BLOCKING}, - {"moveviewpointuntildone", GameScript::MoveViewPoint, 0}, - {"nidspecial1", GameScript::NIDSpecial1,AF_BLOCKING|AF_DIRECT|AF_ALIVE},//we use this for dialogs, hack - {"nidspecial2", GameScript::NIDSpecial2,AF_BLOCKING},//we use this for worldmap, another hack - {"nidspecial3", GameScript::Attack,AF_BLOCKING|AF_DIRECT|AF_ALIVE},//this hack is for attacking preset target - {"nidspecial4", GameScript::ProtectObject,AF_BLOCKING|AF_DIRECT|AF_ALIVE}, - {"nidspecial5", GameScript::UseItem, AF_BLOCKING|AF_DIRECT|AF_ALIVE}, - {"nidspecial6", GameScript::Spell, AF_BLOCKING|AF_DIRECT|AF_ALIVE}, - {"nidspecial7", GameScript::SpellNoDec, AF_BLOCKING|AF_DIRECT|AF_ALIVE}, - //{"nidspecial8", GameScript::SpellPoint, AF_BLOCKING|AF_ALIVE}, //not needed - {"nidspecial9", GameScript::ToggleDoor, AF_BLOCKING},//another internal hack, maybe we should use UseDoor instead - {"noaction", GameScript::NoAction, 0}, - {"opendoor", GameScript::OpenDoor,0}, - {"panic", GameScript::Panic, AF_ALIVE}, - {"permanentstatchange", GameScript::PermanentStatChange, 0}, //pst - {"pausegame", GameScript::PauseGame, AF_BLOCKING}, //this is almost surely blocking - {"picklock", GameScript::PickLock,AF_BLOCKING}, - {"pickpockets", GameScript::PickPockets, AF_BLOCKING}, - {"pickupitem", GameScript::PickUpItem, 0}, - {"playbardsong", GameScript::PlayBardSong, AF_ALIVE}, - {"playdead", GameScript::PlayDead,AF_BLOCKING|AF_ALIVE}, - {"playdeadinterruptable", GameScript::PlayDeadInterruptable,AF_BLOCKING|AF_ALIVE}, - {"playerdialog", GameScript::PlayerDialogue,AF_BLOCKING}, - {"playerdialogue", GameScript::PlayerDialogue,AF_BLOCKING}, - {"playsequence", GameScript::PlaySequence, 0}, - {"playsequenceglobal", GameScript::PlaySequenceGlobal, 0}, //pst - {"playsequencetimed", GameScript::PlaySequenceTimed, 0},//pst - {"playsong", GameScript::StartSong, 0}, - {"playsound", GameScript::PlaySound, 0}, - {"playsoundnotranged", GameScript::PlaySoundNotRanged, 0}, - {"playsoundpoint", GameScript::PlaySoundPoint, 0}, - {"plunder", GameScript::Plunder,AF_BLOCKING|AF_ALIVE}, - {"polymorph", GameScript::Polymorph, 0}, - {"polymorphcopy", GameScript::PolymorphCopy, 0}, - {"polymorphcopybase", GameScript::PolymorphCopyBase, 0}, - {"protectobject", GameScript::ProtectObject, 0}, - {"protectpoint", GameScript::ProtectPoint, AF_BLOCKING}, - {"quitgame", GameScript::QuitGame, 0}, - {"randomfly", GameScript::RandomFly, AF_BLOCKING|AF_ALIVE}, - {"randomrun", GameScript::RandomRun, AF_BLOCKING|AF_ALIVE}, - {"randomturn", GameScript::RandomTurn, AF_BLOCKING}, - {"randomwalk", GameScript::RandomWalk, AF_BLOCKING|AF_ALIVE}, - {"randomwalkcontinuous", GameScript::RandomWalkContinuous, AF_BLOCKING|AF_ALIVE}, - {"realsetglobaltimer", GameScript::RealSetGlobalTimer,AF_MERGESTRINGS}, - {"reallyforcespell", GameScript::ReallyForceSpell, AF_BLOCKING}, - {"reallyforcespelldead", GameScript::ReallyForceSpellDead, AF_BLOCKING}, - {"reallyforcespelllevel", GameScript::ReallyForceSpell, AF_BLOCKING},//this is the same action - {"reallyforcespellpoint", GameScript::ReallyForceSpellPoint, AF_BLOCKING}, - {"recoil", GameScript::Recoil, AF_ALIVE}, - {"regainpaladinhood", GameScript::RegainPaladinHood, 0}, - {"regainrangerhood", GameScript::RegainRangerHood, 0}, - {"removeareaflag", GameScript::RemoveAreaFlag, 0}, - {"removeareatype", GameScript::RemoveAreaType, 0}, - {"removejournalentry", GameScript::RemoveJournalEntry, 0}, - {"removemapnote", GameScript::RemoveMapnote, 0}, - {"removepaladinhood", GameScript::RemovePaladinHood, 0}, - {"removerangerhood", GameScript::RemoveRangerHood, 0}, - {"removespell", GameScript::RemoveSpell, 0}, - {"removetraps", GameScript::RemoveTraps, AF_BLOCKING}, - {"reputationinc", GameScript::ReputationInc, 0}, - {"reputationset", GameScript::ReputationSet, 0}, - {"resetfogofwar", GameScript::UndoExplore, 0}, //pst - {"rest", GameScript::Rest, AF_ALIVE}, - {"restnospells", GameScript::RestNoSpells, 0}, - {"restorepartylocations", GameScript:: RestorePartyLocation, 0}, - {"restparty", GameScript::RestParty, 0}, - {"restuntilhealed", GameScript::RestUntilHealed, 0}, - //this is in iwd2, same as movetosavedlocation, but with stats - {"returntosavedlocation", GameScript::ReturnToSavedLocation, AF_BLOCKING|AF_ALIVE}, - {"returntosavedlocationdelete", GameScript::ReturnToSavedLocationDelete, AF_BLOCKING|AF_ALIVE}, - {"returntosavedplace", GameScript::ReturnToSavedLocation, AF_BLOCKING|AF_ALIVE}, - {"revealareaonmap", GameScript::RevealAreaOnMap, 0}, - {"runawayfrom", GameScript::RunAwayFrom,AF_BLOCKING|AF_ALIVE}, - {"runawayfromnointerrupt", GameScript::RunAwayFromNoInterrupt,AF_BLOCKING|AF_ALIVE}, - {"runawayfromnoleavearea", GameScript::RunAwayFromNoLeaveArea,AF_BLOCKING|AF_ALIVE}, - {"runawayfrompoint", GameScript::RunAwayFromPoint,AF_BLOCKING|AF_ALIVE}, - {"runfollow", GameScript::RunAwayFrom,AF_BLOCKING|AF_ALIVE}, - {"runningattack", GameScript::RunningAttack,AF_BLOCKING|AF_ALIVE}, - {"runningattacknosound", GameScript::RunningAttackNoSound,AF_BLOCKING|AF_ALIVE}, - {"runtoobject", GameScript::RunToObject,AF_BLOCKING|AF_ALIVE}, - {"runtopoint", GameScript::RunToPoint,AF_BLOCKING}, - {"runtopointnorecticle", GameScript::RunToPointNoRecticle,AF_BLOCKING|AF_ALIVE}, - {"runtosavedlocation", GameScript::RunToSavedLocation,AF_BLOCKING|AF_ALIVE}, - {"savegame", GameScript::SaveGame, 0}, - {"savelocation", GameScript::SaveLocation, 0}, - {"saveplace", GameScript::SaveLocation, 0}, - {"saveobjectlocation", GameScript::SaveObjectLocation, 0}, - {"screenshake", GameScript::ScreenShake,AF_BLOCKING}, - {"selectweaponability", GameScript::SelectWeaponAbility, 0}, - {"sendtrigger", GameScript::SendTrigger, 0}, - {"setanimstate", GameScript::PlaySequence, AF_ALIVE},//pst - {"setapparentnamestrref", GameScript::SetApparentName, 0}, - {"setareaflags", GameScript::SetAreaFlags, 0}, - {"setarearestflag", GameScript::SetAreaRestFlag, 0}, - {"setbeeninpartyflags", GameScript::SetBeenInPartyFlags, 0}, - {"setbestweapon", GameScript::SetBestWeapon, 0}, - {"setcorpseenabled", GameScript::AmbientActivate, 0},//another weird name - {"setcutsceneline", GameScript::SetCursorState, 0}, //same as next - {"setcursorstate", GameScript::SetCursorState, 0}, - {"setcreatureareaflag", GameScript::SetCreatureAreaFlag, 0}, - {"setcriticalpathobject", GameScript::SetCriticalPathObject, 0}, - {"setdialog", GameScript::SetDialogue,0}, - {"setdialogrange", GameScript::SetDialogueRange, 0}, - {"setdialogue", GameScript::SetDialogue,0}, - {"setdialoguerange", GameScript::SetDialogueRange, 0}, - {"setdoorflag", GameScript::SetDoorFlag,0}, - {"setdoorlocked", GameScript::SetDoorLocked,0}, - {"setencounterprobability", GameScript::SetEncounterProbability,0}, - {"setextendednight", GameScript::SetExtendedNight, 0}, - {"setfaction", GameScript::SetFaction, 0}, - {"setgabber", GameScript::SetGabber, 0}, - {"setglobal", GameScript::SetGlobal,AF_MERGESTRINGS}, - {"setglobalrandom", GameScript::SetGlobalRandom, AF_MERGESTRINGS}, - {"setglobaltimer", GameScript::SetGlobalTimer,AF_MERGESTRINGS}, - {"setglobaltimeronce", GameScript::SetGlobalTimerOnce,AF_MERGESTRINGS}, - {"setglobaltimerrandom", GameScript::SetGlobalTimerRandom,AF_MERGESTRINGS}, - {"setglobaltint", GameScript::SetGlobalTint, 0}, - {"sethomelocation", GameScript::SetSavedLocation, 0}, //bg2 - {"sethp", GameScript::SetHP, 0}, - {"sethppercent", GameScript::SetHPPercent, 0}, - {"setinternal", GameScript::SetInternal, 0}, - {"setinterrupt", GameScript::SetInterrupt, 0}, - {"setleavepartydialogfile", GameScript::SetLeavePartyDialogFile, 0}, - {"setleavepartydialoguefile", GameScript::SetLeavePartyDialogFile, 0}, - {"setmarkedspell", GameScript::SetMarkedSpell, 0}, - {"setmasterarea", GameScript::SetMasterArea, 0}, - {"setmazeeasier", GameScript::SetMazeEasier, 0}, //pst specific crap - {"setmazeharder", GameScript::SetMazeHarder, 0}, //pst specific crap - {"setmoraleai", GameScript::SetMoraleAI, 0}, - {"setmusic", GameScript::SetMusic, 0}, - {"setname", GameScript::SetApparentName, 0}, - {"setnamelessclass", GameScript::SetNamelessClass, 0}, - {"setnamelessdeath", GameScript::SetNamelessDeath, 0}, - {"setnamelessdisguise", GameScript::SetNamelessDisguise, 0}, - {"setnooneontrigger", GameScript::SetNoOneOnTrigger, 0}, - {"setnumtimestalkedto", GameScript::SetNumTimesTalkedTo, 0}, - {"setplayersound", GameScript::SetPlayerSound, 0}, - {"setquestdone", GameScript::SetQuestDone, 0}, - {"setregularnamestrref", GameScript::SetRegularName, 0}, - {"setrestencounterchance", GameScript::SetRestEncounterChance, 0}, - {"setrestencounterprobabilityday", GameScript::SetRestEncounterProbabilityDay, 0}, - {"setrestencounterprobabilitynight", GameScript::SetRestEncounterProbabilityNight, 0}, - {"setsavedlocation", GameScript::SetSavedLocation, 0}, - {"setsavedlocationpoint", GameScript::SetSavedLocationPoint, 0}, - {"setscriptname", GameScript::SetScriptName, 0}, - {"setselection", GameScript::SetSelection, 0}, - {"setsequence", GameScript::PlaySequence, 0}, //bg2 (only own) - {"setstartpos", GameScript::SetStartPos, 0}, - {"setteam", GameScript::SetTeam, 0}, - {"setteambit", GameScript::SetTeamBit, 0}, - {"settextcolor", GameScript::SetTextColor, 0}, - {"settrackstring", GameScript::SetTrackString, 0}, - {"settoken", GameScript::SetToken, 0}, - {"settoken2da", GameScript::SetToken2DA, 0}, //GemRB specific - {"settokenglobal", GameScript::SetTokenGlobal,AF_MERGESTRINGS}, - {"settokenobject", GameScript::SetTokenObject,0}, - {"setupwish", GameScript::SetupWish, 0}, - {"setupwishobject", GameScript::SetupWishObject, 0}, - {"setvisualrange", GameScript::SetVisualRange, 0}, - {"sg", GameScript::SG, 0}, - {"shout", GameScript::Shout, 0}, - {"sinisterpoof", GameScript::CreateVisualEffect, 0}, - {"smallwait", GameScript::SmallWait,AF_BLOCKING}, - {"smallwaitrandom", GameScript::SmallWaitRandom,AF_BLOCKING}, - {"soundactivate", GameScript::SoundActivate, 0}, - {"spawnptactivate", GameScript::SpawnPtActivate, 0}, - {"spawnptdeactivate", GameScript::SpawnPtDeactivate, 0}, - {"spawnptspawn", GameScript::SpawnPtSpawn, 0}, - {"spell", GameScript::Spell, AF_BLOCKING|AF_ALIVE}, - {"spellcasteffect", GameScript::SpellCastEffect, 0}, - {"spellhiteffectpoint", GameScript::SpellHitEffectPoint, 0}, - {"spellhiteffectsprite", GameScript::SpellHitEffectSprite, 0}, - {"spellnodec", GameScript::SpellNoDec, AF_BLOCKING|AF_ALIVE}, - {"spellpoint", GameScript::SpellPoint, AF_BLOCKING|AF_ALIVE}, - {"spellpointnodec", GameScript::SpellPointNoDec, AF_BLOCKING|AF_ALIVE}, - {"startcombatcounter", GameScript::StartCombatCounter, 0}, - {"startcutscene", GameScript::StartCutScene, 0}, - {"startcutsceneex", GameScript::StartCutScene, 0}, //pst (unknown) - {"startcutscenemode", GameScript::StartCutSceneMode, 0}, - {"startdialog", GameScript::StartDialogue,AF_BLOCKING}, - {"startdialoginterrupt", GameScript::StartDialogueInterrupt,AF_BLOCKING}, - {"startdialogue", GameScript::StartDialogue,AF_BLOCKING}, - {"startdialogueinterrupt", GameScript::StartDialogueInterrupt,AF_BLOCKING}, - {"startdialognoname", GameScript::StartDialogue,AF_BLOCKING}, - {"startdialognoset", GameScript::StartDialogueNoSet,AF_BLOCKING}, - {"startdialognosetinterrupt", GameScript::StartDialogueNoSetInterrupt,AF_BLOCKING}, - {"startdialogoverride", GameScript::StartDialogueOverride,AF_BLOCKING}, - {"startdialogoverrideinterrupt", GameScript::StartDialogueOverrideInterrupt,AF_BLOCKING}, - {"startdialoguenoname", GameScript::StartDialogue,AF_BLOCKING}, - {"startdialoguenoset", GameScript::StartDialogueNoSet,AF_BLOCKING}, - {"startdialoguenosetinterrupt", GameScript::StartDialogueNoSetInterrupt,AF_BLOCKING}, - {"startdialogueoverride", GameScript::StartDialogueOverride,AF_BLOCKING}, - {"startdialogueoverrideinterrupt", GameScript::StartDialogueOverrideInterrupt,AF_BLOCKING}, - {"startmovie", GameScript::StartMovie,AF_BLOCKING}, - {"startmusic", GameScript::StartMusic, 0}, - {"startrainnow", GameScript::StartRainNow, 0}, - {"startrandomtimer", GameScript::StartRandomTimer, 0}, - {"startsong", GameScript::StartSong, 0}, - {"startstore", GameScript::StartStore, 0}, - {"starttimer", GameScript::StartTimer, 0}, - {"stateoverrideflag", GameScript::StateOverrideFlag, 0}, - {"stateoverridetime", GameScript::StateOverrideTime, 0}, - {"staticpalette", GameScript::StaticPalette, 0}, - {"staticsequence", GameScript::PlaySequence, 0},//bg2 animation sequence - {"staticstart", GameScript::StaticStart, 0}, - {"staticstop", GameScript::StaticStop, 0}, - {"stickysinisterpoof", GameScript::CreateVisualEffectObjectSticky, 0}, - {"stopmoving", GameScript::StopMoving, 0}, - {"storepartylocations", GameScript::StorePartyLocation, 0}, - {"swing", GameScript::Swing, AF_ALIVE}, - {"swingonce", GameScript::SwingOnce, AF_ALIVE}, - {"takeitemlist", GameScript::TakeItemList, 0}, - {"takeitemlistparty", GameScript::TakeItemListParty, 0}, - {"takeitemlistpartynum", GameScript::TakeItemListPartyNum, 0}, - {"takeitemreplace", GameScript::TakeItemReplace, 0}, - {"takepartygold", GameScript::TakePartyGold, 0}, - {"takepartyitem", GameScript::TakePartyItem, 0}, - {"takepartyitemall", GameScript::TakePartyItemAll, 0}, - {"takepartyitemnum", GameScript::TakePartyItemNum, 0}, - {"takepartyitemrange", GameScript::TakePartyItemRange, 0}, - {"teleportparty", GameScript::TeleportParty, 0}, - {"textscreen", GameScript::TextScreen, AF_BLOCKING}, - {"timedmovetopoint", GameScript::TimedMoveToPoint,AF_BLOCKING|AF_ALIVE}, - {"tomsstringdisplayer", GameScript::DisplayMessage, 0}, - {"transformitem", GameScript::TransformItem, 0}, - {"transformitemall", GameScript::TransformItemAll, 0}, - {"transformpartyitem", GameScript::TransformPartyItem, 0}, - {"transformpartyitemall", GameScript::TransformPartyItemAll, 0}, - {"triggeractivation", GameScript::TriggerActivation, 0}, - {"triggerwalkto", GameScript::MoveToObject,AF_BLOCKING|AF_ALIVE}, //something like this - {"turn", GameScript::Turn, 0}, - {"turnamt", GameScript::TurnAMT, AF_BLOCKING}, //relative Face() - {"undoexplore", GameScript::UndoExplore, 0}, - {"unhidegui", GameScript::UnhideGUI, 0}, - {"unloadarea", GameScript::UnloadArea, 0}, - {"unlock", GameScript::Unlock, 0}, - {"unlockscroll", GameScript::UnlockScroll, 0}, - {"unmakeglobal", GameScript::UnMakeGlobal, 0}, //this is a GemRB extension - {"usecontainer", GameScript::UseContainer,AF_BLOCKING}, - {"usedoor", GameScript::UseDoor,AF_BLOCKING}, - {"useitem", GameScript::UseItem,AF_BLOCKING}, - {"useitempoint", GameScript::UseItemPoint,AF_BLOCKING}, - {"useitempointslot", GameScript::UseItemPoint,AF_BLOCKING}, - {"useitemslot", GameScript::UseItem,AF_BLOCKING}, - {"vequip",GameScript::SetArmourLevel, 0}, - {"verbalconstant", GameScript::VerbalConstant, 0}, - {"verbalconstanthead", GameScript::VerbalConstantHead, 0}, - {"wait", GameScript::Wait, AF_BLOCKING}, - {"waitanimation", GameScript::WaitAnimation,AF_BLOCKING},//iwd2 - {"waitrandom", GameScript::WaitRandom, AF_BLOCKING}, - {"weather", GameScript::Weather, 0}, - {"xequipitem", GameScript::XEquipItem, 0}, - { NULL,NULL, 0} -}; - -//Make this an ordered list, so we could use bsearch! -static const ObjectLink objectnames[] = { - {"bestac", GameScript::BestAC}, - {"eighthnearest", GameScript::EighthNearest}, - {"eighthnearestdoor", GameScript::EighthNearestDoor}, - {"eighthnearestenemyof", GameScript::EighthNearestEnemyOf}, - {"eighthnearestenemyoftype", GameScript::EighthNearestEnemyOfType}, - {"eighthnearestmygroupoftype", GameScript::EighthNearestEnemyOfType}, - {"eigthnearestenemyof", GameScript::EighthNearestEnemyOf}, //typo in iwd - {"eigthnearestenemyoftype", GameScript::EighthNearestEnemyOfType}, //bg2 - {"eigthnearestmygroupoftype", GameScript::EighthNearestEnemyOfType},//bg2 - {"farthest", GameScript::Farthest}, - {"farthestenemyof", GameScript::FarthestEnemyOf}, - {"fifthnearest", GameScript::FifthNearest}, - {"fifthnearestdoor", GameScript::FifthNearestDoor}, - {"fifthnearestenemyof", GameScript::FifthNearestEnemyOf}, - {"fifthnearestenemyoftype", GameScript::FifthNearestEnemyOfType}, - {"fifthnearestmygroupoftype", GameScript::FifthNearestEnemyOfType}, - {"fourthnearest", GameScript::FourthNearest}, - {"fourthnearestdoor", GameScript::FourthNearestDoor}, - {"fourthnearestenemyof", GameScript::FourthNearestEnemyOf}, - {"fourthnearestenemyoftype", GameScript::FourthNearestEnemyOfType}, - {"fourthnearestmygroupoftype", GameScript::FourthNearestEnemyOfType}, - {"gabber", GameScript::Gabber}, - {"groupof", GameScript::GroupOf}, - {"lastattackerof", GameScript::LastAttackerOf}, - {"lastcommandedby", GameScript::LastCommandedBy}, - {"lastheardby", GameScript::LastHeardBy}, - {"lasthelp", GameScript::LastHelp}, - {"lasthitter", GameScript::LastHitter}, - {"lastmarkedobject", GameScript::LastMarkedObject}, - {"lastseenby", GameScript::LastSeenBy}, - {"lastsummonerof", GameScript::LastSummonerOf}, - {"lasttalkedtoby", GameScript::LastTalkedToBy}, - {"lasttargetedby", GameScript::LastTargetedBy}, - {"lasttrigger", GameScript::LastTrigger}, - {"leaderof", GameScript::LeaderOf}, - {"leastdamagedof", GameScript::LeastDamagedOf}, - {"marked", GameScript::LastMarkedObject}, //pst - {"mostdamagedof", GameScript::MostDamagedOf}, - {"myself", GameScript::Myself}, - {"mytarget", GameScript::MyTarget},//see lasttargetedby(myself) - {"nearest", GameScript::Nearest}, //actually this seems broken in IE and resolve as Myself - {"nearestdoor", GameScript::NearestDoor}, - {"nearestenemyof", GameScript::NearestEnemyOf}, - {"nearestenemyoftype", GameScript::NearestEnemyOfType}, - {"nearestenemysummoned", GameScript::NearestEnemySummoned}, - {"nearestmygroupoftype", GameScript::NearestMyGroupOfType}, - {"nearestpc", GameScript::NearestPC}, - {"ninthnearest", GameScript::NinthNearest}, - {"ninthnearestdoor", GameScript::NinthNearestDoor}, - {"ninthnearestenemyof", GameScript::NinthNearestEnemyOf}, - {"ninthnearestenemyoftype", GameScript::NinthNearestEnemyOfType}, - {"ninthnearestmygroupoftype", GameScript::NinthNearestMyGroupOfType}, - {"nothing", GameScript::Nothing}, - {"player1", GameScript::Player1}, - {"player1fill", GameScript::Player1Fill}, - {"player2", GameScript::Player2}, - {"player2fill", GameScript::Player2Fill}, - {"player3", GameScript::Player3}, - {"player3fill", GameScript::Player3Fill}, - {"player4", GameScript::Player4}, - {"player4fill", GameScript::Player4Fill}, - {"player5", GameScript::Player5}, - {"player5fill", GameScript::Player5Fill}, - {"player6", GameScript::Player6}, - {"player6fill", GameScript::Player6Fill}, - {"player7", GameScript::Player7}, - {"player7fill", GameScript::Player7Fill}, - {"player8", GameScript::Player8}, - {"player8fill", GameScript::Player8Fill}, - {"protectedby", GameScript::ProtectedBy}, - {"protectorof", GameScript::ProtectorOf}, - {"protagonist", GameScript::Protagonist}, - {"secondnearest", GameScript::SecondNearest}, - {"secondnearestdoor", GameScript::SecondNearestDoor}, - {"secondnearestenemyof", GameScript::SecondNearestEnemyOf}, - {"secondnearestenemyoftype", GameScript::SecondNearestEnemyOfType}, - {"secondnearestmygroupoftype", GameScript::SecondNearestMyGroupOfType}, - {"selectedcharacter", GameScript::SelectedCharacter}, - {"seventhnearest", GameScript::SeventhNearest}, - {"seventhnearestdoor", GameScript::SeventhNearestDoor}, - {"seventhnearestenemyof", GameScript::SeventhNearestEnemyOf}, - {"seventhnearestenemyoftype", GameScript::SeventhNearestEnemyOfType}, - {"seventhnearestmygroupoftype", GameScript::SeventhNearestMyGroupOfType}, - {"sixthnearest", GameScript::SixthNearest}, - {"sixthnearestdoor", GameScript::SixthNearestDoor}, - {"sixthnearestenemyof", GameScript::SixthNearestEnemyOf}, - {"sixthnearestenemyoftype", GameScript::SixthNearestEnemyOfType}, - {"sixthnearestmygroupoftype", GameScript::SixthNearestMyGroupOfType}, - {"strongestof", GameScript::StrongestOf}, - {"strongestofmale", GameScript::StrongestOfMale}, - {"tenthnearest", GameScript::TenthNearest}, - {"tenthnearestdoor", GameScript::TenthNearestDoor}, - {"tenthnearestenemyof", GameScript::TenthNearestEnemyOf}, - {"tenthnearestenemyoftype", GameScript::TenthNearestEnemyOfType}, - {"tenthnearestmygroupoftype", GameScript::TenthNearestMyGroupOfType}, - {"thirdnearest", GameScript::ThirdNearest}, - {"thirdnearestdoor", GameScript::ThirdNearestDoor}, - {"thirdnearestenemyof", GameScript::ThirdNearestEnemyOf}, - {"thirdnearestenemyoftype", GameScript::ThirdNearestEnemyOfType}, - {"thirdnearestmygroupoftype", GameScript::ThirdNearestMyGroupOfType}, - {"weakestof", GameScript::WeakestOf}, - {"worstac", GameScript::WorstAC}, - { NULL,NULL} -}; - -static const IDSLink idsnames[] = { - {"align", GameScript::ID_Alignment}, - {"alignmen", GameScript::ID_Alignment}, - {"alignmnt", GameScript::ID_Alignment}, - {"class20", GameScript::ID_AVClass}, - {"class", GameScript::ID_Class}, - {"classmsk", GameScript::ID_ClassMask}, - {"ea", GameScript::ID_Allegiance}, - {"faction", GameScript::ID_Faction}, - {"gender", GameScript::ID_Gender}, - {"general", GameScript::ID_General}, - {"race", GameScript::ID_Race}, - {"specific", GameScript::ID_Specific}, - {"subrace", GameScript::ID_Subrace}, - {"team", GameScript::ID_Team}, - { NULL,NULL} -}; - -static const TriggerLink* FindTrigger(const char* triggername) -{ - if (!triggername) { - return NULL; - } - int len = strlench( triggername, '(' ); - for (int i = 0; triggernames[i].Name; i++) { - if (!strnicmp( triggernames[i].Name, triggername, len )) { - if (!triggernames[i].Name[len]) { - return triggernames + i; - } - } - } - return NULL; -} - -static const ActionLink* FindAction(const char* actionname) -{ - if (!actionname) { - return NULL; - } - int len = strlench( actionname, '(' ); - for (int i = 0; actionnames[i].Name; i++) { - if (!strnicmp( actionnames[i].Name, actionname, len )) { - if (!actionnames[i].Name[len]) { - return actionnames + i; - } - } - } - return NULL; -} - -static const ObjectLink* FindObject(const char* objectname) -{ - if (!objectname) { - return NULL; - } - int len = strlench( objectname, '(' ); - for (int i = 0; objectnames[i].Name; i++) { - if (!strnicmp( objectnames[i].Name, objectname, len )) { - if (!objectnames[i].Name[len]) { - return objectnames + i; - } - } - } - return NULL; -} - -static const IDSLink* FindIdentifier(const char* idsname) -{ - if (!idsname) { - return NULL; - } - int len = (int)strlen( idsname ); - for (int i = 0; idsnames[i].Name; i++) { - if (!strnicmp( idsnames[i].Name, idsname, len )) { - return idsnames + i; - } - } - - printMessage("GameScript", "Couldn't assign ids target: %.*s\n", YELLOW, - len, idsname ); - return NULL; -} - -void SetScriptDebugMode(int arg) -{ - InDebug=arg; -} - - - -/********************** Targets **********************************/ - -int Targets::Count() const -{ - return (int)objects.size(); -} - -targettype *Targets::RemoveTargetAt(targetlist::iterator &m) -{ - m=objects.erase(m); - if (m!=objects.end() ) { - return &(*m); - } - return NULL; -} - -const targettype *Targets::GetLastTarget(int Type) -{ - targetlist::const_iterator m = objects.end(); - while (m--!=objects.begin() ) { - if ( (Type==-1) || ((*m).actor->Type==Type) ) { - return &(*(m)); - } - } - return NULL; -} - -const targettype *Targets::GetFirstTarget(targetlist::iterator &m, int Type) -{ - m=objects.begin(); - while (m!=objects.end() ) { - if ( (Type!=-1) && ( (*m).actor->Type!=Type)) { - m++; - continue; - } - return &(*m); - } - return NULL; -} - -const targettype *Targets::GetNextTarget(targetlist::iterator &m, int Type) -{ - m++; - while (m!=objects.end() ) { - if ( (Type!=-1) && ( (*m).actor->Type!=Type)) { - m++; - continue; - } - return &(*m); - } - return NULL; -} - -Scriptable *Targets::GetTarget(unsigned int index, int Type) -{ - targetlist::iterator m = objects.begin(); - while(m!=objects.end() ) { - if ( (Type==-1) || ((*m).actor->Type==Type)) { - if (!index) { - return (*m).actor; - } - index--; - } - m++; - } - return NULL; -} - -//this stuff should be refined, dead actors are sometimes targetable by script? -void Targets::AddTarget(Scriptable* target, unsigned int distance, int ga_flags) -{ - if (!target) { - return; - } - - switch (target->Type) { - case ST_ACTOR: - //i don't know if unselectable actors are targetable by script - //if yes, then remove GA_SELECT - if (ga_flags) { - if (!((Actor *) target)->ValidTarget(ga_flags) ) { - return; - } - } - break; - case ST_GLOBAL: - // this doesn't seem a good idea to allow - return; - default: - break; - } - targettype Target = {target, distance}; - targetlist::iterator m; - for (m = objects.begin(); m != objects.end(); ++m) { - if ( (*m).distance>distance) { - objects.insert( m, Target); - return; - } - } - objects.push_back( Target ); -} - -void Targets::Clear() -{ - objects.clear(); -} - -/** releasing global memory */ -static void CleanupIEScript() -{ - triggersTable.release(); - actionsTable.release(); - objectsTable.release(); - overrideActionsTable.release(); - if (ObjectIDSTableNames) - free(ObjectIDSTableNames); - ObjectIDSTableNames = NULL; -} - -void printFunction(Holder table, int index) -{ - const char *str = table->GetStringIndex(index); - int value = table->GetValueIndex(index); - - int len = strchr(str,'(')-str; - if (len<0) { - print("%d %s\n", value, str); - } else { - print("%d %.*s\n", value, len, str); - } -} - -void InitializeIEScript() -{ - std::list missing_triggers; - std::list missing_actions; - std::list missing_objects; - std::list::iterator l; - - 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" ); - int oT = core->LoadSymbol( "object" ); - int gaT = core->LoadSymbol( "gemact" ); - AutoTable objNameTable("script"); - if (tT < 0 || aT < 0 || oT < 0 || !objNameTable) { - error("GameScript", "A critical scripting file is missing!\n"); - } - triggersTable = core->GetSymbol( tT ); - actionsTable = core->GetSymbol( aT ); - objectsTable = core->GetSymbol( oT ); - overrideActionsTable = core->GetSymbol( gaT ); - if (!triggersTable || !actionsTable || !objectsTable || !objNameTable) { - error("GameScript", "A critical scripting file is damaged!\n"); - } - - int i; - - /* Loading Script Configuration Parameters */ - - ObjectIDSCount = atoi( objNameTable->QueryField() ); - if (ObjectIDSCount<0 || ObjectIDSCount>MAX_OBJECT_FIELDS) { - error("GameScript", "The IDS Count shouldn't be more than 10!\n"); - } - - ObjectIDSTableNames = (ieResRef *) malloc( sizeof(ieResRef) * ObjectIDSCount ); - for (i = 0; i < ObjectIDSCount; i++) { - const char *idsname; - idsname=objNameTable->QueryField( 0, i + 1 ); - const IDSLink *poi=FindIdentifier( idsname ); - if (poi==NULL) { - idtargets[i]=NULL; - } - else { - idtargets[i]=poi->Function; - } - strnlwrcpy(ObjectIDSTableNames[i], idsname, 8 ); - } - MaxObjectNesting = atoi( objNameTable->QueryField( 1 ) ); - if (MaxObjectNesting<0 || MaxObjectNesting>MAX_NESTING) { - error("GameScript", "The Object Nesting Count shouldn't be more than 5!\n"); - } - HasAdditionalRect = ( atoi( objNameTable->QueryField( 2 ) ) != 0 ); - ExtraParametersCount = atoi( objNameTable->QueryField( 3 ) ); - HasTriggerPoint = ( atoi( objNameTable->QueryField( 4 ) ) != 0 ); - ObjectFieldsCount = ObjectIDSCount - ExtraParametersCount; - - /* Initializing the Script Engine */ - - memset( triggers, 0, sizeof( triggers ) ); - memset( triggerflags, 0, sizeof( triggerflags ) ); - memset( actions, 0, sizeof( actions ) ); - memset( actionflags, 0, sizeof( actionflags ) ); - memset( objects, 0, sizeof( objects ) ); - - int j; - - j = triggersTable->GetSize(); - while (j--) { - i = triggersTable->GetValueIndex( j ); - const TriggerLink* poi = FindTrigger(triggersTable->GetStringIndex( j )); - - bool was_condition = (i & 0x4000); - i &= 0x3fff; - if (i >= MAX_TRIGGERS) { - printMessage("GameScript", "trigger %d (%s) is too high, ignoring\n", RED, - i, triggersTable->GetStringIndex( j ) ); - continue; - } - - if (triggers[i]) { - if (poi && triggers[i]!=poi->Function) { - printMessage("GameScript", "%s is in collision with ", YELLOW, - triggersTable->GetStringIndex( j ) ); - printFunction(triggersTable,triggersTable->FindValue(triggersTable->GetValueIndex( j ))); - } else { - if (InDebug&ID_TRIGGERS) { - printMessage("GameScript", "%s is a synonym of ", WHITE, - triggersTable->GetStringIndex( j ) ); - printFunction(triggersTable,triggersTable->FindValue(triggersTable->GetValueIndex( j ))); - } - } - continue; //we already found an alternative - } - - if (poi == NULL) { - // missing trigger which might be resolved later - triggers[i] = NULL; - triggerflags[i] = 0; - missing_triggers.push_back(j); - continue; - } - triggers[i] = poi->Function; - triggerflags[i] = poi->Flags; - if (was_condition) - triggerflags[i] |= TF_CONDITION; - } - - for (l = missing_triggers.begin(); l!=missing_triggers.end();l++) { - j = *l; - // found later as a different name - int ii = triggersTable->GetValueIndex( j ) & 0x3fff; - if (ii >= MAX_TRIGGERS) { - continue; - } - - TriggerFunction f = triggers[ii]; - if (f) { - for (i = 0; triggernames[i].Name; i++) { - if (f == triggernames[i].Function) { - if (InDebug&ID_TRIGGERS) { - printMessage("GameScript", "%s is a synonym of %s\n", WHITE, - triggersTable->GetStringIndex( j ), triggernames[i].Name ); - break; - } - } - } - continue; - } - - printMessage("GameScript","Couldn't assign function to trigger: ", YELLOW); - printFunction(triggersTable,j); - } - - j = actionsTable->GetSize(); - while (j--) { - i = actionsTable->GetValueIndex( j ); - if (i >= MAX_ACTIONS) { - printMessage("GameScript", "action %d (%s) is too high, ignoring\n", RED, - i, actionsTable->GetStringIndex( j ) ); - continue; - } - const ActionLink* poi = FindAction( actionsTable->GetStringIndex( j )); - if (actions[i]) { - if (poi && actions[i]!=poi->Function) { - printMessage("GameScript", "%s is in collision with ", YELLOW, - actionsTable->GetStringIndex( j ) ); - printFunction(actionsTable, actionsTable->FindValue(actionsTable->GetValueIndex(j))); -//->GetStringIndex(actionsTable->FindValue(actionsTable->GetValueIndex( j )) ) ); - } else { - if (InDebug&ID_ACTIONS) { - printMessage("GameScript", "%s is a synonym of ", WHITE, - actionsTable->GetStringIndex( j ) ); - printFunction(actionsTable, actionsTable->FindValue(actionsTable->GetValueIndex( j ))); -//actionsTable->GetStringIndex(actionsTable->FindValue(actionsTable->GetValueIndex( j )) ) ); - } - } - continue; //we already found an alternative - } - if (poi == NULL) { - actions[i] = NULL; - actionflags[i] = 0; - missing_actions.push_back(j); - continue; - } - actions[i] = poi->Function; - actionflags[i] = poi->Flags; - } - - if (overrideActionsTable) { - /* - * we add/replace some actions from gemact.ids - * right now you can't print or generate these actions! - */ - j = overrideActionsTable->GetSize(); - while (j--) { - i = overrideActionsTable->GetValueIndex( j ); - if (i >= MAX_ACTIONS) { - printMessage("GameScript", "action %d (%s) is too high, ignoring\n", RED, - i, overrideActionsTable->GetStringIndex( j ) ); - continue; - } - const ActionLink *poi = FindAction( overrideActionsTable->GetStringIndex( j )); - if (!poi) { - continue; - } - if (actions[i]) { - printMessage("GameScript", "%s overrides existing action ", WHITE, - overrideActionsTable->GetStringIndex( j ) ); - printFunction( actionsTable, actionsTable->FindValue(overrideActionsTable->GetValueIndex( j ))); - //printFunction( actionsTable->GetStringIndex(actionsTable->FindValue(overrideActionsTable->GetValueIndex( j )) ) ); - } - actions[i] = poi->Function; - actionflags[i] = poi->Flags; - } - } - - for (l = missing_actions.begin(); l!=missing_actions.end();l++) { - j = *l; - // found later as a different name - int ii = actionsTable->GetValueIndex( j ); - if (ii>=MAX_ACTIONS) { - continue; - } - - ActionFunction f = actions[ii]; - if (f) { - for (i = 0; actionnames[i].Name; i++) { - if (f == actionnames[i].Function) { - if (InDebug&ID_ACTIONS) { - printMessage("GameScript", "%s is a synonym of %s\n", WHITE, - actionsTable->GetStringIndex( j ), actionnames[i].Name ); - break; - } - } - } - continue; - } - printMessage("GameScript","Couldn't assign function to action: ", YELLOW); - printFunction(actionsTable,j); - //printFunction(actionsTable->GetStringIndex(j) ); - } - - j = objectsTable->GetSize(); - while (j--) { - i = objectsTable->GetValueIndex( j ); - if (i >= MAX_OBJECTS) { - printMessage("GameScript", "object %d (%s) is too high, ignoring\n", RED, - i, objectsTable->GetStringIndex( j ) ); - continue; - } - const ObjectLink* poi = FindObject( objectsTable->GetStringIndex( j )); - if (objects[i]) { - if (poi && objects[i]!=poi->Function) { - printMessage("GameScript", "%s is in collision with ", YELLOW, - objectsTable->GetStringIndex( j ) ); - printFunction(objectsTable,objectsTable->FindValue(objectsTable->GetValueIndex( j ))); - //printFunction(objectsTable->GetStringIndex(objectsTable->FindValue(objectsTable->GetValueIndex( j )) ) ); - } else { - printMessage("GameScript", "%s is a synonym of ", WHITE, - objectsTable->GetStringIndex( j ) ); - printFunction(objectsTable, objectsTable->FindValue(objectsTable->GetValueIndex( j ))); - //printFunction(objectsTable->GetStringIndex(objectsTable->FindValue(objectsTable->GetValueIndex( j )) ) ); - } - continue; - } - if (poi == NULL) { - objects[i] = NULL; - missing_objects.push_back(j); - } else { - objects[i] = poi->Function; - } - } - - for (l = missing_objects.begin(); l!=missing_objects.end();l++) { - j = *l; - // found later as a different name - int ii = objectsTable->GetValueIndex( j ); - if (ii>=MAX_ACTIONS) { - continue; - } - - ObjectFunction f = objects[ii]; - if (f) { - for (i = 0; objectnames[i].Name; i++) { - if (f == objectnames[i].Function) { - printMessage("GameScript", "%s is a synonym of %s\n", WHITE, - objectsTable->GetStringIndex( j ), objectnames[i].Name ); - break; - } - } - continue; - } - printMessage("GameScript","Couldn't assign function to object: ", YELLOW); - printFunction(objectsTable,j); - //printFunction(objectsTable->GetStringIndex(j) ); - } - - int instantTableIndex = core->LoadSymbol("instant"); - if (instantTableIndex < 0) { - error("GameScript", "Couldn't find instant symbols!\n"); - } - Holder instantTable = core->GetSymbol(instantTableIndex); - if (!instantTable) { - error("GameScript", "Couldn't load instant symbols!\n"); - } - j = instantTable->GetSize(); - while (j--) { - i = instantTable->GetValueIndex( j ); - if (i >= MAX_ACTIONS) { - printMessage("GameScript", "instant action %d (%s) is too high, ignoring\n", RED, - i, instantTable->GetStringIndex( j ) ); - continue; - } - if (!actions[i]) { - printMessage("GameScript", "instant action %d (%s) doesn't exist, ignoring\n", YELLOW, - i, instantTable->GetStringIndex( j ) ); - continue; - } - actionflags[i] |= AF_INSTANT; - } - - int savedTriggersIndex = core->LoadSymbol("svtriobj"); - if (savedTriggersIndex < 0) { - // leaving this as not strictly necessary, for now - printMessage("GameScript", "Couldn't find saved trigger symbols!\n", YELLOW); - } else { - Holder savedTriggersTable = core->GetSymbol(savedTriggersIndex); - if (!savedTriggersTable) { - error("GameScript", "Couldn't laod saved trigger symbols!\n"); - } - j = savedTriggersTable->GetSize(); - while (j--) { - i = savedTriggersTable->GetValueIndex( j ); - i &= 0x3fff; - if (i >= MAX_ACTIONS) { - printMessage("GameScript", "saved trigger %d (%s) is too high, ignoring\n", RED, - i, savedTriggersTable->GetStringIndex( j ) ); - continue; - } - if (!triggers[i]) { - printMessage("GameScript", "saved trigger %d (%s) doesn't exist, ignoring\n", YELLOW, - i, savedTriggersTable->GetStringIndex( j ) ); - continue; - } - triggerflags[i] |= TF_SAVED; - } - } -} - -/********************** GameScript *******************************/ -GameScript::GameScript(const ieResRef ResRef, Scriptable* MySelf, - int ScriptLevel, bool AIScript) - : MySelf(MySelf) -{ - scriptlevel = ScriptLevel; - lastAction = (unsigned int) ~0; - - strnlwrcpy( Name, ResRef, 8 ); - - script = CacheScript( Name, AIScript); -} - -GameScript::~GameScript(void) -{ - if (script) { - //set 3. parameter to true if you want instant free - //and possible death - if (InDebug&ID_REFERENCE) { - print("One instance of %s is dropped from %d.\n", Name, BcsCache.RefCount(Name) ); - } - int res = BcsCache.DecRef(script, Name, true); - - if (res<0) { - error("GameScript", "Corrupted Script cache encountered (reference count went below zero), Script name is: %.8s\n", Name); - } - if (!res) { - //print("Freeing script %s because its refcount has reached 0.\n", Name); - script->Release(); - } - script = NULL; - } -} - -Script* GameScript::CacheScript(ieResRef ResRef, bool AIScript) -{ - char line[10]; - - SClass_ID type = AIScript ? IE_BS_CLASS_ID : IE_BCS_CLASS_ID; - - Script *newScript = (Script *) BcsCache.GetResource(ResRef); - if ( newScript ) { - if (InDebug&ID_REFERENCE) { - print("Caching %s for the %d. time\n", ResRef, BcsCache.RefCount(ResRef) ); - } - return newScript; - } - - DataStream* stream = gamedata->GetResource( ResRef, type ); - if (!stream) { - return NULL; - } - stream->ReadLine( line, 10 ); - if (strncmp( line, "SC", 2 ) != 0) { - printMessage( "GameScript","Not a Compiled Script file\n", YELLOW ); - delete( stream ); - return NULL; - } - newScript = new Script( ); - BcsCache.SetAt( ResRef, (void *) newScript ); - if (InDebug&ID_REFERENCE) { - print("Caching %s for the %d. time\n", ResRef, BcsCache.RefCount(ResRef) ); - } - - while (true) { - ResponseBlock* rB = ReadResponseBlock( stream ); - if (!rB) - break; - newScript->responseBlocks.push_back( rB ); - stream->ReadLine( line, 10 ); - } - delete( stream ); - return newScript; -} - -static int ParseInt(const char*& src) -{ - char number[33]; - - char* tmp = number; - while (isdigit(*src) || *src=='-') { - *tmp = *src; - tmp++; - src++; - } - *tmp = 0; - if (*src) - src++; - return atoi( number ); -} - -static void ParseString(const char*& src, char* tmp) -{ - while (*src != '"' && *src) { - *tmp = *src; - tmp++; - src++; - } - *tmp = 0; - if (*src) - src++; -} - -static Object* DecodeObject(const char* line) -{ - int i; - const char *origline = line; // for debug below - - Object* oB = new Object(); - for (i = 0; i < ObjectFieldsCount; i++) { - oB->objectFields[i] = ParseInt( line ); - } - for (i = 0; i < MaxObjectNesting; i++) { - oB->objectFilters[i] = ParseInt( line ); - } - //iwd tolerates the missing rectangle, so we do so too - if (HasAdditionalRect && (*line=='[') ) { - line++; //Skip [ - for (i = 0; i < 4; i++) { - oB->objectRect[i] = ParseInt( line ); - } - if (*line == ' ') - line++; //Skip ] (not really... it skips a ' ' since the ] was skipped by the ParseInt function - } - if (*line == '"') - line++; //Skip " - ParseString( line, oB->objectName ); - if (*line == '"') - line++; //Skip " (the same as above) - //this seems to be needed too - if (ExtraParametersCount && *line) { - line++; - } - for (i = 0; i < ExtraParametersCount; i++) { - oB->objectFields[i + ObjectFieldsCount] = ParseInt( line ); - } - if (*line != 'O' || *(line + 1) != 'B') { - printMessage("GameScript", "Got confused parsing object line: %s\n", YELLOW, origline); - } - //let the object realize it has no future (in case of null objects) - if (oB->isNull()) { - oB->Release(); - return NULL; - } - return oB; -} - -static Trigger* ReadTrigger(DataStream* stream) -{ - char* line = ( char* ) malloc( 1024 ); - stream->ReadLine( line, 1024 ); - if (strncmp( line, "TR", 2 ) != 0) { - free( line ); - return NULL; - } - stream->ReadLine( line, 1024 ); - Trigger* tR = new Trigger(); - //this exists only in PST? - if (HasTriggerPoint) { - sscanf( line, "%hu %d %d %d %d [%hd,%hd] \"%[^\"]\" \"%[^\"]\" OB", - &tR->triggerID, &tR->int0Parameter, &tR->flags, - &tR->int1Parameter, &tR->int2Parameter, &tR->pointParameter.x, - &tR->pointParameter.y, tR->string0Parameter, tR->string1Parameter ); - } else { - sscanf( line, "%hu %d %d %d %d \"%[^\"]\" \"%[^\"]\" OB", - &tR->triggerID, &tR->int0Parameter, &tR->flags, - &tR->int1Parameter, &tR->int2Parameter, tR->string0Parameter, - tR->string1Parameter ); - } - strlwr(tR->string0Parameter); - strlwr(tR->string1Parameter); - tR->triggerID &= 0x3fff; - stream->ReadLine( line, 1024 ); - tR->objectParameter = DecodeObject( line ); - stream->ReadLine( line, 1024 ); - free( line ); - return tR; -} - -static Condition* ReadCondition(DataStream* stream) -{ - char line[10]; - - stream->ReadLine( line, 10 ); - if (strncmp( line, "CO", 2 ) != 0) { - return NULL; - } - Condition* cO = new Condition(); - while (true) { - Trigger* tR = ReadTrigger( stream ); - if (!tR) - break; - cO->triggers.push_back( tR ); - } - return cO; -} - -/* - * if you pass non-NULL parameters, continuing is set to whether we Continue()ed - * (should start false and be passed to next script's Update), - * and done is set to whether we processed a block without Continue() - */ -bool GameScript::Update(bool *continuing, bool *done) -{ - if (!MySelf) - return false; - - if (!script) - return false; - - //ieDword thisTime = core->GetGame()->Ticks; - //if (( thisTime - lastRunTime ) < scriptRunDelay) { - // return false; - //} - - //lastRunTime = thisTime; - - if(!(MySelf->GetInternalFlag()&IF_ACTIVE) ) { - return false; - } - - bool continueExecution = false; - if (continuing) continueExecution = *continuing; - - RandomNumValue=rand(); - for (size_t a = 0; a < script->responseBlocks.size(); a++) { - ResponseBlock* rB = script->responseBlocks[a]; - if (rB->condition->Evaluate(MySelf)) { - //if this isn't a continue-d block, we have to clear the queue - //we cannot clear the queue and cannot execute the new block - //if we already have stuff on the queue! - if (!continueExecution) { - if (MySelf->GetCurrentAction() || MySelf->GetNextAction()) { - if (MySelf->GetInternalFlag()&IF_NOINT) { - // we presumably don't want any further execution? - if (done) *done = true; - return false; - } - - if (lastAction==a) { - // we presumably don't want any further execution? - // this one is a bit more complicated, due to possible - // interactions with Continue() (lastAction here is always - // the first block encountered), needs more testing - //if (done) *done = true; - return false; - } - - //movetoobjectfollow would break if this isn't called - //(what is broken if it is here?) - MySelf->ClearActions(); - //IE even clears the path, shall we? - //yes we must :) - if (MySelf->Type == ST_ACTOR) { - ((Movable *)MySelf)->ClearPath(); - } - } - lastAction=a; - } - continueExecution = ( rB->responseSet->Execute(MySelf) != 0); - if (continuing) *continuing = continueExecution; - if (!continueExecution) { - if (done) *done = true; - return true; - } - } - } - return continueExecution; -} - -//IE simply takes the first action's object for cutscene object -//then adds these actions to its queue: -// SetInterrupt(false), , SetInterrupt(true) - -void GameScript::EvaluateAllBlocks() -{ - if (!MySelf || !(MySelf->GetInternalFlag()&IF_ACTIVE) ) { - return; - } - - if (!script) { - return; - } - -#ifdef GEMRB_CUTSCENES - // this is the (unused) more logical way of executing a cutscene, which - // evaluates conditions and doesn't just use the first response - for (size_t a = 0; a < script->responseBlocks.size(); a++) { - ResponseBlock* rB = script->responseBlocks[a]; - if (rB->Condition->Evaluate(MySelf)) { - // TODO: this no longer works since the cutscene changes - rB->Execute(MySelf); - } - } -#else - // this is the original IE behaviour: - // cutscenes don't evaluate conditions - they just choose the - // first response, take the object from the first action, - // and then add the actions to that object's queue. - for (size_t a = 0; a < script->responseBlocks.size(); a++) { - ResponseBlock* rB = script->responseBlocks[a]; - ResponseSet * rS = rB->responseSet; - if (rS->responses.size()) { - Response *response = rS->responses[0]; - if (response->actions.size()) { - Action *action = response->actions[0]; - Scriptable *target = GetActorFromObject(MySelf, action->objects[1]); - if (target) { - // TODO: sometimes SetInterrupt(false) and SetInterrupt(true) are added before/after? - rS->responses[0]->Execute(target); - // TODO: this will break blocking instants, if there are any - target->ReleaseCurrentAction(); - } else if ((InDebug&ID_CUTSCENE) || !action->objects[1]) { - printMessage("GameScript","Failed to find CutSceneID target!\n",YELLOW); - if (action->objects[1]) { - action->objects[1]->Dump(); - } - } - } - } - } -#endif -} - -ResponseBlock* GameScript::ReadResponseBlock(DataStream* stream) -{ - char line[10]; - - stream->ReadLine( line, 10 ); - if (strncmp( line, "CR", 2 ) != 0) { - return NULL; - } - ResponseBlock* rB = new ResponseBlock(); - rB->condition = ReadCondition( stream ); - rB->responseSet = ReadResponseSet( stream ); - return rB; -} - -ResponseSet* GameScript::ReadResponseSet(DataStream* stream) -{ - char line[10]; - - stream->ReadLine( line, 10 ); - if (strncmp( line, "RS", 2 ) != 0) { - return NULL; - } - ResponseSet* rS = new ResponseSet(); - while (true) { - Response* rE = ReadResponse( stream ); - if (!rE) - break; - rS->responses.push_back( rE ); - } - return rS; -} - -//this is the border of the GameScript object (all subsequent functions are library functions) -//we can't make this a library function, because scriptlevel is set here -Response* GameScript::ReadResponse(DataStream* stream) -{ - char* line = ( char* ) malloc( 1024 ); - stream->ReadLine( line, 1024 ); - if (strncmp( line, "RE", 2 ) != 0) { - free( line ); - return NULL; - } - Response* rE = new Response(); - rE->weight = 0; - stream->ReadLine( line, 1024 ); - char *poi; - rE->weight = (unsigned char)strtoul(line,&poi,10); - if (strncmp(poi,"AC",2)==0) - while (true) { - //not autofreed, because it is referenced by the Script - Action* aC = new Action(false); - stream->ReadLine( line, 1024 ); - aC->actionID = (unsigned short)strtoul(line, NULL,10); - for (int i = 0; i < 3; i++) { - stream->ReadLine( line, 1024 ); - Object* oB = DecodeObject( line ); - aC->objects[i] = oB; - if (i != 2) - stream->ReadLine( line, 1024 ); - } - stream->ReadLine( line, 1024 ); - sscanf( line, "%d %hd %hd %d %d\"%[^\"]\" \"%[^\"]\" AC", - &aC->int0Parameter, &aC->pointParameter.x, &aC->pointParameter.y, - &aC->int1Parameter, &aC->int2Parameter, aC->string0Parameter, - aC->string1Parameter ); - strlwr(aC->string0Parameter); - strlwr(aC->string1Parameter); - if (aC->actionID>=MAX_ACTIONS) { - aC->actionID=0; - printMessage("GameScript","Invalid script action ID!",LIGHT_RED); - } else { - if (actionflags[aC->actionID] & AF_SCRIPTLEVEL) { - aC->int0Parameter = scriptlevel; - } - } - rE->actions.push_back( aC ); - stream->ReadLine( line, 1024 ); - if (strncmp( line, "RE", 2 ) == 0) - break; - } - free( line ); - return rE; -} - -void GameScript::ExecuteString(Scriptable* Sender, char* String) -{ - if (String[0] == 0) { - return; - } - Action* act = GenerateAction( String ); - if (!act) { - return; - } - Sender->AddActionInFront(act); -} - -//This must return integer because Or(3) returns 3 -int GameScript::EvaluateString(Scriptable* Sender, char* String) -{ - if (String[0] == 0) { - return 0; - } - Trigger* tri = GenerateTrigger( String ); - if (tri) { - int ret = tri->Evaluate(Sender); - tri->Release(); - return ret; - } - return 0; -} - -bool Condition::Evaluate(Scriptable* Sender) -{ - int ORcount = 0; - unsigned int result = 0; - bool subresult = true; - - for (size_t i = 0; i < triggers.size(); i++) { - Trigger* tR = triggers[i]; - //do not evaluate triggers in an Or() block if one of them - //was already True() - if (!ORcount || !subresult) { - result = tR->Evaluate(Sender); - } - if (result > 1) { - //we started an Or() block - if (ORcount) { - printMessage( "GameScript","Unfinished OR block encountered!\n",YELLOW ); - } - ORcount = result; - subresult = false; - continue; - } - if (ORcount) { - subresult |= ( result != 0 ); - if (--ORcount) { - continue; - } - result = subresult; - } - if (!result) { - return 0; - } - } - if (ORcount) { - printMessage( "GameScript","Unfinished OR block encountered!\n",YELLOW ); - } - return 1; -} - -/* this may return more than a boolean, in case of Or(x) */ -int Trigger::Evaluate(Scriptable* Sender) -{ - if (!this) { - printMessage( "GameScript","Trigger evaluation fails due to NULL trigger.\n",LIGHT_RED ); - return 0; - } - TriggerFunction func = triggers[triggerID]; - const char *tmpstr=triggersTable->GetValue(triggerID); - if (!tmpstr) { - tmpstr=triggersTable->GetValue(triggerID|0x4000); - } - if (!func) { - triggers[triggerID] = GameScript::False; - printMessage("GameScript"," ",YELLOW); - print("Unhandled trigger code: 0x%04x %s\n", - triggerID, tmpstr ); - return 0; - } - if (InDebug&ID_TRIGGERS) { - printMessage("GameScript"," ",YELLOW); - print( "Executing trigger code: 0x%04x %s\n", - triggerID, tmpstr ); - } - int ret = func( Sender, this ); - if (flags & NEGATE_TRIGGER) { - return !ret; - } - return ret; -} - -int ResponseSet::Execute(Scriptable* Sender) -{ - size_t i; - - switch(responses.size()) { - case 0: - return 0; - case 1: - return responses[0]->Execute(Sender); - } - /*default*/ - int randWeight; - int maxWeight = 0; - - for (i = 0; i < responses.size(); i++) { - maxWeight += responses[i]->weight; - } - if (maxWeight) { - randWeight = rand() % maxWeight; - } - else { - randWeight = 0; - } - - for (i = 0; i < responses.size(); i++) { - Response* rE = responses[i]; - if (rE->weight > randWeight) { - return rE->Execute(Sender); - /* this break is only symbolic */ - break; - } - randWeight-=rE->weight; - } - return 0; -} - -//continue is effective only as the last action in the block -int Response::Execute(Scriptable* Sender) -{ - int ret = 0; // continue or not - for (size_t i = 0; i < actions.size(); i++) { - Action* aC = actions[i]; - switch (actionflags[aC->actionID] & AF_MASK) { - case AF_IMMEDIATE: - GameScript::ExecuteAction( Sender, aC ); - ret = 0; - break; - case AF_NONE: - Sender->AddAction( aC ); - ret = 0; - break; - case AF_CONTINUE: - case AF_MASK: - ret = 1; - break; - } - } - return ret; -} - -void PrintAction(int actionID) -{ - print("Action: %d %s\n", actionID , actionsTable->GetValue(actionID) ); -} - -void GameScript::ExecuteAction(Scriptable* Sender, Action* aC) -{ - int actionID = aC->actionID; - - if (aC->objects[0]) { - Scriptable *scr = GetActorFromObject(Sender, aC->objects[0]); - - aC->IncRef(); // if aC is us, we don't want it deleted! - Sender->ReleaseCurrentAction(); - - if (scr) { - if (InDebug&ID_ACTIONS) { - printMessage("GameScript", "Sender: %s-->override: %s\n", YELLOW, - Sender->GetScriptName(), scr->GetScriptName() ); - } - scr->ReleaseCurrentAction(); - scr->AddAction(ParamCopyNoOverride(aC)); - if (!(actionflags[actionID] & AF_INSTANT)) { - assert(scr->GetNextAction()); - // TODO: below was written before i added instants, this might be unnecessary now - - // there are plenty of places where it's vital that ActionOverride is not interrupted and if - // there are actions left on the queue after the release above, we can't instant-execute, - // so this is my best guess for now.. - scr->CurrentActionInterruptable = false; - } - } else { - printMessage("GameScript","Actionoverride failed for object: \n",LIGHT_RED); - aC->objects[0]->Dump(); - } - - aC->Release(); - return; - } - if (InDebug&ID_ACTIONS) { - printMessage("GameScript"," ",YELLOW); - PrintAction(actionID); - print("Sender: %s\n",Sender->GetScriptName() ); - } - ActionFunction func = actions[actionID]; - if (func) { - //turning off interruptable flag - //uninterruptable actions will set it back - if (Sender->Type==ST_ACTOR) { - Sender->Activate(); - if (actionflags[actionID]&AF_ALIVE) { - if (Sender->GetInternalFlag()&IF_STOPATTACK) { - printMessage("GameScript", "Aborted action due to death\n", YELLOW); - Sender->ReleaseCurrentAction(); - return; - } - } - } - func( Sender, aC ); - } else { - actions[actionID] = NoActionAtAll; - printMessage("GameScript", "Unknown ", YELLOW); - textcolor(YELLOW); - PrintAction(actionID); - Sender->ReleaseCurrentAction(); - textcolor(WHITE); - return; - } - - //don't bother with special flow control actions - if (actionflags[actionID] & AF_IMMEDIATE) { - //this action never entered the action queue, therefore shouldn't be freed - if (aC->GetRef()!=1) { - print("Immediate action got queued!\n"); - PrintAction(actionID); - abort(); - } - return; - } - - //Releasing nonblocking actions, blocking actions will release themselves - if (!( actionflags[actionID] & AF_BLOCKING )) { - Sender->ReleaseCurrentAction(); - //aC is invalid beyond this point, so we return! - return; - } -} - -Trigger* GenerateTrigger(char* String) -{ - strlwr( String ); - if (InDebug&ID_TRIGGERS) { - printMessage("GameScript", "Compiling:%s\n", YELLOW, String); - } - int negate = 0; - if (*String == '!') { - String++; - negate = 1; - } - int len = strlench(String,'(')+1; //including ( - int i = triggersTable->FindString(String, len); - if (i<0) { - printMessage("GameScript", "Invalid scripting trigger: %s\n", LIGHT_RED, String); - return NULL; - } - char *src = String+len; - char *str = triggersTable->GetStringIndex( i )+len; - Trigger *trigger = GenerateTriggerCore(src, str, i, negate); - if (!trigger) { - printMessage("GameScript", "Malformed scripting trigger: %s\n", LIGHT_RED, String); - return NULL; - } - return trigger; -} - -Action* GenerateAction(char* String) -{ - strlwr( String ); - if (InDebug&ID_ACTIONS) { - printMessage("GameScript", "Compiling:%s\n", YELLOW, String); - } - int len = strlench(String,'(')+1; //including ( - char *src = String+len; - int i = -1; - char *str; - unsigned short actionID; - if (overrideActionsTable) { - i = overrideActionsTable->FindString(String, len); - if (i >= 0) { - str = overrideActionsTable->GetStringIndex( i )+len; - actionID = overrideActionsTable->GetValueIndex(i); - } - } - if (i<0) { - i = actionsTable->FindString(String, len); - if (i < 0) { - printMessage("GameScript", "Invalid scripting action: %s\n", LIGHT_RED, String); - return NULL; - } - str = actionsTable->GetStringIndex( i )+len; - actionID = actionsTable->GetValueIndex(i); - } - Action *action = GenerateActionCore( src, str, actionID); - if (!action) { - printMessage("GameScript", "Malformed scripting action: %s\n", LIGHT_RED, String); - return NULL; - } - return action; -} - -Action* GenerateActionDirect(char *String, Scriptable *object) -{ - Action* action = GenerateAction(String); - Object *tmp = action->objects[1]; - if (tmp && tmp->objectFields[0]==-1) { - tmp->objectFields[1] = object->GetGlobalID(); - } - action->pointParameter.empty(); - return action; -} - -/** Return true if object is null */ -bool Object::isNull() -{ - if (objectName[0]!=0) { - return false; - } - if (objectFilters[0]) { - return false; - } - for (int i=0;i -#include - -class Action; -class GameScript; - -//escapearea flags -#define EA_DESTROY 1 //destroy actor at the exit (otherwise move to new place) -#define EA_NOSEE 2 //no need to see the exit - -//displaystring flags -#define DS_WAIT 1 -#define DS_HEAD 2 -#define DS_CONSOLE 4 -#define DS_CONST 8 -#define DS_NONAME 16 -#define DS_SILENT 32 -#define DS_SPEECH 64 -#define DS_AREA 128 - -//verbal constant (bg2), we need a lookup table for other games -#define VB_PANIC 1 -#define VB_HAPPY 2 -#define VB_UNHAPPY 3 -#define VB_LEADER 6 -#define VB_TIRED 7 -#define VB_BORED 8 -#define VB_ATTACK 9 -#define VB_DAMAGE 18 -#define VB_DIE 19 -#define VB_SELECT 26 -#define VB_INSULT 44 -#define VB_COMPLIMENT 47 -#define VB_SPECIAL 50 -#define VB_REACT 53 -#define VB_REACT_S 54 -#define VB_RESP_COMP 55 -#define VB_RESP_INS 58 -#define VB_HOSTILE 59 -#define VB_DIALOG 60 -#define VB_CRITHIT 65 -#define VB_CRITMISS 66 -#define VB_TIMMUNE 67 -#define VB_INVENTORY 68 -#define VB_PP_SUCC 69 -#define VB_BIO 74 - -//diffmode (iwd2) -#define DM_EQUAL 1 -#define DM_LESS 2 -#define DM_GREATER 3 - -//markspellandobject (iwd2) -#define MSO_IGNORE_SEE 1 -#define MSO_IGNORE_INVALID 2 -#define MSO_RANDOM_SPELL 4 -#define MSO_IGNORE_HAVE 8 -#define MSO_IGNORE_RANGE 16 -#define MSO_IGNORE_NULL 32 - -//delta (pst) -#define DM_LOWER 1 -#define DM_RAISE 2 -#define DM_SET 3 - -//attack core flags -#define AC_NO_SOUND 1 -#define AC_RUNNING 2 - -//trigger flags stored in triggers in .bcs files -#define NEGATE_TRIGGER 1 - -#define MAX_OBJECT_FIELDS 10 -#define MAX_NESTING 5 - -#define GSASSERT(f,c) \ - if(!(f)) \ - { \ - print("Assertion failed: %s [0x%08lX] Line %d",#f, c, __LINE__); \ - abort(); \ - } - -typedef std::vector SrcVector; - -struct targettype { - Scriptable *actor; //hmm, could be door - unsigned int distance; -}; - -typedef std::list targetlist; - -class GEM_EXPORT Targets { -public: - Targets() - { - } - - ~Targets() - { - Clear(); - } -private: - targetlist objects; -public: - int Count() const; - targettype *RemoveTargetAt(targetlist::iterator &m); - const targettype *GetNextTarget(targetlist::iterator &m, int Type); - const targettype *GetLastTarget(int Type); - const targettype *GetFirstTarget(targetlist::iterator &m, int Type); - Scriptable *GetTarget(unsigned int index, int Type); - void AddTarget(Scriptable* target, unsigned int distance, int flags); - void Clear(); -}; - -class GEM_EXPORT Object { -public: - Object() - { - memset( objectName, 0, 65 ); - - memset( objectFields, 0, MAX_OBJECT_FIELDS * sizeof( int ) ); - memset( objectFilters, 0, MAX_NESTING * sizeof( int ) ); - memset( objectRect, 0, 4 * sizeof( int ) ); - - canary = (unsigned long) 0xdeadbeef; - } - ~Object() - { - } -public: - int objectFields[MAX_OBJECT_FIELDS]; - int objectFilters[MAX_NESTING]; - int objectRect[4]; - char objectName[65]; -private: - volatile unsigned long canary; -public: - void Dump() - { - int i; - - GSASSERT( canary == (unsigned long) 0xdeadbeef, canary ); - if(objectName[0]) { - print("Object: %s\n",objectName); - return; - } - print("IDS Targeting: "); - for(i=0;iRelease(); - objectParameter = NULL; - } - } - int Evaluate(Scriptable* Sender); -public: - unsigned short triggerID; - int int0Parameter; - int flags; - int int1Parameter; - int int2Parameter; - Point pointParameter; - char string0Parameter[65]; - char string1Parameter[65]; - Object* objectParameter; -private: - volatile unsigned long canary; -public: - void Dump() - { - GSASSERT( canary == (unsigned long) 0xdeadbeef, canary ); - print ("Trigger: %d\n", triggerID); - print ("Int parameters: %d %d %d\n", int0Parameter, int1Parameter, int2Parameter); - print ("Point: [%d.%d]\n", pointParameter.x, pointParameter.y); - print ("String0: %s\n", string0Parameter); - print ("String1: %s\n", string1Parameter); - if (objectParameter) { - objectParameter->Dump(); - } else { - print("No object\n"); - } - print("\n"); - } - - void Release() - { - GSASSERT( canary == (unsigned long) 0xdeadbeef, canary ); - canary = 0xdddddddd; - delete this; - } -}; - -class GEM_EXPORT Condition { -public: - Condition() - { - canary = (unsigned long) 0xdeadbeef; - } - ~Condition() - { - for (size_t c = 0; c < triggers.size(); ++c) { - if (triggers[c]) { - triggers[c]->Release(); - triggers[c] = NULL; - } - } - } - bool Evaluate(Scriptable* Sender); -public: - std::vector triggers; -private: - volatile unsigned long canary; -public: - void Release() - { - GSASSERT( canary == (unsigned long) 0xdeadbeef, canary ); - canary = 0xdddddddd; - delete this; - } -}; - -class GEM_EXPORT Action { -public: - Action(bool autoFree) - { - actionID = 0; - objects[0] = NULL; - objects[1] = NULL; - objects[2] = NULL; - memset(string0Parameter, 0, 65); - memset(string1Parameter, 0, 65); - int0Parameter = 0; - pointParameter.null(); - int1Parameter = 0; - int2Parameter = 0; - //changed now - if (autoFree) { - RefCount = 0; //refcount will be increased by each AddAction - } else { - RefCount = 1; //one reference hold by the script - } - canary = (unsigned long) 0xdeadbeef; - } - ~Action() - { - for (int c = 0; c < 3; c++) { - if (objects[c]) { - objects[c]->Release(); - objects[c] = NULL; - } - } - } -public: - unsigned short actionID; - Object* objects[3]; - int int0Parameter; - Point pointParameter; - int int1Parameter; - int int2Parameter; - char string0Parameter[65]; - char string1Parameter[65]; -private: - int RefCount; - volatile unsigned long canary; -public: - int GetRef() { - return RefCount; - } - void Dump() - { - int i; - - GSASSERT( canary == (unsigned long) 0xdeadbeef, canary ); - print("Int0: %d, Int1: %d, Int2: %d\n",int0Parameter, int1Parameter, int2Parameter); - print("String0: %s, String1: %s\n", string0Parameter?string0Parameter:"", string1Parameter?string1Parameter:""); - for (i=0;i<3;i++) { - if (objects[i]) { - print( "%d. ",i+1); - objects[i]->Dump(); - } else { - print( "%d. Object - NULL\n",i+1); - } - } - - print("RefCount: %d\n", RefCount); - } - - void Release() - { - GSASSERT( canary == (unsigned long) 0xdeadbeef, canary ); - if (!RefCount) { - print( "WARNING!!! Double Freeing in %s: Line %d\n", __FILE__, - __LINE__ ); - abort(); - } - RefCount--; - if (!RefCount) { - canary = 0xdddddddd; - delete this; - } - } - void IncRef() - { - GSASSERT( canary == (unsigned long) 0xdeadbeef, canary ); - RefCount++; - if (RefCount >= 65536) { - print( "Refcount increased to: %d in action %d\n", RefCount, - actionID ); - abort(); - } - } -}; - -class GEM_EXPORT Response { -public: - Response() - { - weight = 0; - canary = (unsigned long) 0xdeadbeef; - } - ~Response() - { - for (size_t c = 0; c < actions.size(); c++) { - if (actions[c]) { - if (actions[c]->GetRef()>2) { - print("Residue action %d with refcount %d\n", actions[c]->actionID, actions[c]->GetRef()); - } - actions[c]->Release(); - actions[c] = NULL; - } - } - } - int Execute(Scriptable* Sender); -public: - unsigned char weight; - std::vector actions; -private: - volatile unsigned long canary; -public: - void Release() - { - GSASSERT( canary == (unsigned long) 0xdeadbeef, canary ); - canary = 0xdddddddd; - delete this; - } -}; - -class GEM_EXPORT ResponseSet { -public: - ResponseSet() - { - canary = (unsigned long) 0xdeadbeef; - } - ~ResponseSet() - { - for (size_t b = 0; b < responses.size(); b++) { - responses[b]->Release(); - responses[b] = NULL; - } - } - int Execute(Scriptable* Sender); -public: - std::vector responses; -private: - volatile unsigned long canary; -public: - void Release() - { - GSASSERT( canary == (unsigned long) 0xdeadbeef, canary ); - canary = 0xdddddddd; - delete this; - } -}; - -class GEM_EXPORT ResponseBlock { -public: - ResponseBlock() - { - condition = NULL; - responseSet = NULL; - canary = (unsigned long) 0xdeadbeef; - } - ~ResponseBlock() - { - if (condition) { - condition->Release(); - condition = NULL; - } - if (responseSet) { - responseSet->Release(); - responseSet = NULL; - } - } -public: - Condition* condition; - ResponseSet* responseSet; -private: - volatile unsigned long canary; -public: - void Release() - { - GSASSERT( canary == (unsigned long) 0xdeadbeef, canary ); - canary = 0xdddddddd; - delete this; - } -}; - -class GEM_EXPORT Script { -public: - Script() - { - canary = (unsigned long) 0xdeadbeef; - } - ~Script() - { - for (unsigned int i = 0; i < responseBlocks.size(); i++) { - if (responseBlocks[i]) { - responseBlocks[i]->Release(); - responseBlocks[i] = NULL; - } - } - } -public: - std::vector responseBlocks; -private: - volatile unsigned long canary; -public: - void Release() - { - GSASSERT( canary == (unsigned long) 0xdeadbeef, canary ); - canary = 0xdddddddd; - delete this; - } -}; - -typedef int (* TriggerFunction)(Scriptable*, Trigger*); -typedef void (* ActionFunction)(Scriptable*, Action*); -typedef Targets* (* ObjectFunction)(Scriptable *, Targets*, int ga_flags); -typedef int (* IDSFunction)(Actor *, int parameter); - -#define TF_NONE 0 -#define TF_CONDITION 1 //this isn't a trigger, just a condition (0x4000) -#define TF_SAVED 2 //trigger is in svtriobj.ids -#define TF_MERGESTRINGS 8 //same value as actions' mergestring - -struct TriggerLink { - const char* Name; - TriggerFunction Function; - short Flags; -}; - -//createcreature flags -#define CC_OFFSET 1 -#define CC_OBJECT 2 -#define CC_OFFSCREEN 3 -#define CC_MASK 3 -#define CC_CHECK_IMPASSABLE 4 //adjust position (searchmap) -#define CC_PLAY_ANIM 8 //play animation -#define CC_STRING1 16 //resref is in second string -#define CC_CHECK_OVERLAP 32 //other actors -#define CC_COPY 64 //copy appearance -#define CC_SCRIPTNAME 128 //scriptname in 2nd string - -//begindialog flags -#define BD_STRING0 0 -#define BD_TARGET 1 -#define BD_SOURCE 2 -#define BD_RESERVED 3 //playerX resref -#define BD_INTERACT 4 //banter dialogs -#define BD_LOCMASK 7 //where is the dialog resref -#define BD_TALKCOUNT 8 //increases talkcount -#define BD_SETDIALOG 16 //also sets dialog (for string0) -#define BD_CHECKDIST 32 //checks distance, if needs, walks up -#define BD_OWN 64 //source == target, works for player only -#define BD_INTERRUPT 128 //interrupts action -#define BD_NUMERIC 256 //target is numeric -#define BD_ITEM 512 //talk to an item -#define BD_NOEMPTY 1024 //don't display '... has nothing to say to you' - -#define AF_NONE 0 -#define AF_IMMEDIATE 1 -#define AF_CONTINUE 2 -#define AF_MASK 3 //none, immediate or continue -#define AF_BLOCKING 4 -#define AF_MERGESTRINGS 8 -//we could use this flag to restrict player scripts from using dangerous -//opcodes, it would be a very useful and easy to implement feature! -#define AF_RESTRICTED 16 -//#define AF_RESTRICTED_LEVEL2 32 //maybe we could use 2 bits for this??? -#define AF_SCRIPTLEVEL 64 //this hack will transfer scriptlevel to int0parameter at runtime (changecurrentscript relies on it) -#define AF_INVALID 128 -#define AF_DIRECT 256 //this hack will transfer target from gamecontrol to object1 at compile time -#define AF_ALIVE 512 //only alive actors can do this -#define AF_INSTANT 1024 - -struct ActionLink { - const char* Name; - ActionFunction Function; - short Flags; -}; - -struct ObjectLink { - const char* Name; - ObjectFunction Function; -}; - -struct IDSLink { - const char* Name; - IDSFunction Function; -}; - -#define MAX_TRIGGERS 0xFF -#define MAX_ACTIONS 400 -#define MAX_OBJECTS 128 -#define AI_SCRIPT_LEVEL 4 //the script level of special ai scripts - -extern void SetScriptDebugMode(int arg); -extern int RandomNumValue; - -class GEM_EXPORT GameScript { -public: - GameScript(const ieResRef ResRef, Scriptable* Myself, - int ScriptLevel = 0, bool AIScript = false); - ~GameScript(); - const char *GetName() { return this?Name:"NONE\0\0\0\0"; } - static void ExecuteString(Scriptable* Sender, char* String); - static int EvaluateString(Scriptable* Sender, char* String); - static void ExecuteAction(Scriptable* Sender, Action* aC); -public: - bool Update(bool *continuing = NULL, bool *done = NULL); - void EvaluateAllBlocks(); -private: //Internal Functions - Script* CacheScript(ieResRef ResRef, bool AIScript); - ResponseBlock* ReadResponseBlock(DataStream* stream); - ResponseSet* ReadResponseSet(DataStream* stream); - Response* ReadResponse(DataStream* stream); - Trigger* ReadTrigger(DataStream* stream); - static int ParseInt(const char*& src); - static void ParseString(const char*& src, char* tmp); -private: //Internal variables - Scriptable* const MySelf; - ieResRef Name; - Script* script; - unsigned int lastAction; - int scriptlevel; -public: //Script Functions - static int ID_Alignment(Actor *actor, int parameter); - static int ID_Allegiance(Actor *actor, int parameter); - static int ID_AVClass(Actor *actor, int parameter); - static int ID_Class(Actor *actor, int parameter); - static int ID_ClassMask(Actor *actor, int parameter); - static int ID_Faction(Actor *actor, int parameter); - static int ID_Gender(Actor *actor, int parameter); - static int ID_General(Actor *actor, int parameter); - static int ID_Race(Actor *actor, int parameter); - static int ID_Specific(Actor *actor, int parameter); - static int ID_Subrace(Actor *actor, int parameter); - static int ID_Team(Actor *actor, int parameter); - - //Triggers - static int ActionListEmpty(Scriptable* Sender, Trigger* parameters); - static int ActuallyInCombat(Scriptable* Sender, Trigger* parameters); - static int Acquired(Scriptable* Sender, Trigger* parameters); - static int Alignment(Scriptable* Sender, Trigger* parameters); - static int Allegiance(Scriptable* Sender, Trigger* parameters); - static int AnimationID(Scriptable* Sender, Trigger* parameters); - static int AnimState(Scriptable* Sender, Trigger* parameters); - static int AnyPCOnMap(Scriptable* Sender, Trigger* parameters); - static int AnyPCSeesEnemy(Scriptable* Sender, Trigger* parameters); - static int AreaCheck(Scriptable* Sender, Trigger* parameter); - static int AreaCheckObject(Scriptable* Sender, Trigger* parameter); - static int AreaFlag(Scriptable* Sender, Trigger* parameter); - static int AreaRestDisabled(Scriptable* Sender, Trigger* parameter); - static int AreaStartsWith(Scriptable* Sender, Trigger* parameter); //InWatchersKeep - static int AreaType(Scriptable* Sender, Trigger* parameter); - static int AtLocation(Scriptable* Sender, Trigger* parameter); - static int AttackedBy(Scriptable* Sender, Trigger* parameters); - static int BecameVisible(Scriptable* Sender, Trigger* parameters); - static int BitCheck(Scriptable* Sender, Trigger* parameters); - static int BitCheckExact(Scriptable* Sender, Trigger* parameters); - static int BitGlobal_Trigger(Scriptable* Sender, Trigger* parameters); - static int BreakingPoint(Scriptable* Sender, Trigger* parameters); - static int CalendarDay(Scriptable* Sender, Trigger* parameters); - static int CalendarDayGT(Scriptable* Sender, Trigger* parameters); - static int CalendarDayLT(Scriptable* Sender, Trigger* parameters); - static int CalledByName(Scriptable* Sender, Trigger* parameters); - static int ChargeCount(Scriptable* Sender, Trigger* parameters); - static int CharName(Scriptable* Sender, Trigger* parameters); - static int CheckDoorFlags(Scriptable* Sender, Trigger* parameters); - static int CheckPartyAverageLevel(Scriptable* Sender, Trigger* parameters); - static int CheckPartyLevel(Scriptable* Sender, Trigger* parameters); - static int CheckSkill(Scriptable* Sender, Trigger* parameters); - static int CheckSkillGT(Scriptable* Sender, Trigger* parameters); - static int CheckSkillLT(Scriptable* Sender, Trigger* parameters); - static int CheckSpellState(Scriptable* Sender, Trigger* parameters); - static int CheckStat(Scriptable* Sender, Trigger* parameters); - static int CheckStatGT(Scriptable* Sender, Trigger* parameters); - static int CheckStatLT(Scriptable* Sender, Trigger* parameters); - static int Class(Scriptable* Sender, Trigger* parameters); - static int ClassEx(Scriptable* Sender, Trigger* parameters); - static int ClassLevel(Scriptable* Sender, Trigger* parameters); - static int ClassLevelGT(Scriptable* Sender, Trigger* parameters); - static int ClassLevelLT(Scriptable* Sender, Trigger* parameters); - static int Clicked(Scriptable* Sender, Trigger* parameters); - static int Closed(Scriptable* Sender, Trigger* parameters); - static int CombatCounter(Scriptable* Sender, Trigger* parameters); - static int CombatCounterGT(Scriptable* Sender, Trigger* parameters); - static int CombatCounterLT(Scriptable* Sender, Trigger* parameters); - static int Contains(Scriptable* Sender, Trigger* parameters); - static int CreatureHidden( Scriptable* Sender, Trigger* parameters); - static int CurrentAreaIs(Scriptable* Sender, Trigger* parameters); - //static int DamageTaken(Scriptable* Sender, Trigger* parameters); - //static int DamageTakenGT(Scriptable* Sender, Trigger* parameters); - //static int DamageTakenLT(Scriptable* Sender, Trigger* parameters); - static int Dead(Scriptable* Sender, Trigger* parameters); - static int Delay(Scriptable* Sender, Trigger* parameters); - static int Detect(Scriptable* Sender, Trigger* parameters); - static int Die(Scriptable* Sender, Trigger* parameters); - static int Died(Scriptable* Sender, Trigger* parameters); - static int Difficulty(Scriptable* Sender, Trigger* parameters); - static int DifficultyGT(Scriptable* Sender, Trigger* parameters); - static int DifficultyLT(Scriptable* Sender, Trigger* parameters); - static int Disarmed(Scriptable* Sender, Trigger* parameters); - static int DisarmFailed(Scriptable* Sender, Trigger* parameters); - static int Entered(Scriptable* Sender, Trigger* parameters); - static int EntirePartyOnMap(Scriptable* Sender, Trigger* parameters); - static int Exists(Scriptable* Sender, Trigger* parameters); - static int ExtendedStateCheck(Scriptable* Sender, Trigger* parameters); - static int ExtraProficiency(Scriptable* Sender, Trigger* parameters); - static int ExtraProficiencyGT(Scriptable* Sender, Trigger* parameters); - static int ExtraProficiencyLT(Scriptable* Sender, Trigger* parameters); - static int Faction(Scriptable* Sender, Trigger* parameters); - static int FallenPaladin(Scriptable* Sender, Trigger* parameters); - static int FallenRanger(Scriptable* Sender, Trigger* parameters); - static int False(Scriptable* Sender, Trigger* parameters); - static int ForceMarkedSpell_Trigger(Scriptable* Sender, Trigger* parameters); - static int Frame(Scriptable* Sender, Trigger* parameters); - static int Gender(Scriptable* Sender, Trigger* parameters); - static int General(Scriptable* Sender, Trigger* parameters); - static int G_Trigger(Scriptable* Sender, Trigger* parameters); - static int Global(Scriptable* Sender, Trigger* parameters); - static int GlobalAndGlobal_Trigger(Scriptable* Sender, Trigger* parameters); - static int GlobalBAndGlobal_Trigger(Scriptable* Sender, Trigger* parameters); - static int GlobalBAndGlobalExact(Scriptable* Sender, Trigger* parameters); - static int GlobalBitGlobal_Trigger(Scriptable* Sender, Trigger* parameters); - static int GlobalGT(Scriptable* Sender, Trigger* parameters); - static int GlobalGTGlobal(Scriptable* Sender, Trigger* parameters); - static int GlobalLT(Scriptable* Sender, Trigger* parameters); - static int GlobalLTGlobal(Scriptable* Sender, Trigger* parameters); - static int GlobalOrGlobal_Trigger(Scriptable* Sender, Trigger* parameters); - static int GlobalsEqual(Scriptable* Sender, Trigger* parameters); - static int GlobalsGT(Scriptable* Sender, Trigger* parameters); - static int GlobalsLT(Scriptable* Sender, Trigger* parameters); - static int GlobalTimerExact(Scriptable* Sender, Trigger* parameters); - static int GlobalTimerExpired(Scriptable* Sender, Trigger* parameters); - static int GlobalTimerNotExpired(Scriptable* Sender, Trigger* parameters); - static int GlobalTimerStarted(Scriptable* Sender, Trigger* parameters); - static int GGT_Trigger(Scriptable* Sender, Trigger* parameters); - static int GLT_Trigger(Scriptable* Sender, Trigger* parameters); - static int Happiness(Scriptable* Sender, Trigger* parameters); - static int HappinessGT(Scriptable* Sender, Trigger* parameters); - static int HappinessLT(Scriptable* Sender, Trigger* parameters); - static int HarmlessEntered(Scriptable* Sender, Trigger* parameters); - static int HasBounceEffects(Scriptable* Sender, Trigger* parameters); - static int HasImmunityEffects(Scriptable* Sender, Trigger* parameters); - static int HasInnateAbility(Scriptable* Sender, Trigger* parameters); - static int HasItem(Scriptable* Sender, Trigger* parameters); - static int HasItemEquipped(Scriptable* Sender, Trigger* parameters); - static int HasItemSlot(Scriptable* Sender, Trigger* parameters); - static int HasItemTypeSlot(Scriptable* Sender, Trigger* parameters); - static int HasWeaponEquipped(Scriptable* Sender, Trigger* parameters); - static int HaveAnySpells(Scriptable* Sender, Trigger* parameters); - static int HaveSpellParty(Scriptable* Sender, Trigger* parameters); - static int HaveSpell(Scriptable* Sender, Trigger* parameters); - static int HaveUsableWeaponEquipped(Scriptable* Sender, Trigger* parameters); - static int Heard(Scriptable* Sender, Trigger* parameters); - static int Help_Trigger(Scriptable* Sender, Trigger* parameters); - static int HelpEX(Scriptable* Sender, Trigger* parameters); - static int HitBy(Scriptable* Sender, Trigger* parameters); - static int HotKey(Scriptable* Sender, Trigger* parameters); - static int HP(Scriptable* Sender, Trigger* parameters); - static int HPGT(Scriptable* Sender, Trigger* parameters); - static int HPLost(Scriptable* Sender, Trigger* parameters); - static int HPLostGT(Scriptable* Sender, Trigger* parameters); - static int HPLostLT(Scriptable* Sender, Trigger* parameters); - static int HPLT(Scriptable* Sender, Trigger* parameters); - static int HPPercent(Scriptable* Sender, Trigger* parameters); - static int HPPercentGT(Scriptable* Sender, Trigger* parameters); - static int HPPercentLT(Scriptable* Sender, Trigger* parameters); - static int InActiveArea(Scriptable* Sender, Trigger* parameter); - static int InCutSceneMode(Scriptable *Sender, Trigger* parameter); - static int InLine(Scriptable* Sender, Trigger* parameter); - static int InMyArea(Scriptable* Sender, Trigger* parameter); - static int InMyGroup(Scriptable* Sender, Trigger* parameter); - static int InParty(Scriptable* Sender, Trigger* parameters); - static int InPartyAllowDead(Scriptable* Sender, Trigger* parameters); - static int InPartySlot(Scriptable* Sender, Trigger* parameters); - static int InteractingWith(Scriptable* Sender, Trigger* parameters); - static int Internal(Scriptable* Sender, Trigger* parameters); - static int InternalGT(Scriptable* Sender, Trigger* parameters); - static int InternalLT(Scriptable* Sender, Trigger* parameters); - static int InTrap(Scriptable* Sender, Trigger* parameters); - static int InventoryFull(Scriptable* Sender, Trigger* parameter); - static int InWeaponRange(Scriptable* Sender, Trigger* parameter); - static int IsAClown(Scriptable* Sender, Trigger* parameters); - static int IsActive(Scriptable* Sender, Trigger* parameters); - static int IsCreatureAreaFlag( Scriptable* Sender, Trigger* parameters); - static int IsCreatureHiddenInShadows( Scriptable* Sender, Trigger* parameters); - static int IsGabber(Scriptable* Sender, Trigger* parameters); - static int IsExtendedNight(Scriptable* Sender, Trigger* parameters); - static int IsFacingObject(Scriptable* Sender, Trigger* parameters); - static int IsFacingSavedRotation(Scriptable* Sender, Trigger* parameters); - static int IsLocked(Scriptable* Sender, Trigger* parameters); - static int IsMarkedSpell(Scriptable* Sender, Trigger* parameters); - static int IsOverMe(Scriptable* Sender, Trigger* parameters); - static int IsPathCriticalObject( Scriptable* Sender, Trigger* parameters); - static int IsPlayerNumber( Scriptable* Sender, Trigger* parameters); - static int IsRotation(Scriptable* Sender, Trigger* parameters); - static int IsSpellTargetValid( Scriptable* Sender, Trigger* parameters); - static int IsTeamBitOn(Scriptable* Sender, Trigger* parameters); - static int IsValidForPartyDialog(Scriptable* Sender, Trigger* parameters); - static int IsWeaponRanged(Scriptable* Sender, Trigger* parameters); - static int IsWeather(Scriptable* Sender, Trigger* parameters); - static int ItemIsIdentified(Scriptable* Sender, Trigger* parameters); - static int Joins(Scriptable* Sender, Trigger* parameters); - static int Kit(Scriptable* Sender, Trigger* parameters); - static int Killed(Scriptable* Sender, Trigger* parameters); - static int KnowSpell(Scriptable* Sender, Trigger* parameters); - static int LastMarkedObject_Trigger(Scriptable* Sender, Trigger* parameters); - static int LastPersonTalkedTo(Scriptable* Sender, Trigger* parameters); - static int Leaves(Scriptable* Sender, Trigger* parameters); - static int Level(Scriptable* Sender, Trigger* parameters); - static int LevelGT(Scriptable* Sender, Trigger* parameters); - static int LevelLT(Scriptable* Sender, Trigger* parameters); - static int LevelInClass(Scriptable* Sender, Trigger* parameters); - static int LevelInClassGT(Scriptable* Sender, Trigger* parameters); - static int LevelInClassLT(Scriptable* Sender, Trigger* parameters); - static int LevelParty(Scriptable* Sender, Trigger* parameters); - static int LevelPartyGT(Scriptable* Sender, Trigger* parameters); - static int LevelPartyLT(Scriptable* Sender, Trigger* parameters); - static int LocalsEqual(Scriptable* Sender, Trigger* parameters); - static int LocalsGT(Scriptable* Sender, Trigger* parameters); - static int LocalsLT(Scriptable* Sender, Trigger* parameters); - static int LOS(Scriptable* Sender, Trigger* parameters); - static int ModalState(Scriptable* Sender, Trigger* parameters); - static int Morale(Scriptable* Sender, Trigger* parameters); - static int MoraleGT(Scriptable* Sender, Trigger* parameters); - static int MoraleLT(Scriptable* Sender, Trigger* parameters); - static int NamelessBitTheDust(Scriptable* Sender, Trigger* parameters); - static int NearbyDialog(Scriptable* Sender, Trigger* parameters); - static int NearLocation(Scriptable* Sender, Trigger* parameters); - static int NearSavedLocation(Scriptable* Sender, Trigger* parameters); - static int NightmareModeOn(Scriptable* Sender, Trigger* parameters); - static int NotStateCheck(Scriptable* Sender, Trigger* parameters); - static int NullDialog(Scriptable* Sender, Trigger* parameters); - static int NumCreatures(Scriptable* Sender, Trigger* parameters); - static int NumCreaturesAtMyLevel(Scriptable* Sender, Trigger* parameters); - static int NumCreaturesGT(Scriptable* Sender, Trigger* parameters); - static int NumCreaturesGTMyLevel(Scriptable* Sender, Trigger* parameters); - static int NumCreaturesLT(Scriptable* Sender, Trigger* parameters); - static int NumCreaturesLTMyLevel(Scriptable* Sender, Trigger* parameters); - static int NumCreatureVsParty(Scriptable* Sender, Trigger* parameters); - static int NumCreatureVsPartyGT(Scriptable* Sender, Trigger* parameters); - static int NumCreatureVsPartyLT(Scriptable* Sender, Trigger* parameters); - static int NumDead(Scriptable* Sender, Trigger* parameters); - static int NumDeadGT(Scriptable* Sender, Trigger* parameters); - static int NumDeadLT(Scriptable* Sender, Trigger* parameters); - static int NumItems(Scriptable* Sender, Trigger* parameters); - static int NumItemsGT(Scriptable* Sender, Trigger* parameters); - static int NumItemsLT(Scriptable* Sender, Trigger* parameters); - static int NumItemsParty(Scriptable* Sender, Trigger* parameters); - static int NumItemsPartyGT(Scriptable* Sender, Trigger* parameters); - static int NumItemsPartyLT(Scriptable* Sender, Trigger* parameters); - static int NumTimesInteracted(Scriptable* Sender, Trigger* parameters); - static int NumTimesInteractedGT(Scriptable* Sender, Trigger* parameters); - static int NumTimesInteractedLT(Scriptable* Sender, Trigger* parameters); - static int NumTimesInteractedObject(Scriptable* Sender, Trigger* parameters); - static int NumTimesInteractedObjectGT(Scriptable* Sender, Trigger* parameters); - static int NumTimesInteractedObjectLT(Scriptable* Sender, Trigger* parameters); - static int NumTimesTalkedTo(Scriptable* Sender, Trigger* parameters); - static int NumTimesTalkedToGT(Scriptable* Sender, Trigger* parameters); - static int NumTimesTalkedToLT(Scriptable* Sender, Trigger* parameters); - static int ObjectActionListEmpty(Scriptable* Sender, Trigger* parameters); - static int OnCreation(Scriptable* Sender, Trigger* parameters); - static int OnIsland(Scriptable* Sender, Trigger* parameters); - static int OnScreen(Scriptable* Sender, Trigger* parameters); - static int Opened(Scriptable* Sender, Trigger* parameters); - static int OpenFailed(Scriptable* Sender, Trigger* parameters); - static int OpenState(Scriptable* Sender, Trigger* parameters); - static int Or(Scriptable* Sender, Trigger* parameters); - static int OutOfAmmo(Scriptable* Sender, Trigger* parameters); - static int OwnsFloaterMessage(Scriptable* Sender, Trigger* parameters); - static int PartyCountEQ(Scriptable* Sender, Trigger* parameters); - static int PartyCountGT(Scriptable* Sender, Trigger* parameters); - static int PartyCountLT(Scriptable* Sender, Trigger* parameters); - static int PartyCountAliveEQ(Scriptable* Sender, Trigger* parameters); - static int PartyCountAliveGT(Scriptable* Sender, Trigger* parameters); - static int PartyCountAliveLT(Scriptable* Sender, Trigger* parameters); - static int PartyGold(Scriptable* Sender, Trigger* parameters); - static int PartyGoldGT(Scriptable* Sender, Trigger* parameters); - static int PartyGoldLT(Scriptable* Sender, Trigger* parameters); - static int PartyHasItem(Scriptable* Sender, Trigger* parameters); - static int PartyHasItemIdentified(Scriptable* Sender, Trigger* parameters); - static int PartyMemberDied(Scriptable* Sender, Trigger* parameters); - static int PartyRested(Scriptable* Sender, Trigger* parameters); - static int PCCanSeePoint(Scriptable* Sender, Trigger* parameters); - static int PCInStore(Scriptable* Sender, Trigger* parameters); - static int PersonalSpaceDistance(Scriptable* Sender, Trigger* parameters); - static int PickLockFailed(Scriptable* Sender, Trigger* parameters); - static int PickpocketFailed(Scriptable* Sender, Trigger* parameters); - static int Proficiency(Scriptable* Sender, Trigger* parameters); - static int ProficiencyGT(Scriptable* Sender, Trigger* parameters); - static int ProficiencyLT(Scriptable* Sender, Trigger* parameters); - static int Race(Scriptable* Sender, Trigger* parameters); - static int RandomNum(Scriptable* Sender, Trigger* parameters); - static int RandomNumGT(Scriptable* Sender, Trigger* parameters); - static int RandomNumLT(Scriptable* Sender, Trigger* parameters); - static int RandomStatCheck(Scriptable* Sender, Trigger* parameters); - static int Range(Scriptable* Sender, Trigger* parameters); - static int Reaction(Scriptable* Sender, Trigger* parameters); - static int ReactionLT(Scriptable* Sender, Trigger* parameters); - static int ReactionGT(Scriptable* Sender, Trigger* parameters); - static int RealGlobalTimerExact(Scriptable* Sender, Trigger* parameters); - static int RealGlobalTimerExpired(Scriptable* Sender, Trigger* parameters); - static int RealGlobalTimerNotExpired(Scriptable* Sender, Trigger* parameters); - static int ReceivedOrder(Scriptable* Sender, Trigger* parameters); - static int Reputation(Scriptable* Sender, Trigger* parameters); - static int ReputationGT(Scriptable* Sender, Trigger* parameters); - static int ReputationLT(Scriptable* Sender, Trigger* parameters); - static int School(Scriptable* Sender, Trigger* parameters); - static int See(Scriptable* Sender, Trigger* parameters); - static int Sequence(Scriptable* Sender, Trigger* parameters); - static int SetLastMarkedObject(Scriptable* Sender, Trigger* parameters); - static int SetMarkedSpell_Trigger(Scriptable* Sender, Trigger* parameters); - static int Specifics(Scriptable* Sender, Trigger* parameters); - static int SpellCast(Scriptable* Sender, Trigger* parameters); - static int SpellCastInnate(Scriptable* Sender, Trigger* parameters); - static int SpellCastOnMe(Scriptable* Sender, Trigger* parameters); - static int SpellCastPriest(Scriptable* Sender, Trigger* parameters); - static int StateCheck(Scriptable* Sender, Trigger* parameters); - static int StealFailed(Scriptable* Sender, Trigger* parameters); - static int StoreHasItem(Scriptable* Sender, Trigger* parameters); - static int StuffGlobalRandom(Scriptable* Sender, Trigger* parameters); - static int SubRace(Scriptable* Sender, Trigger* parameters); - static int SystemVariable_Trigger(Scriptable* Sender, Trigger* parameters); - static int TargetUnreachable(Scriptable* Sender, Trigger* parameters); - static int Team(Scriptable* Sender, Trigger* parameters); - static int Time(Scriptable* Sender, Trigger* parameters); - static int TimeGT(Scriptable* Sender, Trigger* parameters); - static int TimeLT(Scriptable* Sender, Trigger* parameters); - static int TimeOfDay(Scriptable* Sender, Trigger* parameters); - static int TimerActive(Scriptable* Sender, Trigger* parameters); - static int TimerExpired(Scriptable* Sender, Trigger* parameters); - static int TookDamage(Scriptable* Sender, Trigger* parameters); - static int TotalItemCnt(Scriptable* Sender, Trigger* parameters); - static int TotalItemCntExclude(Scriptable* Sender, Trigger* parameters); - static int TotalItemCntExcludeGT(Scriptable* Sender, Trigger* parameters); - static int TotalItemCntExcludeLT(Scriptable* Sender, Trigger* parameters); - static int TotalItemCntGT(Scriptable* Sender, Trigger* parameters); - static int TotalItemCntLT(Scriptable* Sender, Trigger* parameters); - static int TrapTriggered(Scriptable* Sender, Trigger* parameters); - static int TriggerTrigger(Scriptable* Sender, Trigger* parameters); - static int TriggerSetGlobal(Scriptable* Sender, Trigger* parameters); - static int True(Scriptable* Sender, Trigger* parameters); - static int TurnedBy(Scriptable* Sender, Trigger* parameters); - static int Unlocked(Scriptable* Sender, Trigger* parameters); - static int UnselectableVariable(Scriptable* Sender, Trigger* parameters); - static int UnselectableVariableGT(Scriptable* Sender, Trigger* parameters); - static int UnselectableVariableLT(Scriptable* Sender, Trigger* parameters); - static int Unusable(Scriptable* Sender, Trigger* parameters); - static int Vacant(Scriptable* Sender, Trigger* parameters); - static int WalkedToTrigger(Scriptable* Sender, Trigger* parameters); - static int WasInDialog(Scriptable* Sender, Trigger* parameters); - static int Xor(Scriptable* Sender, Trigger* parameters); - static int XP(Scriptable* Sender, Trigger* parameters); - static int XPGT(Scriptable* Sender, Trigger* parameters); - static int XPLT(Scriptable* Sender, Trigger* parameters); -public: - //Actions - static void Activate(Scriptable* Sender, Action* parameters); - static void ActivatePortalCursor(Scriptable* Sender, Action* parameters); - static void AddAreaFlag(Scriptable* Sender, Action* parameters); - static void AddAreaType(Scriptable* Sender, Action* parameters); - static void AddExperienceParty(Scriptable *Sender, Action* parameters); - static void AddExperiencePartyCR(Scriptable *Sender, Action* parameters); - static void AddExperiencePartyGlobal(Scriptable *Sender, Action* parameters); - static void AddFeat(Scriptable *Sender, Action* parameters); - static void AddGlobals(Scriptable* Sender, Action* parameters); - static void AddHP(Scriptable* Sender, Action* parameters); - static void AddJournalEntry(Scriptable* Sender, Action* parameters); - static void AddKit(Scriptable* Sender, Action* parameters); - static void AddMapnote(Scriptable* Sender, Action* parameters); - static void AddSpecialAbility(Scriptable* Sender, Action* parameters); - static void AddSuperKit(Scriptable* Sender, Action* parameters); - static void AddWayPoint(Scriptable* Sender, Action* parameters); - static void AddXP2DA(Scriptable *Sender, Action* parameters); - static void AddXPObject(Scriptable *Sender, Action* parameters); - static void AdvanceTime(Scriptable *Sender, Action* parameters); - static void Ally(Scriptable* Sender, Action* parameters); - static void AmbientActivate(Scriptable* Sender, Action* parameters); - static void AnkhegEmerge(Scriptable* Sender, Action* parameters); - static void AnkhegHide(Scriptable* Sender, Action* parameters); - static void ApplyDamage(Scriptable* Sender, Action* parameters); - static void ApplyDamagePercent(Scriptable* Sender, Action* parameters); - static void ApplySpell(Scriptable* Sender, Action* parameters); - static void ApplySpellPoint(Scriptable* Sender, Action* parameters); - static void AttachTransitionToDoor(Scriptable* Sender, Action* parameters); - static void Attack(Scriptable* Sender, Action* parameters); - static void AttackNoSound(Scriptable* Sender, Action* parameters); - static void AttackOneRound(Scriptable* Sender, Action* parameters); - static void AttackReevaluate(Scriptable* Sender, Action* parameters); - static void BanterBlockFlag(Scriptable* Sender, Action* parameters); - static void BanterBlockTime(Scriptable* Sender, Action* parameters); - static void BashDoor(Scriptable* Sender, Action* parameters); - static void BattleSong(Scriptable* Sender, Action* parameters); - static void Berserk(Scriptable* Sender, Action* parameters); - static void BitClear(Scriptable* Sender, Action* parameters); - static void BitGlobal(Scriptable* Sender, Action* parameters); - static void BreakInstants(Scriptable* Sender, Action* parameters); - static void Calm(Scriptable* Sender, Action* parameters); - static void ChangeAIScript(Scriptable* Sender, Action* parameters); - static void ChangeAIType(Scriptable* Sender, Action* parameters); - static void ChangeAlignment(Scriptable* Sender, Action* parameters); - static void ChangeAllegiance(Scriptable* Sender, Action* parameters); - static void ChangeAnimation(Scriptable* Sender, Action* parameters); - static void ChangeAnimationNoEffect(Scriptable* Sender, Action* parameters); - static void ChangeClass(Scriptable* Sender, Action* parameters); - static void ChangeColor(Scriptable* Sender, Action* parameters); - static void ChangeCurrentScript(Scriptable* Sender, Action* parameters); - static void ChangeDestination(Scriptable* Sender, Action* parameters); - static void ChangeDialogue(Scriptable* Sender, Action* parameters); - static void ChangeGender(Scriptable* Sender, Action* parameters); - static void ChangeGeneral(Scriptable* Sender, Action* parameters); - static void ChangeRace(Scriptable* Sender, Action* parameters); - static void ChangeSpecifics(Scriptable* Sender, Action* parameters); - static void ChangeStat(Scriptable* Sender, Action* parameters); - static void ChangeStatGlobal(Scriptable* Sender, Action* parameters); - static void ChangeStoreMarkup(Scriptable* Sender, Action* parameters); - static void ChangeTileState(Scriptable* Sender, Action* parameters); - static void ClearActions(Scriptable* Sender, Action* parameters); - static void ClearAllActions(Scriptable* Sender, Action* parameters); - static void ClearPartyEffects(Scriptable* Sender, Action* parameters); - static void ClearSpriteEffects(Scriptable* Sender, Action* parameters); - static void ClickLButtonObject(Scriptable* Sender, Action* parameters); - static void ClickLButtonPoint(Scriptable* Sender, Action* parameters); - static void ClickRButtonObject(Scriptable* Sender, Action* parameters); - static void ClickRButtonPoint(Scriptable* Sender, Action* parameters); - static void CloseDoor(Scriptable* Sender, Action* parameters); - static void ContainerEnable(Scriptable* Sender, Action* parameters); - static void Continue(Scriptable* Sender, Action* parameters); - static void CopyGroundPilesTo(Scriptable* Sender, Action* parameters); - static void CreateCreature(Scriptable* Sender, Action* parameters); - static void CreateCreatureAtLocation(Scriptable* Sender, Action* parameters); - static void CreateCreatureAtFeet(Scriptable* Sender, Action* parameters); - static void CreateCreatureCopyPoint(Scriptable* Sender, Action* parameters); - static void CreateCreatureDoor(Scriptable* Sender, Action* parameters); - static void CreateCreatureImpassable(Scriptable* Sender, Action* parameters); - static void CreateCreatureImpassableAllowOverlap(Scriptable* Sender, - Action* parameters); - static void CreateCreatureObject(Scriptable* Sender, Action* parameters); - static void CreateCreatureObjectCopy(Scriptable* Sender, Action* parameters); - static void CreateCreatureObjectDoor(Scriptable* Sender, Action* parameters); - static void CreateCreatureObjectOffset(Scriptable* Sender, Action* parameters); - static void CreateCreatureObjectOffScreen(Scriptable* Sender, Action* parameters); - static void CreateCreatureOffScreen(Scriptable* Sender, Action* parameters); - static void CreateItem(Scriptable* Sender, Action* parameters); - static void CreateItemNumGlobal(Scriptable* Sender, Action* parameters); - static void CreatePartyGold(Scriptable *Sender, Action *parameters); - static void CreateVisualEffect(Scriptable* Sender, Action* parameters); - static void CreateVisualEffectObject(Scriptable* Sender, - Action* parameters); - static void CreateVisualEffectObjectSticky(Scriptable* Sender, - Action* parameters); - static void CutSceneID(Scriptable* Sender, Action* parameters); - static void Damage(Scriptable* Sender, Action* parameters); - static void DayNight(Scriptable *Sender, Action* parameters); - static void Deactivate(Scriptable* Sender, Action* parameters); - static void Debug(Scriptable* Sender, Action* parameters); - static void DemoEnd(Scriptable* Sender, Action* parameters); - static void DestroyAllDestructableEquipment(Scriptable* Sender, - Action* parameters); - static void DestroyAllEquipment(Scriptable* Sender, Action* parameters); - static void DestroyGold(Scriptable* Sender, Action* parameters); - static void DestroyItem(Scriptable* Sender, Action* parameters); - static void DestroyPartyGold(Scriptable* Sender, Action* parameters); - static void DestroyPartyItem(Scriptable* Sender, Action* parameters); - static void DestroyPartyItemNum(Scriptable* Sender, Action* parameters); - static void DestroySelf(Scriptable* Sender, Action* parameters); - static void DetectSecretDoor(Scriptable* Sender, Action* parameters); - static void Dialogue(Scriptable* Sender, Action* parameters); - static void DialogueForceInterrupt(Scriptable* Sender, Action* parameters); - static void DialogueInterrupt(Scriptable* Sender, Action* parameters); - static void DisableFogDither(Scriptable* Sender, Action* parameters); - static void DisableSpriteDither(Scriptable* Sender, Action* parameters); - static void DisplayMessage(Scriptable* Sender, Action* parameters); - static void DisplayString(Scriptable* Sender, Action* parameters); - static void DisplayStringHead(Scriptable* Sender, Action* parameters); - static void DisplayStringHeadOwner(Scriptable* Sender, Action* parameters); - static void DisplayStringNoName(Scriptable* Sender, Action* parameters); - static void DisplayStringNoNameHead(Scriptable* Sender, Action* parameters); - static void DisplayStringWait(Scriptable* Sender, Action* parameters); - static void DoubleClickLButtonObject(Scriptable* Sender, Action* parameters); - static void DoubleClickLButtonPoint(Scriptable* Sender, Action* parameters); - static void DoubleClickRButtonObject(Scriptable* Sender, Action* parameters); - static void DoubleClickRButtonPoint(Scriptable* Sender, Action* parameters); - static void DropInventory(Scriptable* Sender, Action* parameters); - static void DropInventoryEX(Scriptable* Sender, Action* parameters); - static void DropItem(Scriptable* Sender, Action* parameters); - static void EnableFogDither(Scriptable* Sender, Action* parameters); - static void EnablePortalTravel(Scriptable* Sender, Action* parameters); - static void EnableSpriteDither(Scriptable* Sender, Action* parameters); - static void EndCredits(Scriptable* Sender, Action* parameters); - static void EndCutSceneMode(Scriptable* Sender, Action* parameters); - static void Enemy(Scriptable* Sender, Action* parameters); - static void EscapeArea(Scriptable* Sender, Action* parameters); - static void EscapeAreaDestroy(Scriptable* Sender, Action* parameters); - static void EscapeAreaNoSee(Scriptable* Sender, Action* parameters); - static void EscapeAreaObject(Scriptable* Sender, Action* parameters); - static void EscapeAreaObjectNoSee(Scriptable* Sender, Action* parameters); - static void EquipItem(Scriptable *Sender, Action *parameters); - static void EquipMostDamagingMelee(Scriptable *Sender, Action *parameters); - static void EquipRanged(Scriptable *Sender, Action *parameters); - static void EquipWeapon(Scriptable *Sender, Action *parameters); - static void ExitPocketPlane(Scriptable* Sender, Action* parameters); - static void ExpansionEndCredits(Scriptable* Sender, Action* parameters); - static void Explore(Scriptable *Sender, Action *parameters); - static void ExploreMapChunk(Scriptable *Sender, Action *parameters); - static void ExportParty(Scriptable *Sender, Action *parameters); - static void Face(Scriptable* Sender, Action* parameters); - static void FaceObject(Scriptable* Sender, Action* parameters); - static void FaceSavedLocation(Scriptable* Sender, Action* parameters); - static void FadeFromColor(Scriptable* Sender, Action* parameters); - static void FadeToAndFromColor(Scriptable* Sender, Action* parameters); - static void FadeToColor(Scriptable* Sender, Action* parameters); - static void FakeEffectExpiryCheck(Scriptable* Sender, Action* parameters); - static void FillSlot(Scriptable *Sender, Action* parameters); - static void FindTraps(Scriptable* Sender, Action* parameters); - static void FixEngineRoom(Scriptable *Sender, Action* parameters); - static void FloatMessageFixed(Scriptable* Sender, Action* parameters); - static void FloatMessageFixedRnd(Scriptable* Sender, Action* parameters); - static void FloatMessageRnd(Scriptable* Sender, Action* parameters); - static void FloatRebus(Scriptable* Sender, Action* parameters); - static void Follow(Scriptable* Sender, Action* parameters); - static void FollowCreature(Scriptable* Sender, Action* parameters); - static void FollowObjectFormation(Scriptable* Sender, Action* parameters); - static void ForceAIScript(Scriptable* Sender, Action* parameters); - static void ForceAttack(Scriptable* Sender, Action* parameters); - static void ForceFacing(Scriptable* Sender, Action* parameters); - static void ForceHide(Scriptable* Sender, Action* parameters); - static void ForceLeaveAreaLUA(Scriptable* Sender, Action* parameters); - static void ForceMarkedSpell(Scriptable* Sender, Action* parameters); - static void ForceSpell(Scriptable* Sender, Action* parameters); - static void ForceSpellPoint(Scriptable* Sender, Action* parameters); - static void ForceUseContainer(Scriptable* Sender, Action* parameters); - static void Formation(Scriptable* Sender, Action* parameters); - static void FullHeal(Scriptable* Sender, Action* parameters); - static void GenerateMaze(Scriptable* Sender, Action* parameters); - static void GeneratePartyMember(Scriptable* Sender, Action* parameters); - static void GetItem(Scriptable* Sender, Action* parameters); - static void GetStat(Scriptable* Sender, Action* parameters); - static void GiveItem(Scriptable* Sender, Action* parameters); - static void GiveOrder(Scriptable* Sender, Action* parameters); - static void GivePartyAllEquipment(Scriptable* Sender, Action* parameters); - static void GivePartyGold(Scriptable* Sender, Action* parameters); - static void GivePartyGoldGlobal(Scriptable* Sender, Action* parameters); - static void GlobalAddGlobal(Scriptable* Sender, Action* parameters); - static void GlobalAndGlobal(Scriptable* Sender, Action* parameters); - static void GlobalBAnd(Scriptable* Sender, Action* parameters); - static void GlobalBAndGlobal(Scriptable* Sender, Action* parameters); - static void GlobalBitGlobal(Scriptable* Sender, Action* parameters); - static void GlobalBOr(Scriptable* Sender, Action* parameters); - static void GlobalBOrGlobal(Scriptable* Sender, Action* parameters); - static void GlobalMax(Scriptable* Sender, Action* parameters); - static void GlobalMaxGlobal(Scriptable* Sender, Action* parameters); - static void GlobalMin(Scriptable* Sender, Action* parameters); - static void GlobalMinGlobal(Scriptable* Sender, Action* parameters); - static void GlobalOrGlobal(Scriptable* Sender, Action* parameters); - static void GlobalSetGlobal(Scriptable* Sender, Action* parameters); - static void GlobalShL(Scriptable* Sender, Action* parameters); - static void GlobalShLGlobal(Scriptable* Sender, Action* parameters); - static void GlobalShout(Scriptable* Sender, Action* parameters); - static void GlobalShR(Scriptable* Sender, Action* parameters); - static void GlobalShRGlobal(Scriptable* Sender, Action* parameters); - static void GlobalSubGlobal(Scriptable* Sender, Action* parameters); - static void GlobalXor(Scriptable* Sender, Action* parameters); - static void GlobalXorGlobal(Scriptable* Sender, Action* parameters); - static void Help(Scriptable* Sender, Action* parameters); - static void Hide(Scriptable* Sender, Action* parameters); - static void HideAreaOnMap(Scriptable* Sender, Action* parameters); - static void HideCreature(Scriptable* Sender, Action* parameters); - static void HideGUI(Scriptable* Sender, Action* parameters); - static void IncInternal(Scriptable* Sender, Action* parameters); - static void IncMoraleAI(Scriptable* Sender, Action* parameters); - static void IncrementChapter(Scriptable* Sender, Action* parameters); - static void IncrementExtraProficiency(Scriptable* Sender, Action* parameters); - static void IncrementGlobal(Scriptable* Sender, Action* parameters); - static void IncrementGlobalOnce(Scriptable* Sender, Action* parameters); - static void IncrementKillStat(Scriptable* Sender, Action* parameters); - static void IncrementProficiency(Scriptable* Sender, Action* parameters); - static void Interact(Scriptable* Sender, Action* parameters); - static void JoinParty(Scriptable* Sender, Action* parameters); - static void JumpToObject(Scriptable* Sender, Action* parameters); - static void JumpToPoint(Scriptable* Sender, Action* parameters); - static void JumpToPointInstant(Scriptable* Sender, Action* parameters); - static void JumpToSavedLocation(Scriptable* Sender, Action* parameters); - static void Kill(Scriptable* Sender, Action* parameters); - static void KillFloatMessage(Scriptable* Sender, Action* parameters); - static void Leader(Scriptable* Sender, Action* parameters); - static void LeaveArea(Scriptable* Sender, Action* parameters); - static void LeaveAreaLUA(Scriptable* Sender, Action* parameters); - static void LeaveAreaLUAEntry(Scriptable* Sender, Action* parameters); - static void LeaveAreaLUAPanic(Scriptable* Sender, Action* parameters); - static void LeaveAreaLUAPanicEntry(Scriptable* Sender, Action* parameters); - static void LeaveParty(Scriptable* Sender, Action* parameters); - static void Lock(Scriptable* Sender, Action* parameters); - static void LockScroll(Scriptable* Sender, Action* parameters); - static void MakeGlobal(Scriptable* Sender, Action* parameters); - static void MakeUnselectable(Scriptable* Sender, Action* parameters); - static void MarkObject(Scriptable* Sender, Action* parameters); - static void MarkSpellAndObject(Scriptable* Sender, Action* parameters); - static void MatchHP(Scriptable* Sender, Action* parameters); - static void MoraleDec(Scriptable* Sender, Action* parameters); - static void MoraleInc(Scriptable* Sender, Action* parameters); - static void MoraleSet(Scriptable* Sender, Action* parameters); - static void MoveBetweenAreas(Scriptable* Sender, Action* parameters); - static void MoveBetweenAreasEffect(Scriptable* Sender, Action* parameters); - static void MoveCursorPoint(Scriptable* Sender, Action* parameters); - static void MoveGlobal(Scriptable* Sender, Action* parameters); - static void MoveGlobalObject(Scriptable* Sender, Action* parameters); - static void MoveGlobalObjectOffScreen(Scriptable* Sender, Action* parameters); - static void MoveGlobalsTo(Scriptable* Sender, Action* parameters); - static void MoveInventory(Scriptable *Sender, Action* parameters); - static void MoveToCenterOfScreen(Scriptable* Sender, Action* parameters); - static void MoveToExpansion(Scriptable* Sender, Action* parameters); - static void MoveToObject(Scriptable* Sender, Action* parameters); - static void MoveToObjectFollow(Scriptable* Sender, Action* parameters); - static void MoveToObjectNoInterrupt(Scriptable* Sender, Action* parameters); - static void MoveToObjectUntilSee(Scriptable* Sender, Action* parameters); - static void MoveToOffset(Scriptable* Sender, Action* parameters); - static void MoveToPoint(Scriptable* Sender, Action* parameters); - static void MoveToPointNoInterrupt(Scriptable* Sender, Action* parameters); - static void MoveToPointNoRecticle(Scriptable* Sender, Action* parameters); - static void MoveToSavedLocation(Scriptable* Sender, Action* parameters); - static void MoveViewPoint(Scriptable* Sender, Action* parameters); - static void MoveViewObject(Scriptable* Sender, Action* parameters); - static void NIDSpecial1(Scriptable* Sender, Action* parameters); - static void NIDSpecial2(Scriptable* Sender, Action* parameters); - static void NoAction(Scriptable* Sender, Action* parameters); - static void NoActionAtAll(Scriptable* Sender, Action* parameters); - static void OpenDoor(Scriptable* Sender, Action* parameters); - static void Panic(Scriptable* Sender, Action* parameters); - static void PauseGame(Scriptable *Sender, Action* parameters); - static void PermanentStatChange(Scriptable* Sender, Action* parameters); - static void PickLock(Scriptable* Sender, Action* parameters); - static void PickPockets(Scriptable* Sender, Action* parameters); - static void PickUpItem(Scriptable* Sender, Action* parameters); - static void PlayBardSong(Scriptable* Sender, Action* parameters); - static void PlayDead(Scriptable* Sender, Action* parameters); - static void PlayDeadInterruptable(Scriptable* Sender, Action* parameters); - static void PlayerDialogue(Scriptable* Sender, Action* parameters); - static void PlaySequence(Scriptable* Sender, Action* parameters); - static void PlaySequenceGlobal(Scriptable* Sender, Action* parameters); - static void PlaySequenceTimed(Scriptable* Sender, Action* parameters); - static void PlaySound(Scriptable* Sender, Action* parameters); - static void PlaySoundNotRanged(Scriptable* Sender, Action* parameters); - static void PlaySoundPoint(Scriptable* Sender, Action* parameters); - static void Plunder(Scriptable* Sender, Action* parameters); - static void Polymorph(Scriptable* Sender, Action* parameters); - static void PolymorphCopy(Scriptable* Sender, Action* parameters); - static void PolymorphCopyBase(Scriptable* Sender, Action* parameters); - static void ProtectObject(Scriptable* Sender, Action* parameters); - static void ProtectPoint(Scriptable* Sender, Action* parameters); - static void QuitGame(Scriptable* Sender, Action* parameters); - static void RandomFly(Scriptable* Sender, Action* parameters); - static void RandomRun(Scriptable* Sender, Action* parameters); - static void RandomTurn(Scriptable* Sender, Action* parameters); - static void RandomWalk(Scriptable* Sender, Action* parameters); - static void RandomWalkContinuous(Scriptable* Sender, Action* parameters); - static void RealSetGlobalTimer(Scriptable* Sender, Action* parameters); - static void ReallyForceSpell(Scriptable* Sender, Action* parameters); - static void ReallyForceSpellDead(Scriptable* Sender, Action* parameters); - static void ReallyForceSpellPoint(Scriptable* Sender, Action* parameters); - static void Recoil(Scriptable* Sender, Action* parameters); - static void RegainPaladinHood(Scriptable* Sender, Action* parameters); - static void RegainRangerHood(Scriptable* Sender, Action* parameters); - static void RemoveAreaFlag(Scriptable* Sender, Action* parameters); - static void RemoveAreaType(Scriptable* Sender, Action* parameters); - static void RemoveJournalEntry(Scriptable* Sender, Action* parameters); - static void RemoveMapnote(Scriptable* Sender, Action* parameters); - static void RemovePaladinHood(Scriptable* Sender, Action* parameters); - static void RemoveRangerHood(Scriptable* Sender, Action* parameters); - static void RemoveSpell(Scriptable* Sender, Action* parameters); - static void RemoveTraps(Scriptable* Sender, Action* parameters); - static void ReputationInc(Scriptable* Sender, Action* parameters); - static void ReputationSet(Scriptable* Sender, Action* parameters); - static void RestorePartyLocation(Scriptable *Sender, Action* parameters); - static void Rest(Scriptable *Sender, Action* parameters); - static void RestNoSpells(Scriptable *Sender, Action* parameters); - static void RestParty(Scriptable *Sender, Action* parameters); - static void RestUntilHealed(Scriptable *Sender, Action* parameters); - static void ReturnToSavedLocation(Scriptable* Sender, Action* parameters); - static void ReturnToSavedLocationDelete(Scriptable* Sender, Action* parameters); - static void RevealAreaOnMap(Scriptable* Sender, Action* parameters); - static void RunAwayFrom(Scriptable* Sender, Action* parameters); - static void RunAwayFromNoInterrupt(Scriptable* Sender, Action* parameters); - static void RunAwayFromNoLeaveArea(Scriptable* Sender, Action* parameters); - static void RunFollow(Scriptable* Sender, Action* parameters); - static void RunningAttack(Scriptable* Sender, Action* parameters); - static void RunningAttackNoSound(Scriptable* Sender, Action* parameters); - static void RunToObject(Scriptable* Sender, Action* parameters); - static void RunToPoint(Scriptable* Sender, Action* parameters); - static void RunToPointNoRecticle(Scriptable* Sender, Action* parameters); - static void RunToSavedLocation(Scriptable* Sender, Action* parameters); - static void SaveGame(Scriptable* Sender, Action* parameters); - static void SaveLocation(Scriptable* Sender, Action* parameters); - static void SaveObjectLocation(Scriptable* Sender, Action* parameters); - static void ScreenShake(Scriptable* Sender, Action* parameters); - static void SelectWeaponAbility(Scriptable* Sender, Action* parameters); - static void SendTrigger(Scriptable* Sender, Action* parameters); - static void SetAnimState(Scriptable* Sender, Action* parameters); - static void SetApparentName(Scriptable* Sender, Action* parameters); - static void SetAreaFlags(Scriptable* Sender, Action* parameters); - static void SetAreaRestFlag(Scriptable* Sender, Action* parameters); - static void SetArmourLevel(Scriptable* Sender, Action* parameters); - static void SetBeenInPartyFlags(Scriptable* Sender, Action* parameters); - static void SetBestWeapon(Scriptable *Sender, Action *parameters); - static void SetCursorState(Scriptable* Sender, Action* parameters); - static void SetCreatureAreaFlag(Scriptable* Sender, Action* parameters); - static void SetCriticalPathObject(Scriptable* Sender, Action* parameters); - static void SetDialogue(Scriptable* Sender, Action* parameters); - static void SetDialogueRange(Scriptable* Sender, Action* parameters); - static void SetDoorFlag(Scriptable* Sender, Action* parameters); - static void SetDoorLocked(Scriptable* Sender, Action* parameters); - static void SetEncounterProbability(Scriptable* Sender, Action* parameters); - static void SetExtendedNight(Scriptable* Sender, Action* parameters); - static void SetFaction(Scriptable* Sender, Action* parameters); - static void SetGabber(Scriptable* Sender, Action* parameters); - static void SetGlobal(Scriptable* Sender, Action* parameters); - static void SetGlobalRandom(Scriptable* Sender, Action* parameters); - static void SetGlobalTimer(Scriptable* Sender, Action* parameters); - static void SetGlobalTimerOnce(Scriptable* Sender, Action* parameters); - static void SetGlobalTimerRandom(Scriptable* Sender, Action* parameters); - static void SetGlobalTint(Scriptable* Sender, Action* parameters); - static void SetHP(Scriptable* Sender, Action* parameters); - static void SetHPPercent(Scriptable* Sender, Action* parameters); - static void SetInternal(Scriptable* Sender, Action* parameters); - static void SetInterrupt(Scriptable* Sender, Action* parameters); - static void SetLeavePartyDialogFile(Scriptable* Sender, Action* parameters); - static void SetMarkedSpell(Scriptable* Sender, Action* parameters); - static void SetMasterArea(Scriptable* Sender, Action* parameters); - static void SetMazeEasier(Scriptable* Sender, Action* parameters); - static void SetMazeHarder(Scriptable* Sender, Action* parameters); - static void SetMoraleAI(Scriptable* Sender, Action* parameters); - static void SetMusic(Scriptable* Sender, Action* parameters); - static void SetNamelessClass(Scriptable* Sender, Action* parameters); - static void SetNamelessDeath(Scriptable* Sender, Action* parameters); - static void SetNamelessDisguise(Scriptable* Sender, Action* parameters); - static void SetNoOneOnTrigger(Scriptable* Sender, Action* parameters); - static void SetNumTimesTalkedTo(Scriptable* Sender, Action* parameters); - static void SetPlayerSound(Scriptable* Sender, Action* parameters); - static void SetQuestDone(Scriptable* Sender, Action* parameters); - static void SetRegularName(Scriptable* Sender, Action* parameters); - static void SetRestEncounterChance(Scriptable* Sender, Action* parameters); - static void SetRestEncounterProbabilityDay(Scriptable* Sender, Action* parameters); - static void SetRestEncounterProbabilityNight(Scriptable* Sender, Action* parameters); - static void SetSavedLocation(Scriptable* Sender, Action* parameters); - static void SetSavedLocationPoint(Scriptable* Sender, Action* parameters); - static void SetScriptName(Scriptable* Sender, Action* parameters); - static void SetSelection(Scriptable* Sender, Action* parameters); - static void SetStartPos(Scriptable* Sender, Action* parameters); - static void SetTeam(Scriptable* Sender, Action* parameters); - static void SetTeamBit(Scriptable* Sender, Action* parameters); - static void SetTextColor(Scriptable* Sender, Action* parameters); - static void SetToken(Scriptable* Sender, Action* parameters); - static void SetToken2DA(Scriptable* Sender, Action* parameters); - static void SetTokenGlobal(Scriptable* Sender, Action* parameters); - static void SetTokenObject(Scriptable* Sender, Action* parameters); - static void SetTrackString(Scriptable* Sender, Action* parameters); - static void SetupWish(Scriptable* Sender, Action* parameters); - static void SetupWishObject(Scriptable* Sender, Action* parameters); - static void SetVisualRange(Scriptable* Sender, Action* parameters); - static void SG(Scriptable* Sender, Action* parameters); - static void Shout(Scriptable* Sender, Action* parameters); - static void SmallWait(Scriptable* Sender, Action* parameters); - static void SmallWaitRandom(Scriptable* Sender, Action* parameters); - static void SoundActivate(Scriptable* Sender, Action* parameters); - static void SpawnPtActivate(Scriptable* Sender, Action* parameters); - static void SpawnPtDeactivate(Scriptable* Sender, Action* parameters); - static void SpawnPtSpawn(Scriptable* Sender, Action* parameters); - static void Spell(Scriptable* Sender, Action* parameters); - static void SpellCastEffect(Scriptable* Sender, Action* parameters); - static void SpellHitEffectPoint(Scriptable* Sender, Action* parameters); - static void SpellHitEffectSprite(Scriptable* Sender, Action* parameters); - static void SpellNoDec(Scriptable* Sender, Action* parameters); - static void SpellPoint(Scriptable* Sender, Action* parameters); - static void SpellPointNoDec(Scriptable* Sender, Action* parameters); - static void StartCombatCounter(Scriptable* Sender, Action* parameters); - static void StartCutScene(Scriptable* Sender, Action* parameters); - static void StartCutSceneMode(Scriptable* Sender, Action* parameters); - static void StartDialogue(Scriptable* Sender, Action* parameters); - static void StartDialogueInterrupt(Scriptable* Sender, Action* parameters); - static void StartDialogueNoSet(Scriptable* Sender, Action* parameters); - static void StartDialogueNoSetInterrupt(Scriptable* Sender, - Action* parameters); - static void StartDialogueOverride(Scriptable* Sender, Action* parameters); - static void StartDialogueOverrideInterrupt(Scriptable* Sender, - Action* parameters); - static void StartMovie(Scriptable* Sender, Action* parameters); - static void StartMusic(Scriptable* Sender, Action* parameters); - static void StartRainNow(Scriptable* Sender, Action* parameters); - static void StartRandomTimer(Scriptable* Sender, Action* parameters); - static void StartSong(Scriptable* Sender, Action* parameters); - static void StartStore(Scriptable* Sender, Action* parameters); - static void StartTimer(Scriptable* Sender, Action* parameters); - static void StateOverrideFlag(Scriptable* Sender, Action* parameters); - static void StateOverrideTime(Scriptable* Sender, Action* parameters); - static void StaticPalette(Scriptable* Sender, Action* parameters); - static void StaticStart(Scriptable* Sender, Action* parameters); - static void StaticStop(Scriptable* Sender, Action* parameters); - static void StopMoving(Scriptable* Sender, Action* parameters); - static void StorePartyLocation(Scriptable *Sender, Action* parameters); - static void Swing(Scriptable* Sender, Action* parameters); - static void SwingOnce(Scriptable* Sender, Action* parameters); - static void TakeItemList(Scriptable* Sender, Action* parameters); - static void TakeItemListParty(Scriptable* Sender, Action* parameters); - static void TakeItemListPartyNum(Scriptable* Sender, Action* parameters); - static void TakeItemReplace(Scriptable* Sender, Action* parameters); - static void TakePartyGold(Scriptable* Sender, Action* parameters); - static void TakePartyItem(Scriptable* Sender, Action* parameters); - static void TakePartyItemAll(Scriptable* Sender, Action* parameters); - static void TakePartyItemNum(Scriptable* Sender, Action* parameters); - static void TakePartyItemRange(Scriptable* Sender, Action* parameters); - static void TeleportParty(Scriptable* Sender, Action* parameters); - static void TextScreen(Scriptable* Sender, Action* parameters); - static void ToggleDoor(Scriptable* Sender, Action* parameters); - static void TimedMoveToPoint(Scriptable* Sender, Action* parameters); - static void TransformItem(Scriptable* Sender, Action* parameters); - static void TransformItemAll(Scriptable* Sender, Action* parameters); - static void TransformPartyItem(Scriptable* Sender, Action* parameters); - static void TransformPartyItemAll(Scriptable* Sender, Action* parameters); - static void TriggerActivation(Scriptable* Sender, Action* parameters); - static void Turn(Scriptable* Sender, Action* parameters); - static void TurnAMT(Scriptable* Sender, Action* parameters); - static void UndoExplore(Scriptable *Sender, Action *parameters); - static void UnhideGUI(Scriptable* Sender, Action* parameters); - static void Unlock(Scriptable* Sender, Action* parameters); - static void UnlockScroll(Scriptable* Sender, Action* parameters); - static void UseContainer(Scriptable* Sender, Action* parameters); - static void UseDoor(Scriptable* Sender, Action* parameters); - static void UseItem(Scriptable* Sender, Action* parameters); - static void UseItemPoint(Scriptable* Sender, Action* parameters); - static void VerbalConstant(Scriptable* Sender, Action* parameters); - static void VerbalConstantHead(Scriptable* Sender, Action* parameters); - static void Wait(Scriptable* Sender, Action* parameters); - static void WaitAnimation(Scriptable* Sender, Action* parameters); - static void WaitRandom(Scriptable* Sender, Action* parameters); - static void Weather(Scriptable* Sender, Action* parameters); - static void XEquipItem(Scriptable *Sender, Action *parameters); -public: - //Objects - static Targets *BestAC(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *EighthNearest(Scriptable *Sender, Targets *parameter, int ga_flagss); - static Targets *EighthNearestDoor(Scriptable *Sender, Targets *parameter, int ga_flagss); - static Targets *EighthNearestEnemyOf(Scriptable *Sender, Targets *parameter, int ga_flagss); - static Targets *EighthNearestEnemyOfType(Scriptable *Sender, Targets *parameter, int ga_flagss); - static Targets *EighthNearestMyGroupOfType(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *Farthest(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *FarthestEnemyOf(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *FifthNearest(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *FifthNearestDoor(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *FifthNearestEnemyOf(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *FifthNearestEnemyOfType(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *FifthNearestMyGroupOfType(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *FourthNearest(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *FourthNearestDoor(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *FourthNearestEnemyOf(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *FourthNearestEnemyOfType(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *FourthNearestMyGroupOfType(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *Gabber(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *GroupOf(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *LastAttackerOf(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *LastCommandedBy(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *LastHeardBy(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *LastHelp(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *LastHitter(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *LastMarkedObject(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *LastSeenBy(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *LastSummonerOf(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *LastTalkedToBy(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *LastTargetedBy(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *LastTrigger(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *LeaderOf(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *LeastDamagedOf(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *MostDamagedOf(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *Myself(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *MyTarget(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *Nearest(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *NearestDoor(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *NearestEnemyOf(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *NearestEnemyOfType(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *NearestEnemySummoned(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *NearestMyGroupOfType(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *NearestPC(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *NinthNearest(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *NinthNearestDoor(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *NinthNearestEnemyOf(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *NinthNearestEnemyOfType(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *NinthNearestMyGroupOfType(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *Nothing(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *Player1(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *Player1Fill(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *Player2(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *Player2Fill(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *Player3(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *Player3Fill(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *Player4(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *Player4Fill(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *Player5(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *Player5Fill(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *Player6(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *Player6Fill(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *Protagonist(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *ProtectedBy(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *ProtectorOf(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *SecondNearest(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *SecondNearestDoor(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *SecondNearestEnemyOf(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *SecondNearestEnemyOfType(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *SecondNearestMyGroupOfType(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *SelectedCharacter(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *SeventhNearest(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *SeventhNearestDoor(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *SeventhNearestEnemyOf(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *SeventhNearestEnemyOfType(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *SeventhNearestMyGroupOfType(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *SixthNearest(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *SixthNearestDoor(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *SixthNearestEnemyOf(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *SixthNearestEnemyOfType(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *SixthNearestMyGroupOfType(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *StrongestOf(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *StrongestOfMale(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *TenthNearest(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *TenthNearestDoor(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *TenthNearestEnemyOf(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *TenthNearestEnemyOfType(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *TenthNearestMyGroupOfType(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *ThirdNearest(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *ThirdNearestDoor(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *ThirdNearestEnemyOf(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *ThirdNearestEnemyOfType(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *ThirdNearestMyGroupOfType(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *WeakestOf(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *WorstAC(Scriptable *Sender, Targets *parameters, int ga_flags); - -public: - /*GemRB extensions/actions*/ - static void RunAwayFromPoint(Scriptable* Sender, Action* parameters); - static void UnMakeGlobal(Scriptable* Sender, Action* parameters); - static void UnloadArea(Scriptable* Sender, Action* parameters); - - /*GemRB extensions/objects*/ - static Targets *Player7(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *Player7Fill(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *Player8(Scriptable *Sender, Targets *parameters, int ga_flags); - static Targets *Player8Fill(Scriptable *Sender, Targets *parameters, int ga_flags); -}; - -GEM_EXPORT Action* GenerateAction(char* String); -Action* GenerateActionDirect(char* String, Scriptable *object); -GEM_EXPORT Trigger* GenerateTrigger(char* String); - -void InitializeIEScript(); - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/GameScript/Matching.cpp b/project/jni/application/gemrb/gemrb/core/GameScript/Matching.cpp deleted file mode 100644 index 78ddc6a91..000000000 --- a/project/jni/application/gemrb/gemrb/core/GameScript/Matching.cpp +++ /dev/null @@ -1,674 +0,0 @@ -/* 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 "GameScript/Matching.h" - -#include "GameScript/GSUtils.h" - -#include "Interface.h" -#include "Game.h" -#include "Map.h" -#include "TileMap.h" -#include "Scriptable/Container.h" -#include "Scriptable/Door.h" -#include "Scriptable/InfoPoint.h" - -/* return a Targets object with a single scriptable inside */ -static inline Targets* ReturnScriptableAsTarget(Scriptable *sc) -{ - if (!sc) return NULL; - Targets *tgts = new Targets(); - tgts->AddTarget(sc, 0, 0); - return tgts; -} - -/* do IDS filtering: [PC], [ENEMY], etc */ -static inline bool DoObjectIDSCheck(Object *oC, Actor *ac, bool *filtered) { - for (int j = 0; j < ObjectIDSCount; j++) { - if (!oC->objectFields[j]) { - continue; - } - *filtered = true; - IDSFunction func = idtargets[j]; - if (!func) { - printMessage("GameScript", "Unimplemented IDS targeting opcode: %d\n", YELLOW, j); - continue; - } - if (!func( ac, oC->objectFields[j] ) ) { - return false; - } - } - return true; -} - -/* do object filtering: Myself, LastAttackerOf(Player1), etc */ -static inline Targets *DoObjectFiltering(Scriptable *Sender, Targets *tgts, Object *oC, int ga_flags) { - for (int i = 0; i < MaxObjectNesting; i++) { - int filterid = oC->objectFilters[i]; - if (!filterid) break; - - ObjectFunction func = objects[filterid]; - if (!func) { - printMessage("GameScript", "Unknown object filter: %d %s\n", YELLOW, - filterid, objectsTable->GetValue(filterid)); - continue; - } - - tgts = func(Sender, tgts, ga_flags); - if (!tgts->Count()) { - delete tgts; - return NULL; - } - } - return tgts; -} - -static EffectRef fx_protection_creature_ref = { "Protection:Creature", -1 }; - -static inline bool DoObjectChecks(Map *map, Scriptable *Sender, Actor *target, int &dist, bool ignoreinvis=false) -{ - dist = SquaredMapDistance(Sender, target); - - // TODO: what do we check for non-actors? - // non-actors have a visual range (15), we should do visual range and LOS - - if (Sender->Type == ST_ACTOR) { - Actor *source = (Actor *)Sender; - - // Detect() ignores invisibility completely - if (!ignoreinvis) { - // TODO: move this stuff into a shared function so it can be used elsewhere? - - // SEEINVISIBLE skips these checks :-) - if (source->Modified[IE_SEEINVISIBLE] == 0) { - ieDword state = target->Modified[IE_STATE_ID]; - // check for invisibility - if ((state & STATE_INVISIBLE) != 0) return false; - // check for improved invisibility? probably not - //if ((state & STATE_INVIS2) != 0) return false; - } - - // maybe this should be setting an invis flag? - // TODO: should SEEINVISIBLE ignore this? Detect()? - if (target->Modified[IE_AVATARREMOVAL]) return false; - } - - // visual range check - int visualrange = source->Modified[IE_VISUALRANGE]; - if (dist > visualrange*visualrange) return false; - - // LOS check - if (!map->IsVisible(Sender->Pos, target->Pos)) return false; - - // protection against creature - if (target->fxqueue.HasEffect(fx_protection_creature_ref)) { - // TODO: de-hardcode these (may not all be correct anyway) - if (target->fxqueue.HasEffectWithParamPair(fx_protection_creature_ref, 2, source->Modified[IE_EA])) return false; - if (target->fxqueue.HasEffectWithParamPair(fx_protection_creature_ref, 3, source->Modified[IE_GENERAL])) return false; - if (target->fxqueue.HasEffectWithParamPair(fx_protection_creature_ref, 4, source->Modified[IE_RACE])) return false; - if (target->fxqueue.HasEffectWithParamPair(fx_protection_creature_ref, 5, source->Modified[IE_CLASS])) return false; - if (target->fxqueue.HasEffectWithParamPair(fx_protection_creature_ref, 6, source->Modified[IE_SPECIFIC])) return false; - if (target->fxqueue.HasEffectWithParamPair(fx_protection_creature_ref, 7, source->Modified[IE_SEX])) return false; - if (target->fxqueue.HasEffectWithParamPair(fx_protection_creature_ref, 8, source->Modified[IE_ALIGNMENT])) return false; - } - } - return true; -} - -/* returns actors that match the [x.y.z] expression */ -static Targets* EvaluateObject(Map *map, Scriptable* Sender, Object* oC, int ga_flags) -{ - // if you ActionOverride a global actor, they might not have a map :( - // TODO: don't allow this to happen? - if (!map) { - return NULL; - } - - if (oC->objectName[0]) { - //We want the object by its name... (doors/triggers don't play here!) - Actor* aC = map->GetActor( oC->objectName, ga_flags ); - - /*if (!aC && (ga_flags&GA_GLOBAL) ) { - aC = FindActorNearby(oC->objectName, map, ga_flags ); - }*/ - - //return here because object name/IDS targeting are mutually exclusive - return ReturnScriptableAsTarget(aC); - } - - if (oC->objectFields[0]==-1) { - // this is an internal hack, allowing us to pass actor ids around as objects - Actor* aC = map->GetActorByGlobalID( (ieDword) oC->objectFields[1] ); - if (aC) { - if (!aC->ValidTarget(ga_flags)) { - return NULL; - } - return ReturnScriptableAsTarget(aC); - } - Door *door = map->GetDoorByGlobalID( (ieDword) oC->objectFields[1]); - if (door) { - return ReturnScriptableAsTarget(door); - } - - Container* cont = map->GetContainerByGlobalID((ieDword) oC->objectFields[1]); - if (cont) { - return ReturnScriptableAsTarget(cont); - } - - InfoPoint* trap = map->GetInfoPointByGlobalID((ieDword) oC->objectFields[1]); - if (trap) { - return ReturnScriptableAsTarget(trap); - } - - return NULL; - } - - Targets *tgts = NULL; - - //we need to get a subset of actors from the large array - //if this gets slow, we will need some index tables - int i = map->GetActorCount(true); - while (i--) { - Actor *ac = map->GetActor(i, true); - if (!ac) continue; // is this check really needed? - // don't return Sender in IDS targeting! - if (ac == Sender) continue; - bool filtered = false; - if (DoObjectIDSCheck(oC, ac, &filtered)) { - if (!filtered) { - // if no filters were applied.. - assert(!tgts); - return NULL; - } - int dist; - if (DoObjectChecks(map, Sender, ac, dist, (ga_flags & GA_DETECT) != 0)) { - if (!tgts) tgts = new Targets(); - tgts->AddTarget((Scriptable *) ac, dist, ga_flags); - } - } - } - - return tgts; -} - -Targets* GetAllObjects(Map *map, Scriptable* Sender, Object* oC, int ga_flags) -{ - if (!oC) { - return NULL; - } - Targets* tgts = EvaluateObject(map, Sender, oC, ga_flags); - //if we couldn't find an endpoint by name or object qualifiers - //it is not an Actor, but could still be a Door or Container (scriptable) - if (!tgts && oC->objectName[0]) { - return NULL; - } - //now lets do the object filter stuff, we create Targets because - //it is possible to start from blank sheets using endpoint filters - //like (Myself, Protagonist etc) - if (!tgts) { - tgts = new Targets(); - } - tgts = DoObjectFiltering(Sender, tgts, oC, ga_flags); - return tgts; -} - -Targets *GetAllActors(Scriptable *Sender, int ga_flags) -{ - Map *map = Sender->GetCurrentArea(); - - int i = map->GetActorCount(true); - Targets *tgts = new Targets(); - while (i--) { - Actor *ac = map->GetActor(i,true); - int dist = Distance(Sender->Pos, ac->Pos); - tgts->AddTarget((Scriptable *) ac, dist, ga_flags); - } - return tgts; -} - -/* get a non-actor object from a map, by name */ -Scriptable *GetActorObject(TileMap *TMap, const char *name) -{ - Scriptable * aC = TMap->GetDoor( name ); - if (aC) { - return aC; - } - - //containers should have a precedence over infopoints because otherwise - //AR1512 sanity test quest would fail - //If this order couldn't be maintained, then 'Contains' should have a - //unique call to get containers only - - //No... it was not an door... maybe a Container? - aC = TMap->GetContainer( name ); - if (aC) { - return aC; - } - - //No... it was not a container ... maybe an InfoPoint? - aC = TMap->GetInfoPoint( name ); - if (aC) { - return aC; - } - return aC; -} - -// blocking actions need to store some kinds of objects between ticks -Scriptable* GetStoredActorFromObject(Scriptable* Sender, Object* oC, int ga_flags) -{ - Scriptable *tar = NULL; - // retrieve an existing target if it still exists and is valid - if (Sender->CurrentActionTarget) { - tar = core->GetGame()->GetActorByGlobalID(Sender->CurrentActionTarget); - if (tar) { - // always an actor, check if it satisfies flags - if (((Actor *)tar)->ValidTarget(ga_flags)) { - return tar; - } - } - return NULL; // target invalid/gone - } - tar = GetActorFromObject(Sender, oC, ga_flags); - // maybe store the target if it's an actor.. - if (tar && tar->Type == ST_ACTOR) { - // .. but we only want objects created via objectFilters - if (oC->objectFilters[0]) { - Sender->CurrentActionTarget = tar->GetGlobalID(); - } - } - return tar; -} - -Scriptable* GetActorFromObject(Scriptable* Sender, Object* oC, int ga_flags) -{ - Scriptable *aC = NULL; - - if (!oC) { - return NULL; - } - Game *game = core->GetGame(); - Targets *tgts = GetAllObjects(Sender->GetCurrentArea(), Sender, oC, ga_flags); - if (tgts) { - //now this could return other than actor objects - aC = tgts->GetTarget(0,-1); - delete tgts; - if (aC || oC->objectFields[0]!=-1) { - return aC; - } - - //global actors are always found by object ID! - return game->GetGlobalActorByGlobalID(oC->objectFields[1]); - } - - if (oC->objectName[0]) { - // if you ActionOverride a global actor, they might not have a map :( - // TODO: don't allow this to happen? - if (Sender->GetCurrentArea()) { - aC = GetActorObject(Sender->GetCurrentArea()->GetTileMap(), oC->objectName ); - if (aC) { - return aC; - } - } - - //global actors are always found by scripting name! - aC = game->FindPC(oC->objectName); - if (aC) { - return aC; - } - aC = game->FindNPC(oC->objectName); - if (aC) { - return aC; - } - } - return NULL; -} - -bool MatchActor(Scriptable *Sender, ieDword actorID, Object* oC) -{ - if (!Sender) { - return false; - } - Actor *ac = Sender->GetCurrentArea()->GetActorByGlobalID(actorID); - if (!ac) { - return false; - } - - // [0]/[ANYONE] can match all actors - if (!oC) { - return true; - } - - bool filtered = false; - - // name matching - if (oC->objectName[0]) { - if (strnicmp(ac->GetScriptName(), oC->objectName, 32) != 0) { - return false; - } - filtered = true; - } - - // IDS targeting - // (if we already matched by name, we don't do this) - // TODO: check distance? area? visibility? - if (!filtered && !DoObjectIDSCheck(oC, ac, &filtered)) return false; - - // globalID hack should never get here - assert(oC->objectFilters[0] != -1); - - // object filters - if (oC->objectFilters[0]) { - // object filters insist on having a stupid targets list, - // so we waste a lot of time here - Targets *tgts = new Targets(); - int ga_flags = 0; // TODO: correct? - - // handle already-filtered vs not-yet-filtered cases - // e.g. LastTalkedToBy(Myself) vs LastTalkedToBy - if (filtered) tgts->AddTarget(ac, 0, ga_flags); - - tgts = DoObjectFiltering(Sender, tgts, oC, ga_flags); - if (!tgts) return false; - - // and sometimes object filters are lazy and not only don't filter - // what we give them, they clear it and return a list :( - // so we have to search the whole list.. - bool ret = false; - targetlist::iterator m; - const targettype *tt = tgts->GetFirstTarget(m, ST_ACTOR); - while (tt) { - Actor *actor = (Actor *) tt->actor; - if (actor->GetGlobalID() == actorID) { - ret = true; - break; - } - tt = tgts->GetNextTarget(m, ST_ACTOR); - } - delete tgts; - if (!ret) return false; - } - return true; -} - -int GetObjectCount(Scriptable* Sender, Object* oC) -{ - if (!oC) { - return 0; - } - // EvaluateObject will return [PC] - // GetAllObjects will also return Myself (evaluates object filters) - // i believe we need the latter here - Targets* tgts = GetAllObjects(Sender->GetCurrentArea(), Sender, oC, 0); - int count = tgts->Count(); - delete tgts; - return count; -} - -//TODO: -//check numcreaturesatmylevel(myself, 1) -//when the actor is alone -//it should (obviously) return true if the trigger -//evaluates object filters -//also check numcreaturesgtmylevel(myself,0) with -//actor having at high level -int GetObjectLevelCount(Scriptable* Sender, Object* oC) -{ - if (!oC) { - return 0; - } - // EvaluateObject will return [PC] - // GetAllObjects will also return Myself (evaluates object filters) - // i believe we need the latter here - Targets* tgts = GetAllObjects(Sender->GetCurrentArea(), Sender, oC, 0); - int count = 0; - if (tgts) { - targetlist::iterator m; - const targettype *tt = tgts->GetFirstTarget(m, ST_ACTOR); - while (tt) { - count += ((Actor *) tt->actor)->GetXPLevel(true); - tt = tgts->GetNextTarget(m, ST_ACTOR); - } - } - delete tgts; - return count; -} - -Targets *GetMyTarget(Scriptable *Sender, Actor *actor, Targets *parameters, int ga_flags) -{ - if (!actor) { - if (Sender->Type==ST_ACTOR) { - actor = (Actor *) Sender; - } - } - parameters->Clear(); - if (actor) { - Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastTarget); - if (target) { - parameters->AddTarget(target, 0, ga_flags); - } - } - return parameters; -} - -Targets *XthNearestDoor(Targets *parameters, unsigned int count) -{ - //get the origin - Scriptable *origin = parameters->GetTarget(0, -1); - parameters->Clear(); - if (!origin) { - return parameters; - } - //get the doors based on it - Map *map = origin->GetCurrentArea(); - unsigned int i =(unsigned int) map->TMap->GetDoorCount(); - if (count>i) { - return parameters; - } - while (i--) { - Door *door = map->TMap->GetDoor(i); - unsigned int dist = Distance(origin->Pos, door->Pos); - parameters->AddTarget(door, dist, 0); - } - - //now get the xth door - origin = parameters->GetTarget(count, ST_DOOR); - parameters->Clear(); - if (!origin) { - return parameters; - } - parameters->AddTarget(origin, 0, 0); - return parameters; -} - -Targets *XthNearestOf(Targets *parameters, int count, int ga_flags) -{ - Scriptable *origin; - - if (count<0) { - const targettype *t = parameters->GetLastTarget(ST_ACTOR); - origin = t->actor; - } else { - origin = parameters->GetTarget(count, ST_ACTOR); - } - parameters->Clear(); - if (!origin) { - return parameters; - } - parameters->AddTarget(origin, 0, ga_flags); - return parameters; -} - -//mygroup means the same specifics as origin -Targets *XthNearestMyGroupOfType(Scriptable *origin, Targets *parameters, unsigned int count, int ga_flags) -{ - if (origin->Type != ST_ACTOR) { - parameters->Clear(); - return parameters; - } - - targetlist::iterator m; - const targettype *t = parameters->GetFirstTarget(m, ST_ACTOR); - if (!t) { - return parameters; - } - Actor *actor = (Actor *) origin; - //determining the specifics of origin - ieDword type = actor->GetStat(IE_SPECIFIC); //my group - - while ( t ) { - if (t->actor->Type!=ST_ACTOR) { - t=parameters->RemoveTargetAt(m); - continue; - } - Actor *actor = (Actor *) (t->actor); - if (actor->GetStat(IE_SPECIFIC) != type) { - t=parameters->RemoveTargetAt(m); - continue; - } - t = parameters->GetNextTarget(m, ST_ACTOR); - } - return XthNearestOf(parameters,count, ga_flags); -} - -Targets *ClosestEnemySummoned(Scriptable *origin, Targets *parameters, int ga_flags) -{ - if (origin->Type != ST_ACTOR) { - parameters->Clear(); - return parameters; - } - - targetlist::iterator m; - const targettype *t = parameters->GetFirstTarget(m, ST_ACTOR); - if (!t) { - return parameters; - } - Actor *actor = (Actor *) origin; - //determining the allegiance of the origin - int type = GetGroup(actor); - - if (type==2) { - parameters->Clear(); - return parameters; - } - - actor = NULL; - while ( t ) { - Actor *tmp = (Actor *) (t->actor); - if (tmp->GetStat(IE_SEX) != SEX_SUMMON) { - continue; - } - if (type) { //origin is PC - if (tmp->GetStat(IE_EA) <= EA_GOODCUTOFF) { - continue; - } - } else { - if (tmp->GetStat(IE_EA) >= EA_EVILCUTOFF) { - continue; - } - } - actor = tmp; - t = parameters->GetNextTarget(m, ST_ACTOR); - } - parameters->Clear(); - parameters->AddTarget(actor, 0, ga_flags); - return parameters; -} - -Targets *XthNearestEnemyOfType(Scriptable *origin, Targets *parameters, unsigned int count, int ga_flags) -{ - if (origin->Type != ST_ACTOR) { - parameters->Clear(); - return parameters; - } - - targetlist::iterator m; - const targettype *t = parameters->GetFirstTarget(m, ST_ACTOR); - if (!t) { - return parameters; - } - Actor *actor = (Actor *) origin; - //determining the allegiance of the origin - int type = GetGroup(actor); - - if (type==2) { - parameters->Clear(); - return parameters; - } - - while ( t ) { - if (t->actor->Type!=ST_ACTOR) { - t=parameters->RemoveTargetAt(m); - continue; - } - Actor *actor = (Actor *) (t->actor); - // IDS targeting already did object checks (unless we need to override Detect?) - if (type) { //origin is PC - if (actor->GetStat(IE_EA) <= EA_GOODCUTOFF) { - t=parameters->RemoveTargetAt(m); - continue; - } - } else { - if (actor->GetStat(IE_EA) >= EA_EVILCUTOFF) { - t=parameters->RemoveTargetAt(m); - continue; - } - } - t = parameters->GetNextTarget(m, ST_ACTOR); - } - return XthNearestOf(parameters,count, ga_flags); -} - -Targets *XthNearestEnemyOf(Targets *parameters, int count, int ga_flags) -{ - Actor *origin = (Actor *) parameters->GetTarget(0, ST_ACTOR); - parameters->Clear(); - if (!origin) { - return parameters; - } - //determining the allegiance of the origin - int type = GetGroup(origin); - - if (type==2) { - return parameters; - } - Map *map = origin->GetCurrentArea(); - int i = map->GetActorCount(true); - Actor *ac; - while (i--) { - ac=map->GetActor(i,true); - int distance; - //int distance = Distance(ac, origin); - // TODO: if it turns out you need to check Sender here, beware you take the right distance! - // (n the original games, this is only used for NearestEnemyOf(Player1) in obsgolem.bcs) - if (!DoObjectChecks(map, origin, ac, distance)) continue; - if (type) { //origin is PC - if (ac->GetStat(IE_EA) >= EA_EVILCUTOFF) { - parameters->AddTarget(ac, distance, ga_flags); - } - } - else { - if (ac->GetStat(IE_EA) <= EA_GOODCUTOFF) { - parameters->AddTarget(ac, distance, ga_flags); - } - } - } - return XthNearestOf(parameters,count, ga_flags); -} - diff --git a/project/jni/application/gemrb/gemrb/core/GameScript/Matching.h b/project/jni/application/gemrb/gemrb/core/GameScript/Matching.h deleted file mode 100644 index f069d6bb9..000000000 --- a/project/jni/application/gemrb/gemrb/core/GameScript/Matching.h +++ /dev/null @@ -1,49 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ -#ifndef MATCHING_H -#define MATCHING_H - -#include "GameScript/GameScript.h" - -#include "exports.h" - -class TileMap; - -GEM_EXPORT Targets* GetAllObjects(Map *map, Scriptable* Sender, Object* oC, int ga_flags); -Targets* GetAllActors(Scriptable* Sender, int ga_flags); -Scriptable* GetActorFromObject(Scriptable* Sender, Object* oC, int ga_flags = 0); -Scriptable* GetStoredActorFromObject(Scriptable* Sender, Object* oC, int ga_flags = 0); -Scriptable *GetActorObject(TileMap *TMap, const char *name); - -Targets *GetMyTarget(Scriptable *Sender, Actor *actor, Targets *parameters, int ga_flags); -Targets *XthNearestOf(Targets *parameters, int count, int ga_flags); -Targets *XthNearestDoor(Targets *parameters, unsigned int count); -Targets *XthNearestEnemyOf(Targets *parameters, int count, int ga_flags); -Targets *ClosestEnemySummoned(Scriptable *origin, Targets *parameters, int ga_flags); -Targets *XthNearestEnemyOfType(Scriptable *origin, Targets *parameters, unsigned int count, int ga_flags); -Targets *XthNearestMyGroupOfType(Scriptable *origin, Targets *parameters, unsigned int count, int ga_flags); - -/* returns true if actor matches the object specs. */ -bool MatchActor(Scriptable *Sender, ieDword ID, Object* oC); -/* returns the number of actors matching the IDS targeting */ -int GetObjectCount(Scriptable* Sender, Object* oC); -int GetObjectLevelCount(Scriptable* Sender, Object* oC); - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/GameScript/Objects.cpp b/project/jni/application/gemrb/gemrb/core/GameScript/Objects.cpp deleted file mode 100644 index 05beeba7f..000000000 --- a/project/jni/application/gemrb/gemrb/core/GameScript/Objects.cpp +++ /dev/null @@ -1,1164 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "GameScript/GameScript.h" - -#include "GameScript/GSUtils.h" -#include "GameScript/Matching.h" - -#include "win32def.h" - -#include "DialogHandler.h" -#include "Game.h" -#include "GUI/GameControl.h" - -//------------------------------------------------------------- -// Object Functions -//------------------------------------------------------------- - -//in this implementation, Myself will drop the parameter array -//i think all object filters could be expected to do so -//they should remove unnecessary elements from the parameters -Targets *GameScript::Myself(Scriptable* Sender, Targets* parameters, int ga_flags) -{ - parameters->Clear(); - parameters->AddTarget(Sender, 0, ga_flags); - return parameters; -} - -Targets *GameScript::NearestDoor(Scriptable* /*Sender*/, Targets *parameters, int /*ga_flags*/) -{ - return XthNearestDoor(parameters, 0); -} - -Targets *GameScript::SecondNearestDoor(Scriptable* /*Sender*/, Targets *parameters, int /*ga_flags*/) -{ - return XthNearestDoor(parameters, 1); -} - -Targets *GameScript::ThirdNearestDoor(Scriptable* /*Sender*/, Targets *parameters, int /*ga_flags*/) -{ - return XthNearestDoor(parameters, 2); -} - -Targets *GameScript::FourthNearestDoor(Scriptable* /*Sender*/, Targets *parameters, int /*ga_flags*/) -{ - return XthNearestDoor(parameters, 3); -} - -Targets *GameScript::FifthNearestDoor(Scriptable* /*Sender*/, Targets *parameters, int /*ga_flags*/) -{ - return XthNearestDoor(parameters, 4); -} - -Targets *GameScript::SixthNearestDoor(Scriptable* /*Sender*/, Targets *parameters, int /*ga_flags*/) -{ - return XthNearestDoor(parameters, 5); -} - -Targets *GameScript::SeventhNearestDoor(Scriptable* /*Sender*/, Targets *parameters, int /*ga_flags*/) -{ - return XthNearestDoor(parameters, 6); -} - -Targets *GameScript::EighthNearestDoor(Scriptable* /*Sender*/, Targets *parameters, int /*ga_flags*/) -{ - return XthNearestDoor(parameters, 7); -} - -Targets *GameScript::NinthNearestDoor(Scriptable* /*Sender*/, Targets *parameters, int /*ga_flags*/) -{ - return XthNearestDoor(parameters, 8); -} - -Targets *GameScript::TenthNearestDoor(Scriptable* /*Sender*/, Targets *parameters, int /*ga_flags*/) -{ - return XthNearestDoor(parameters, 9); -} - -//in bg2 it is same as player1 so far -//in iwd2 this is the Gabber!!! -//but also, if there is no gabber, it is the first PC -//probably it is simply the nearest exportable character... -Targets *GameScript::Protagonist(Scriptable* Sender, Targets *parameters, int ga_flags) -{ - parameters->Clear(); - //this sucks but IWD2 is like that... - static bool charnameisgabber = core->HasFeature(GF_CHARNAMEISGABBER); - if (charnameisgabber) { - GameControl* gc = core->GetGameControl(); - if (gc) { - parameters->AddTarget(gc->dialoghandler->GetSpeaker(), 0, ga_flags); - } - if (parameters->Count()) { - return parameters; - } - //ok, this will return the nearest PC in the first slot - Game *game = core->GetGame(); - int i = game->GetPartySize(false); - while(i--) { - Actor *target = game->GetPC(i,false); - parameters->AddTarget(target, Distance(Sender, target), ga_flags); - } - return parameters; - } - parameters->AddTarget(core->GetGame()->GetPC(0, false), 0, ga_flags); - return parameters; -} - -//last talker -Targets *GameScript::Gabber(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - parameters->Clear(); - GameControl* gc = core->GetGameControl(); - if (gc) { - parameters->AddTarget(gc->dialoghandler->GetSpeaker(), 0, ga_flags); - } - return parameters; -} - -Targets *GameScript::LastTrigger(Scriptable *Sender, Targets *parameters, int ga_flags) -{ - parameters->Clear(); - if (Sender->LastTrigger) { - Actor *target = Sender->GetCurrentArea()->GetActorByGlobalID(Sender->LastTrigger); - parameters->AddTarget(target, 0, ga_flags); - } - return parameters; -} - -Targets *GameScript::LastMarkedObject(Scriptable *Sender, Targets *parameters, int ga_flags) -{ - Actor *actor = (Actor *) parameters->GetTarget(0, ST_ACTOR); - if (!actor) { - if (Sender->Type==ST_ACTOR) { - actor = (Actor *) Sender; - } - } - parameters->Clear(); - if (actor) { - Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastMarked); - if (target) { - parameters->AddTarget(target, 0, ga_flags); - } - } - return parameters; -} - -//actions should always use LastMarkedObject, because LastSeen could be deleted -Targets *GameScript::LastSeenBy(Scriptable *Sender, Targets *parameters, int ga_flags) -{ - Actor *actor = (Actor *) parameters->GetTarget(0, ST_ACTOR); - if (!actor) { - if (Sender->Type==ST_ACTOR) { - actor = (Actor *) Sender; - } - } - parameters->Clear(); - if (actor) { - Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastSeen); - if (target) { - parameters->AddTarget(target, 0, ga_flags); - } - } - return parameters; -} - -Targets *GameScript::LastHelp(Scriptable *Sender, Targets *parameters, int ga_flags) -{ - Actor *actor = (Actor *) parameters->GetTarget(0, ST_ACTOR); - if (!actor) { - if (Sender->Type==ST_ACTOR) { - actor = (Actor *) Sender; - } - } - parameters->Clear(); - if (actor) { - Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastHelp); - if (target) { - parameters->AddTarget(target, 0, ga_flags); - } - } - return parameters; -} - -Targets *GameScript::LastHeardBy(Scriptable *Sender, Targets *parameters, int ga_flags) -{ - Actor *actor = (Actor *) parameters->GetTarget(0, ST_ACTOR); - if (!actor) { - if (Sender->Type==ST_ACTOR) { - actor = (Actor *) Sender; - } - } - parameters->Clear(); - if (actor) { - Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastHeard); - if (target) { - parameters->AddTarget(target, 0, ga_flags); - } - } - return parameters; -} - -//i was told that Group means the same specifics, so this is just an -//object selector for everyone with the same specifics as the current object -Targets *GameScript::GroupOf(Scriptable *Sender, Targets *parameters, int ga_flags) -{ - Actor *actor = (Actor *) parameters->GetTarget(0, ST_ACTOR); - if (!actor) { - if (Sender->Type==ST_ACTOR) { - actor = (Actor *) Sender; - } - } - parameters->Clear(); - if (actor) { - ieDword tmp = actor->GetStat(IE_SPECIFIC); - Map *cm = Sender->GetCurrentArea(); - int i = cm->GetActorCount(true); - while (i--) { - Actor *target=cm->GetActor(i,true); - if (target && (target->GetStat(IE_SPECIFIC)==tmp) ) { - parameters->AddTarget(target, 0, ga_flags); - } - } - } - return parameters; -} - -/*this one is tough, but done */ -Targets *GameScript::ProtectorOf(Scriptable *Sender, Targets *parameters, int ga_flags) -{ - Actor *actor = (Actor *) parameters->GetTarget(0, ST_ACTOR); - if (!actor) { - if (Sender->Type==ST_ACTOR) { - actor = (Actor *) Sender; - } - } - parameters->Clear(); - /*if (actor) { - ieWord tmp = actor->LastProtected; - Map *cm = Sender->GetCurrentArea(); - int i = cm->GetActorCount(true); - while (i--) { - Actor *target=cm->GetActor(i,true); - if (target && (target->LastProtected ==tmp) ) { - parameters->AddTarget(target, 0, ga_flags); - } - } - }*/ - if (actor) { - Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastProtector); - if (target) { - parameters->AddTarget(target, 0, ga_flags); - } - } - return parameters; -} - -Targets *GameScript::ProtectedBy(Scriptable *Sender, Targets *parameters, int ga_flags) -{ - Actor *actor = (Actor *) parameters->GetTarget(0, ST_ACTOR); - if (!actor) { - if (Sender->Type==ST_ACTOR) { - actor = (Actor *) Sender; - } - } - parameters->Clear(); - if (actor) { - Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastProtectee); - if (target) { - parameters->AddTarget(target, 0, ga_flags); - } - } - return parameters; -} - -Targets *GameScript::LastCommandedBy(Scriptable *Sender, Targets *parameters, int ga_flags) -{ - Actor *actor = (Actor *) parameters->GetTarget(0, ST_ACTOR); - if (!actor) { - if (Sender->Type==ST_ACTOR) { - actor = (Actor *) Sender; - } - } - parameters->Clear(); - if (actor) { - Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastCommander); - if (target) { - parameters->AddTarget(target, 0, ga_flags); - } - } - return parameters; -} - -// this is essentially a LastTargetedBy(0) - or MySelf -// but IWD2 defines it -Targets *GameScript::MyTarget(Scriptable *Sender, Targets *parameters, int ga_flags) -{ - return GetMyTarget(Sender, NULL, parameters, ga_flags); -} - -Targets *GameScript::LastTargetedBy(Scriptable *Sender, Targets *parameters, int ga_flags) -{ - Actor *actor = (Actor *) parameters->GetTarget(0, ST_ACTOR); - return GetMyTarget(Sender, actor, parameters, ga_flags); -} - -Targets *GameScript::LastAttackerOf(Scriptable *Sender, Targets *parameters, int ga_flags) -{ - Actor *actor = (Actor *) parameters->GetTarget(0, ST_ACTOR); - if (!actor) { - if (Sender->Type==ST_ACTOR) { - actor = (Actor *) Sender; - } - } - parameters->Clear(); - if (actor) { - Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastAttacker); - if (target) { - parameters->AddTarget(target, 0, ga_flags); - } - } - return parameters; -} - -Targets *GameScript::LastHitter(Scriptable *Sender, Targets *parameters, int ga_flags) -{ - Actor *actor = (Actor *) parameters->GetTarget(0, ST_ACTOR); - if (!actor) { - if (Sender->Type==ST_ACTOR) { - actor = (Actor *) Sender; - } - } - parameters->Clear(); - if (actor) { - Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastHitter); - if (target) { - parameters->AddTarget(target, 0, ga_flags); - } - } - return parameters; -} - -Targets *GameScript::LeaderOf(Scriptable *Sender, Targets *parameters, int ga_flags) -{ - Actor *actor = (Actor *) parameters->GetTarget(0, ST_ACTOR); - if (!actor) { - if (Sender->Type==ST_ACTOR) { - actor = (Actor *) Sender; - } - } - parameters->Clear(); - if (actor) { - Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastFollowed); - if (target) { - parameters->AddTarget(target, 0, ga_flags); - } - } - return parameters; -} - -Targets *GameScript::LastTalkedToBy(Scriptable *Sender, Targets *parameters, int ga_flags) -{ - Actor *actor = (Actor *) parameters->GetTarget(0, ST_ACTOR); - if (!actor) { - if (Sender->Type==ST_ACTOR) { - actor = (Actor *) Sender; - } - } - parameters->Clear(); - if (actor) { - Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastTalker); - if (target) { - parameters->AddTarget(target, 0, ga_flags); - } - } - return parameters; -} - -Targets *GameScript::LastSummonerOf(Scriptable* Sender, Targets *parameters, int ga_flags) -{ - Actor *actor = (Actor *) parameters->GetTarget(0, ST_ACTOR); - if (!actor) { - if (Sender->Type==ST_ACTOR) { - actor = (Actor *) Sender; - } - } - parameters->Clear(); - if (actor) { - Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastSummoner); - if (target) { - parameters->AddTarget(target, 0, ga_flags); - } - } - return parameters; -} - -Targets *GameScript::Player1(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - parameters->Clear(); - parameters->AddTarget(core->GetGame()->GetPC(0,false), 0, ga_flags); - return parameters; -} - -Targets *GameScript::Player1Fill(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - parameters->Clear(); - parameters->AddTarget(core->GetGame()->FindPC(1), 0, ga_flags); - return parameters; -} - -Targets *GameScript::Player2(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - parameters->Clear(); - parameters->AddTarget(core->GetGame()->GetPC(1,false), 0, ga_flags); - return parameters; -} - -Targets *GameScript::Player2Fill(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - parameters->Clear(); - parameters->AddTarget(core->GetGame()->FindPC(2), 0, ga_flags); - return parameters; -} - -Targets *GameScript::Player3(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - parameters->Clear(); - parameters->AddTarget(core->GetGame()->GetPC(2,false), 0, ga_flags); - return parameters; -} - -Targets *GameScript::Player3Fill(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - parameters->Clear(); - parameters->AddTarget(core->GetGame()->FindPC(3), 0, ga_flags); - return parameters; -} - -Targets *GameScript::Player4(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - parameters->Clear(); - parameters->AddTarget(core->GetGame()->GetPC(3,false), 0, ga_flags); - return parameters; -} - -Targets *GameScript::Player4Fill(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - parameters->Clear(); - parameters->AddTarget(core->GetGame()->FindPC(4), 0, ga_flags); - return parameters; -} - -Targets *GameScript::Player5(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - parameters->Clear(); - parameters->AddTarget(core->GetGame()->GetPC(4,false), 0, ga_flags); - return parameters; -} - -Targets *GameScript::Player5Fill(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - parameters->Clear(); - parameters->AddTarget(core->GetGame()->FindPC(5), 0, ga_flags); - return parameters; -} - -Targets *GameScript::Player6(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - parameters->Clear(); - parameters->AddTarget(core->GetGame()->GetPC(5,false), 0, ga_flags); - return parameters; -} - -Targets *GameScript::Player6Fill(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - parameters->Clear(); - parameters->AddTarget(core->GetGame()->FindPC(6), 0, ga_flags); - return parameters; -} - -Targets *GameScript::Player7(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - parameters->Clear(); - parameters->AddTarget(core->GetGame()->GetPC(6,false), 0, ga_flags); - return parameters; -} - -Targets *GameScript::Player7Fill(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - parameters->Clear(); - parameters->AddTarget(core->GetGame()->FindPC(7), 0, ga_flags); - return parameters; -} - -Targets *GameScript::Player8(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - parameters->Clear(); - parameters->AddTarget(core->GetGame()->GetPC(7,false), 0, ga_flags); - return parameters; -} - -Targets *GameScript::Player8Fill(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - parameters->Clear(); - parameters->AddTarget(core->GetGame()->FindPC(8), 0, ga_flags); - return parameters; -} - -Targets *GameScript::BestAC(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - targetlist::iterator m; - const targettype *t = parameters->GetFirstTarget(m, ST_ACTOR); - if (!t) { - return parameters; - } - Scriptable *scr=t->actor; - Actor *actor=(Actor *) scr; - int bestac=actor->GetStat(IE_ARMORCLASS); - // assignment in while - while ( (t = parameters->GetNextTarget(m, ST_ACTOR) ) ) { - actor = (Actor *) t->actor; - int ac=actor->GetStat(IE_ARMORCLASS); - if (bestacactor; - } - } - - parameters->Clear(); - parameters->AddTarget(scr, 0, ga_flags); - return parameters; -} - -/*no idea why this object exists since the gender could be filtered easier*/ -Targets *GameScript::StrongestOfMale(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - targetlist::iterator m; - const targettype *t = parameters->GetFirstTarget(m, ST_ACTOR); - if (!t) { - return parameters; - } - int pos=-1; - int worsthp=-1; - Scriptable *scr = NULL; - //assignment intentional - while ( (t = parameters->GetNextTarget(m, ST_ACTOR) ) ) { - Actor *actor = (Actor *) t->actor; - if (actor->GetStat(IE_SEX)!=SEX_MALE) continue; - int hp=actor->GetStat(IE_HITPOINTS); - if ((pos==-1) || (worsthpactor; - } - } - parameters->Clear(); - if (scr) { - parameters->AddTarget(scr, 0, ga_flags); - } - return parameters; -} - -Targets *GameScript::StrongestOf(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - targetlist::iterator m; - const targettype *t = parameters->GetFirstTarget(m, ST_ACTOR); - if (!t) { - return parameters; - } - Scriptable *scr=t->actor; - Actor *actor=(Actor *) scr; - int besthp=actor->GetStat(IE_HITPOINTS); - // assignment in while - while ( (t = parameters->GetNextTarget(m, ST_ACTOR) ) ) { - actor = (Actor *) t->actor; - int hp=actor->GetStat(IE_HITPOINTS); - if (besthpactor; - } - } - parameters->Clear(); - parameters->AddTarget(scr, 0, ga_flags); - return parameters; -} - -Targets *GameScript::WeakestOf(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - targetlist::iterator m; - const targettype *t = parameters->GetFirstTarget(m, ST_ACTOR); - if (!t) { - return parameters; - } - Scriptable *scr=t->actor; - Actor *actor=(Actor *) scr; - int worsthp=actor->GetStat(IE_HITPOINTS); - // assignment in while - while ( (t = parameters->GetNextTarget(m, ST_ACTOR) ) ) { - actor = (Actor *) t->actor; - int hp=actor->GetStat(IE_HITPOINTS); - if (worsthp>hp) { - worsthp=hp; - scr=t->actor; - } - } - parameters->Clear(); - parameters->AddTarget(scr, 0, ga_flags); - return parameters; -} - -Targets *GameScript::WorstAC(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - targetlist::iterator m; - const targettype *t = parameters->GetFirstTarget(m, ST_ACTOR); - if (!t) { - return parameters; - } - Scriptable *scr=t->actor; - Actor *actor=(Actor *) scr; - int worstac=actor->GetStat(IE_ARMORCLASS); - // assignment in while - while ( (t = parameters->GetNextTarget(m, ST_ACTOR) ) ) { - actor = (Actor *) t->actor; - int ac=actor->GetStat(IE_ARMORCLASS); - if (worstac>ac) { - worstac=ac; - scr=t->actor; - } - } - parameters->Clear(); - parameters->AddTarget(scr, 0, ga_flags); - return parameters; -} - -Targets *GameScript::MostDamagedOf(Scriptable* Sender, Targets *parameters, int ga_flags) -{ - //Original engines restrict this to the PCs... - /*targetlist::iterator m; - const targettype *t = parameters->GetFirstTarget(m, ST_ACTOR); - if (!t) { - return parameters; - } - Scriptable *scr = t->actor; - Actor *actor=(Actor *) scr; - int worsthp=actor->GetStat(IE_MAXHITPOINTS)-actor->GetBase(IE_HITPOINTS); - // assignment in while - while ( (t = parameters->GetNextTarget(m, ST_ACTOR) ) ) { - actor = (Actor *) t->actor; - int hp=actor->GetStat(IE_MAXHITPOINTS)-actor->GetBase(IE_HITPOINTS); - if (worsthp>hp) { - worsthp=hp; - scr=t->actor; - } - } - parameters->Clear(); - parameters->AddTarget(scr, 0, ga_flags); - return parameters;*/ - Map* area = Sender->GetCurrentArea() ; - Game *game = core->GetGame(); - Scriptable* scr = NULL ; - int worsthp = 0xffff ; - int i = game->GetPartySize(false); - while (i--) { - Actor *actor = game->GetPC(i, false); - if(actor->GetCurrentArea() == area) { - int hp=actor->GetStat(IE_MAXHITPOINTS)-actor->GetBase(IE_HITPOINTS); - if (worsthp>hp) { - worsthp=hp; - scr=actor; - } - } - } - parameters->Clear(); - parameters->AddTarget(scr, 0, ga_flags); - return parameters; -} -Targets *GameScript::LeastDamagedOf(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - targetlist::iterator m; - const targettype *t = parameters->GetFirstTarget(m, ST_ACTOR); - if (!t) { - return parameters; - } - Scriptable *scr = t->actor; - Actor *actor = (Actor *) scr; - int besthp=actor->GetStat(IE_MAXHITPOINTS)-actor->GetBase(IE_HITPOINTS); - // assignment in while - while ( (t = parameters->GetNextTarget(m, ST_ACTOR) ) ) { - actor = (Actor *) t->actor; - int hp=actor->GetStat(IE_MAXHITPOINTS)-actor->GetBase(IE_HITPOINTS); - if (besthpactor; - } - } - parameters->Clear(); - parameters->AddTarget(scr, 0, ga_flags); - return parameters; -} - -Targets *GameScript::Farthest(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - const targettype *t = parameters->GetLastTarget(ST_ACTOR); - parameters->Clear(); - if (t) { - parameters->AddTarget(t->actor, 0, ga_flags); - } - return parameters; -} - -Targets *GameScript::FarthestEnemyOf(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - return XthNearestEnemyOf(parameters, -1, ga_flags); -} - -Targets *GameScript::NearestEnemyOf(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - return XthNearestEnemyOf(parameters, 0, ga_flags); -} - -Targets *GameScript::SecondNearestEnemyOf(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - return XthNearestEnemyOf(parameters, 1, ga_flags); -} - -Targets *GameScript::ThirdNearestEnemyOf(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - return XthNearestEnemyOf(parameters, 2, ga_flags); -} - -Targets *GameScript::FourthNearestEnemyOf(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - return XthNearestEnemyOf(parameters, 3, ga_flags); -} - -Targets *GameScript::FifthNearestEnemyOf(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - return XthNearestEnemyOf(parameters, 4, ga_flags); -} - -Targets *GameScript::SixthNearestEnemyOf(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - return XthNearestEnemyOf(parameters, 5, ga_flags); -} - -Targets *GameScript::SeventhNearestEnemyOf(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - return XthNearestEnemyOf(parameters, 6, ga_flags); -} - -Targets *GameScript::EighthNearestEnemyOf(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - return XthNearestEnemyOf(parameters, 7, ga_flags); -} - -Targets *GameScript::NinthNearestEnemyOf(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - return XthNearestEnemyOf(parameters, 8, ga_flags); -} - -Targets *GameScript::TenthNearestEnemyOf(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - return XthNearestEnemyOf(parameters, 9, ga_flags); -} - -Targets *GameScript::NearestEnemySummoned(Scriptable* Sender, Targets *parameters, int ga_flags) -{ - return ClosestEnemySummoned(Sender, parameters, ga_flags); -} - -Targets *GameScript::NearestEnemyOfType(Scriptable* Sender, Targets *parameters, int ga_flags) -{ - return XthNearestEnemyOfType(Sender, parameters, 0, ga_flags); -} - -Targets *GameScript::SecondNearestEnemyOfType(Scriptable* Sender, Targets *parameters, int ga_flags) -{ - return XthNearestEnemyOfType(Sender, parameters, 1, ga_flags); -} - -Targets *GameScript::ThirdNearestEnemyOfType(Scriptable* Sender, Targets *parameters, int ga_flags) -{ - return XthNearestEnemyOfType(Sender, parameters, 2, ga_flags); -} - -Targets *GameScript::FourthNearestEnemyOfType(Scriptable* Sender, Targets *parameters, int ga_flags) -{ - return XthNearestEnemyOfType(Sender, parameters, 3, ga_flags); -} - -Targets *GameScript::FifthNearestEnemyOfType(Scriptable* Sender, Targets *parameters, int ga_flags) -{ - return XthNearestEnemyOfType(Sender, parameters, 4, ga_flags); -} - -Targets *GameScript::SixthNearestEnemyOfType(Scriptable* Sender, Targets *parameters, int ga_flags) -{ - return XthNearestEnemyOfType(Sender, parameters, 5, ga_flags); -} - -Targets *GameScript::SeventhNearestEnemyOfType(Scriptable* Sender, Targets *parameters, int ga_flags) -{ - return XthNearestEnemyOfType(Sender, parameters, 6, ga_flags); -} - -Targets *GameScript::EighthNearestEnemyOfType(Scriptable* Sender, Targets *parameters, int ga_flags) -{ - return XthNearestEnemyOfType(Sender, parameters, 7, ga_flags); -} - -Targets *GameScript::NinthNearestEnemyOfType(Scriptable* Sender, Targets *parameters, int ga_flags) -{ - return XthNearestEnemyOfType(Sender, parameters, 8, ga_flags); -} - -Targets *GameScript::TenthNearestEnemyOfType(Scriptable* Sender, Targets *parameters, int ga_flags) -{ - return XthNearestEnemyOfType(Sender, parameters, 9, ga_flags); -} - -Targets *GameScript::NearestMyGroupOfType(Scriptable* Sender, Targets *parameters, int ga_flags) -{ - return XthNearestMyGroupOfType(Sender, parameters, 0, ga_flags); -} - -Targets *GameScript::SecondNearestMyGroupOfType(Scriptable* Sender, Targets *parameters, int ga_flags) -{ - return XthNearestMyGroupOfType(Sender, parameters, 1, ga_flags); -} - -Targets *GameScript::ThirdNearestMyGroupOfType(Scriptable* Sender, Targets *parameters, int ga_flags) -{ - return XthNearestMyGroupOfType(Sender, parameters, 2, ga_flags); -} - -Targets *GameScript::FourthNearestMyGroupOfType(Scriptable* Sender, Targets *parameters, int ga_flags) -{ - return XthNearestMyGroupOfType(Sender, parameters, 3, ga_flags); -} - -Targets *GameScript::FifthNearestMyGroupOfType(Scriptable* Sender, Targets *parameters, int ga_flags) -{ - return XthNearestMyGroupOfType(Sender, parameters, 4, ga_flags); -} - -Targets *GameScript::SixthNearestMyGroupOfType(Scriptable* Sender, Targets *parameters, int ga_flags) -{ - return XthNearestMyGroupOfType(Sender, parameters, 5, ga_flags); -} - -Targets *GameScript::SeventhNearestMyGroupOfType(Scriptable* Sender, Targets *parameters, int ga_flags) -{ - return XthNearestMyGroupOfType(Sender, parameters, 6, ga_flags); -} - -Targets *GameScript::EighthNearestMyGroupOfType(Scriptable* Sender, Targets *parameters, int ga_flags) -{ - return XthNearestMyGroupOfType(Sender, parameters, 7, ga_flags); -} - -Targets *GameScript::NinthNearestMyGroupOfType(Scriptable* Sender, Targets *parameters, int ga_flags) -{ - return XthNearestMyGroupOfType(Sender, parameters, 8, ga_flags); -} - -Targets *GameScript::TenthNearestMyGroupOfType(Scriptable* Sender, Targets *parameters, int ga_flags) -{ - return XthNearestMyGroupOfType(Sender, parameters, 9, ga_flags); -} - -/* returns only living PC's? if not, alter getpartysize/getpc flag*/ -Targets *GameScript::NearestPC(Scriptable* Sender, Targets *parameters, int ga_flags) -{ - parameters->Clear(); - Map *map = Sender->GetCurrentArea(); - Game *game = core->GetGame(); - int i = game->GetPartySize(true); - int mindist = -1; - Actor *ac = NULL; - while (i--) { - Actor *newactor=game->GetPC(i,true); - //NearestPC for PC's will not give themselves as a result - //this might be different from the original engine - if ((Sender->Type==ST_ACTOR) && (newactor == (Actor *) Sender)) { - continue; - } - if (newactor->GetCurrentArea()!=map) { - continue; - } - int dist = Distance(Sender, newactor); - if ( (mindist == -1) || (distAddTarget(ac, 0, ga_flags); - } - return parameters; -} - -Targets *GameScript::Nearest(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - return XthNearestOf(parameters, 0, ga_flags); -} - -Targets *GameScript::SecondNearest(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - return XthNearestOf(parameters, 1, ga_flags); -} - -Targets *GameScript::ThirdNearest(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - return XthNearestOf(parameters, 2, ga_flags); -} - -Targets *GameScript::FourthNearest(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - return XthNearestOf(parameters, 3, ga_flags); -} - -Targets *GameScript::FifthNearest(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - return XthNearestOf(parameters, 4, ga_flags); -} - -Targets *GameScript::SixthNearest(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - return XthNearestOf(parameters, 5, ga_flags); -} - -Targets *GameScript::SeventhNearest(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - return XthNearestOf(parameters, 6, ga_flags); -} - -Targets *GameScript::EighthNearest(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - return XthNearestOf(parameters, 7, ga_flags); -} - -Targets *GameScript::NinthNearest(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - return XthNearestOf(parameters, 8, ga_flags); -} - -Targets *GameScript::TenthNearest(Scriptable* /*Sender*/, Targets *parameters, int ga_flags) -{ - return XthNearestOf(parameters, 9, ga_flags); -} - -Targets *GameScript::SelectedCharacter(Scriptable* Sender, Targets* parameters, int ga_flags) -{ - Map *cm = Sender->GetCurrentArea(); - parameters->Clear(); - int i = cm->GetActorCount(true); - while (i--) { - Actor *ac=cm->GetActor(i,true); - if (ac->GetCurrentArea()!=cm) { - continue; - } - if (ac->IsSelected()) { - parameters->AddTarget(ac, Distance(Sender, ac), ga_flags ); - } - } - return parameters; -} - -Targets *GameScript::Nothing(Scriptable* /*Sender*/, Targets* parameters, int /*ga_flags*/) -{ - parameters->Clear(); - return parameters; -} - -//------------------------------------------------------------- -// IDS Functions -//------------------------------------------------------------- - -int GameScript::ID_Alignment(Actor *actor, int parameter) -{ - int value = actor->GetStat( IE_ALIGNMENT ); - int a = parameter&15; - if (a) { - if (a != ( value & 15 )) { - return 0; - } - } - a = parameter & 240; - if (a) { - if (a != ( value & 240 )) { - return 0; - } - } - return 1; -} - -int GameScript::ID_Allegiance(Actor *actor, int parameter) -{ - int value = actor->GetStat( IE_EA ); - switch (parameter) { - case EA_GOODCUTOFF: - return value <= EA_GOODCUTOFF; - - case EA_NOTGOOD: - return value >= EA_NOTGOOD; - - case EA_NOTNEUTRAL: - return value >=EA_EVILCUTOFF || value <= EA_GOODCUTOFF; - - case EA_NOTEVIL: - return value <= EA_NOTEVIL; - - case EA_EVILCUTOFF: - return value >= EA_EVILCUTOFF; - - case 0: - case EA_ANYTHING: - return true; - - } - //default - return parameter == value; -} - -// *_ALL constants are different in iwd2 due to different classes (see note below) -// bard, cleric, druid, fighter, mage, paladin, ranger, thief -static const int all_bg_classes[] = { 206, 204, 208, 203, 202, 207, 209, 205 }; -static const int all_iwd2_classes[] = { 202, 203, 204, 205, 209, 206, 207, 208 }; - -// Dual-classed characters will detect only as their new class until their -// original class is re-activated, when they will detect as a multi-class -// GetClassLevel takes care of this automatically! -inline bool idclass(Actor *actor, int parameter, bool iwd2) { - int value = 0; - if (parameter < 202 || parameter > 209) { - value = actor->GetStat(IE_CLASS); - return parameter==value; - } - - const int *classes; - if (iwd2) { - classes = all_iwd2_classes; - } else { - classes = all_bg_classes; - } - - // we got one of the *_ALL values - if (parameter == classes[4]) { - // MAGE_ALL (also sorcerers) - value = actor->GetMageLevel() + actor->GetSorcererLevel(); - } else if (parameter == classes[3]) { - // FIGHTER_ALL (also monks) - value = actor->GetFighterLevel() + actor->GetMonkLevel(); - } else if (parameter == classes[1]) { - // CLERIC_ALL - value = actor->GetClericLevel(); - } else if (parameter == classes[7]) { - // THIEF_ALL - value = actor->GetThiefLevel(); - } else if (parameter == classes[0]) { - // BARD_ALL - value = actor->GetBardLevel(); - } else if (parameter == classes[5]) { - // PALADIN_ALL - value = actor->GetPaladinLevel(); - } else if (parameter == classes[2]) { - // DRUID_ALL - value = actor->GetDruidLevel(); - } else if (parameter == classes[6]) { - // RANGER_ALL - value = actor->GetRangerLevel(); - } - return value > 0; -} - -int GameScript::ID_Class(Actor *actor, int parameter) -{ - if (core->HasFeature(GF_3ED_RULES)) { - //iwd2 has different values, see also the note for AVClass - return idclass(actor, parameter, 1); - } - return idclass(actor, parameter, 0); -} - -// IE_CLASS holds only one class, not a bitmask like with iwd2 kits. The ids values -// are friendly to binary comparison, so we just need to build such a class value -int GameScript::ID_ClassMask(Actor *actor, int parameter) -{ - // maybe we're lucky... - int value = actor->GetStat(IE_CLASS); - if (parameter&(1<<(value-1))) return 1; - - // otherwise iterate over all the classes - value = actor->GetClassMask(); - - if (parameter&value) return 1; - return 0; -} - -// this is only present in iwd2 -// the function is identical to ID_Class, but uses the class20 IDS, -// iwd2's class.ids is different than the rest, while class20 is identical (remnant) -int GameScript::ID_AVClass(Actor *actor, int parameter) -{ - return idclass(actor, parameter, 0); -} - -int GameScript::ID_Race(Actor *actor, int parameter) -{ - int value = actor->GetStat(IE_RACE); - return parameter==value; -} - -int GameScript::ID_Subrace(Actor *actor, int parameter) -{ - int value = actor->GetStat(IE_SUBRACE); - return parameter==value; -} - -int GameScript::ID_Faction(Actor *actor, int parameter) -{ - int value = actor->GetStat(IE_FACTION); - return parameter==value; -} - -int GameScript::ID_Team(Actor *actor, int parameter) -{ - int value = actor->GetStat(IE_TEAM); - return parameter==value; -} - -int GameScript::ID_Gender(Actor *actor, int parameter) -{ - int value = actor->GetStat(IE_SEX); - return parameter==value; -} - -int GameScript::ID_General(Actor *actor, int parameter) -{ - int value = actor->GetStat(IE_GENERAL); - return parameter==value; -} - -int GameScript::ID_Specific(Actor *actor, int parameter) -{ - int value = actor->GetStat(IE_SPECIFIC); - return parameter==value; -} diff --git a/project/jni/application/gemrb/gemrb/core/GameScript/Triggers.cpp b/project/jni/application/gemrb/gemrb/core/GameScript/Triggers.cpp deleted file mode 100644 index 4f8f79e1e..000000000 --- a/project/jni/application/gemrb/gemrb/core/GameScript/Triggers.cpp +++ /dev/null @@ -1,4105 +0,0 @@ -/* 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 "GameScript/GameScript.h" - -#include "GameScript/GSUtils.h" -#include "GameScript/Matching.h" - -#include "win32def.h" - -#include "Calendar.h" -#include "DialogHandler.h" -#include "Game.h" -#include "GameData.h" -#include "Polygon.h" -#include "Video.h" -#include "GUI/GameControl.h" -#include "math.h" //needs for acos -#include "Scriptable/Container.h" -#include "Scriptable/Door.h" -#include "Scriptable/InfoPoint.h" - -//------------------------------------------------------------- -// Trigger Functions -//------------------------------------------------------------- -int GameScript::BreakingPoint(Scriptable* Sender, Trigger* /*parameters*/) -{ - int value=GetHappiness(Sender, core->GetGame()->Reputation ); - return value < -300; -} - -int GameScript::Reaction(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr || scr->Type != ST_ACTOR) { - parameters->Dump(); - return 0; - } - int value = GetReaction(((Actor*) scr), Sender); - return value == parameters->int0Parameter; -} - -int GameScript::ReactionGT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr || scr->Type != ST_ACTOR) { - parameters->Dump(); - return 0; - } - int value = GetReaction(((Actor*) scr), Sender); - return value > parameters->int0Parameter; -} - -int GameScript::ReactionLT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr || scr->Type != ST_ACTOR) { - parameters->Dump(); - return 0; - } - int value = GetReaction(((Actor*) scr), Sender); - return value < parameters->int0Parameter; -} - -int GameScript::Happiness(Scriptable* Sender, Trigger* parameters) -{ - int value=GetHappiness(Sender, core->GetGame()->Reputation ); - return value == parameters->int0Parameter; -} - -int GameScript::HappinessGT(Scriptable* Sender, Trigger* parameters) -{ - int value=GetHappiness(Sender, core->GetGame()->Reputation ); - return value > parameters->int0Parameter; -} - -int GameScript::HappinessLT(Scriptable* Sender, Trigger* parameters) -{ - int value=GetHappiness(Sender, core->GetGame()->Reputation ); - return value < parameters->int0Parameter; -} - -int GameScript::Reputation(Scriptable* /*Sender*/, Trigger* parameters) -{ - return core->GetGame()->Reputation/10 == (ieDword) parameters->int0Parameter; -} - -int GameScript::ReputationGT(Scriptable* /*Sender*/, Trigger* parameters) -{ - return core->GetGame()->Reputation/10 > (ieDword) parameters->int0Parameter; -} - -int GameScript::ReputationLT(Scriptable* /*Sender*/, Trigger* parameters) -{ - return core->GetGame()->Reputation/10 < (ieDword) parameters->int0Parameter; -} - -int GameScript::Alignment(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr || scr->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) scr; - return ID_Alignment( actor, parameters->int0Parameter); -} - -int GameScript::Allegiance(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr || scr->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) scr; - return ID_Allegiance( actor, parameters->int0Parameter); -} - -//should return *_ALL stuff -int GameScript::Class(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr || scr->Type != ST_ACTOR) { - return 0; - } - Actor* actor = (Actor*)scr; - return ID_Class( actor, parameters->int0Parameter); -} - -int GameScript::ClassEx(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr || scr->Type != ST_ACTOR) { - return 0; - } - Actor* actor = (Actor*)scr; - return ID_AVClass( actor, parameters->int0Parameter); -} - -int GameScript::Faction(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr || scr->Type != ST_ACTOR) { - return 0; - } - Actor* actor = (Actor*)scr; - return ID_Faction( actor, parameters->int0Parameter); -} - -int GameScript::Team(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr || scr->Type != ST_ACTOR) { - return 0; - } - Actor* actor = (Actor*)scr; - return ID_Team( actor, parameters->int0Parameter); -} - -int GameScript::SubRace(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr || scr->Type != ST_ACTOR) { - return 0; - } - Actor* actor = (Actor*)scr; - //subrace trigger uses a weird system, cannot use ID_* - //return ID_Subrace( actor, parameters->int0Parameter); - int value = actor->GetStat(IE_SUBRACE); - if (value) { - value |= actor->GetStat(IE_RACE)<<16; - } - if (value == parameters->int0Parameter) { - return 1; - } - return 0; -} - -//if object parameter is given (gemrb) it is used -//otherwise it works on the current object (iwd2) -int GameScript::IsTeamBitOn(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = Sender; - if (parameters->objectParameter) { - scr = GetActorFromObject( Sender, parameters->objectParameter ); - } - if (!scr || scr->Type != ST_ACTOR) { - return 0; - } - Actor* actor = (Actor*)scr; - if (actor->GetStat(IE_TEAM) & parameters->int0Parameter) { - return 1; - } - return 0; -} - -int GameScript::NearbyDialog(Scriptable* Sender, Trigger* parameters) -{ - Actor *target = Sender->GetCurrentArea()->GetActorByDialog(parameters->string0Parameter); - if ( !target ) { - return 0; - } - return CanSee( Sender, target, true, GA_NO_DEAD | GA_NO_HIDDEN ); -} - -//atm this checks for InParty and See, it is unsure what is required -int GameScript::IsValidForPartyDialog(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - scr = Sender; - } - if (scr->Type != ST_ACTOR) { - return 0; - } - Actor *target = (Actor *) scr; - //inparty returns -1 if not in party - if (core->GetGame()->InParty( target )<0) { - return 0; - } - //don't accept parties currently in dialog! - //this might disturb some modders, but this is the correct behaviour - //for example the aaquatah dialog in irenicus dungeon depends on it - GameControl *gc = core->GetGameControl(); - Actor *pc = (Actor *) scr; - if (pc->GetGlobalID() == gc->dialoghandler->targetID || pc->GetGlobalID()==gc->dialoghandler->speakerID) { - return 0; - } - - //don't accept parties with the no interrupt flag - //this fixes bug #2573808 on gamescript level - //(still someone has to turn the no interrupt flag off) - if(!pc->GetDialog(GD_CHECK)) { - return 0; - } - return CanSee( Sender, target, false, GA_NO_DEAD ); -} - -int GameScript::InParty(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr; - - if (parameters->objectParameter) { - scr = GetActorFromObject( Sender, parameters->objectParameter ); - } else { - scr = Sender; - } - if (!scr || scr->Type != ST_ACTOR) { - return 0; - } - Actor *tar = (Actor *) scr; - if (core->GetGame()->InParty( tar ) <0) { - return 0; - } - //don't allow dead, don't allow maze and similar effects - if (tar->ValidTarget(GA_NO_DEAD|GA_NO_HIDDEN)) { - return 1; - } - return 0; -} - -int GameScript::InPartyAllowDead(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr; - - if (parameters->objectParameter) { - scr = GetActorFromObject( Sender, parameters->objectParameter ); - } else { - scr = Sender; - } - if (!scr || scr->Type != ST_ACTOR) { - return 0; - } - return core->GetGame()->InParty( ( Actor * ) scr ) >= 0 ? 1 : 0; -} - -int GameScript::InPartySlot(Scriptable* Sender, Trigger* parameters) -{ - Actor *actor = core->GetGame()->GetPC(parameters->int0Parameter, false); - return MatchActor(Sender, actor->GetGlobalID(), parameters->objectParameter); -} - -int GameScript::Exists(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - return 0; - } - return 1; -} - -int GameScript::IsAClown(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr || scr->Type!=ST_ACTOR) { - return 0; - } - return 1; -} - -int GameScript::IsGabber(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr || scr->Type!=ST_ACTOR) { - return 0; - } - if (scr->GetGlobalID() == core->GetGameControl()->dialoghandler->speakerID) - return 1; - return 0; -} - -int GameScript::IsActive(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - return 0; - } - if (scr->GetInternalFlag()&IF_ACTIVE) { - return 1; - } - return 0; -} - -int GameScript::InTrap(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - return 0; - } - if (scr->GetInternalFlag()&IF_INTRAP) { - return 1; - } - return 0; -} - -/* checks if targeted actor is in the specified region - GemRB allows different regions, referenced by int0Parameter - The polygons are stored in island.2da files */ -int GameScript::OnIsland(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - return 0; - } - Gem_Polygon *p = GetPolygon2DA(parameters->int0Parameter); - if (!p) { - return 0; - } - return p->PointIn(scr->Pos); -} - -int GameScript::School(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr || scr->Type!=ST_ACTOR) { - return 0; - } - Actor* actor = (Actor *) scr; - //only the low 2 bytes count - //the School values start from 1 to 9 and the first school value is 0x40 - //so this mild hack will do - if ( actor->GetStat(IE_KIT) == (ieDword) (0x20<int0Parameter)) { - return 1; - } - return 0; -} - -int GameScript::Kit(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr || scr->Type!=ST_ACTOR) { - return 0; - } - Actor* actor = (Actor *) scr; - - ieDword kit = actor->GetStat(IE_KIT); - //TODO: fix baseclass / barbarian confusion - - //IWD2 style kit matching (also used for mage schools) - if (kit == (ieDword) (parameters->int0Parameter)) { - return 1; - } - //BG2 style kit matching (not needed anymore?), we do it on load - //kit = (kit>>16)|(kit<<16); - if ( kit == (ieDword) (parameters->int0Parameter)) { - return 1; - } - return 0; -} - -int GameScript::General(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - scr = Sender; - } - if (scr->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) scr; - if (actor == NULL) { - return 0; - } - return ID_General(actor, parameters->int0Parameter); -} - -int GameScript::Specifics(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - scr = Sender; - } - if (scr->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) scr; - if (actor == NULL) { - return 0; - } - return ID_Specific(actor, parameters->int0Parameter); -} - -int GameScript::BitCheck(Scriptable* Sender, Trigger* parameters) -{ - bool valid=true; - - ieDword value = CheckVariable(Sender, parameters->string0Parameter, &valid ); - if (valid) { - if ( value & parameters->int0Parameter ) return 1; - } - return 0; -} - -int GameScript::BitCheckExact(Scriptable* Sender, Trigger* parameters) -{ - bool valid=true; - - ieDword value = CheckVariable(Sender, parameters->string0Parameter, &valid ); - if (valid) { - ieDword tmp = (ieDword) parameters->int0Parameter ; - if ((value & tmp) == tmp) return 1; - } - return 0; -} - -//BM_OR would make sense only if this trigger changes the value of the variable -//should I do that??? -int GameScript::BitGlobal_Trigger(Scriptable* Sender, Trigger* parameters) -{ - bool valid=true; - - ieDword value = CheckVariable(Sender, parameters->string0Parameter, &valid ); - if (valid) { - HandleBitMod(value, parameters->int0Parameter, parameters->int1Parameter); - if (value!=0) return 1; - } - return 0; -} - -int GameScript::GlobalOrGlobal_Trigger(Scriptable* Sender, Trigger* parameters) -{ - bool valid=true; - - ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, &valid ); - if (valid) { - if ( value1 ) return 1; - ieDword value2 = CheckVariable(Sender, parameters->string1Parameter, &valid ); - if (valid) { - if ( value2 ) return 1; - } - } - return 0; -} - -int GameScript::GlobalAndGlobal_Trigger(Scriptable* Sender, Trigger* parameters) -{ - bool valid=true; - - ieDword value1 = CheckVariable( Sender, parameters->string0Parameter, &valid ); - if (valid && value1) { - ieDword value2 = CheckVariable( Sender, parameters->string1Parameter, &valid ); - if (valid && value2) return 1; - } - return 0; -} - -int GameScript::GlobalBAndGlobal_Trigger(Scriptable* Sender, Trigger* parameters) -{ - bool valid=true; - - ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, &valid ); - if (valid) { - ieDword value2 = CheckVariable(Sender, parameters->string1Parameter, &valid ); - if (valid) { - if ((value1& value2 ) != 0) return 1; - } - } - return 0; -} - -int GameScript::GlobalBAndGlobalExact(Scriptable* Sender, Trigger* parameters) -{ - bool valid=true; - - ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, &valid ); - if (valid) { - ieDword value2 = CheckVariable(Sender, parameters->string1Parameter, &valid ); - if (valid) { - if (( value1& value2 ) == value2) return 1; - } - } - return 0; -} - -int GameScript::GlobalBitGlobal_Trigger(Scriptable* Sender, Trigger* parameters) -{ - bool valid=true; - - ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, &valid ); - if (valid) { - ieDword value2 = CheckVariable(Sender, parameters->string1Parameter, &valid ); - if (valid) { - HandleBitMod( value1, value2, parameters->int1Parameter); - if (value1!=0) return 1; - } - } - return 0; -} - -//no what exactly this trigger would do, defined in iwd2, but never used -//i just assume it sets a global in the trigger block -int GameScript::TriggerSetGlobal(Scriptable* Sender, Trigger* parameters) -{ - SetVariable( Sender, parameters->string0Parameter, parameters->int0Parameter ); - return 1; -} - -//would this function also alter the variable? -int GameScript::Xor(Scriptable* Sender, Trigger* parameters) -{ - bool valid=true; - - ieDword value = CheckVariable(Sender, parameters->string0Parameter, &valid ); - if (valid) { - if (( value ^ parameters->int0Parameter ) != 0) return 1; - } - return 0; -} - -//TODO: -//no sprite is dead for iwd, they use KILL__CNT -int GameScript::NumDead(Scriptable* Sender, Trigger* parameters) -{ - ieDword value; - - if (core->HasFeature(GF_HAS_KAPUTZ) ) { - value = CheckVariable(Sender, parameters->string0Parameter, "KAPUTZ"); - } else { - ieVariable VariableName; - snprintf(VariableName, 32, core->GetDeathVarFormat(), parameters->string0Parameter); - value = CheckVariable(Sender, VariableName, "GLOBAL" ); - } - return ( value == (ieDword) parameters->int0Parameter ); -} - -int GameScript::NumDeadGT(Scriptable* Sender, Trigger* parameters) -{ - ieDword value; - - if (core->HasFeature(GF_HAS_KAPUTZ) ) { - value = CheckVariable(Sender, parameters->string0Parameter, "KAPUTZ"); - } else { - ieVariable VariableName; - snprintf(VariableName, 32, core->GetDeathVarFormat(), parameters->string0Parameter); - value = CheckVariable(Sender, VariableName, "GLOBAL" ); - } - return ( value > (ieDword) parameters->int0Parameter ); -} - -int GameScript::NumDeadLT(Scriptable* Sender, Trigger* parameters) -{ - ieDword value; - - if (core->HasFeature(GF_HAS_KAPUTZ) ) { - value = CheckVariable(Sender, parameters->string0Parameter, "KAPUTZ"); - } else { - ieVariable VariableName; - - snprintf(VariableName, 32, core->GetDeathVarFormat(), parameters->string0Parameter); - value = CheckVariable(Sender, VariableName, "GLOBAL" ); - } - return ( value < (ieDword) parameters->int0Parameter ); -} - -int GameScript::G_Trigger(Scriptable* Sender, Trigger* parameters) -{ - ieDwordSigned value = CheckVariable(Sender, parameters->string0Parameter, "GLOBAL" ); - return ( value == parameters->int0Parameter ); -} - -int GameScript::Global(Scriptable* Sender, Trigger* parameters) -{ - bool valid=true; - - ieDwordSigned value = CheckVariable(Sender, parameters->string0Parameter, &valid ); - if (valid) { - if ( value == parameters->int0Parameter ) return 1; - } - return 0; -} - -int GameScript::GLT_Trigger(Scriptable* Sender, Trigger* parameters) -{ - ieDwordSigned value = CheckVariable(Sender, parameters->string0Parameter,"GLOBAL" ); - return ( value < parameters->int0Parameter ); -} - -int GameScript::GlobalLT(Scriptable* Sender, Trigger* parameters) -{ - bool valid=true; - - ieDwordSigned value = CheckVariable(Sender, parameters->string0Parameter, &valid ); - if (valid) { - if ( value < parameters->int0Parameter ) return 1; - } - return 0; -} - -int GameScript::GGT_Trigger(Scriptable* Sender, Trigger* parameters) -{ - ieDwordSigned value = CheckVariable(Sender, parameters->string0Parameter, "GLOBAL" ); - return ( value > parameters->int0Parameter ); -} - -int GameScript::GlobalGT(Scriptable* Sender, Trigger* parameters) -{ - bool valid=true; - - ieDwordSigned value = CheckVariable(Sender, parameters->string0Parameter, &valid ); - if (valid) { - if ( value > parameters->int0Parameter ) return 1; - } - return 0; -} - -int GameScript::GlobalLTGlobal(Scriptable* Sender, Trigger* parameters) -{ - bool valid=true; - - ieDwordSigned value1 = CheckVariable(Sender, parameters->string0Parameter, &valid ); - if (valid) { - ieDwordSigned value2 = CheckVariable(Sender, parameters->string1Parameter, &valid ); - if (valid) { - if ( value1 < value2 ) return 1; - } - } - return 0; -} - -int GameScript::GlobalGTGlobal(Scriptable* Sender, Trigger* parameters) -{ - bool valid=true; - - ieDwordSigned value1 = CheckVariable(Sender, parameters->string0Parameter, &valid ); - if (valid) { - ieDwordSigned value2 = CheckVariable(Sender, parameters->string1Parameter, &valid ); - if (valid) { - if ( value1 > value2 ) return 1; - } - } - return 0; -} - -int GameScript::GlobalsEqual(Scriptable* Sender, Trigger* parameters) -{ - ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, "GLOBAL" ); - ieDword value2 = CheckVariable(Sender, parameters->string1Parameter, "GLOBAL" ); - return ( value1 == value2 ); -} - -int GameScript::GlobalsGT(Scriptable* Sender, Trigger* parameters) -{ - ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, "GLOBAL" ); - ieDword value2 = CheckVariable(Sender, parameters->string1Parameter, "GLOBAL" ); - return ( value1 > value2 ); -} - -int GameScript::GlobalsLT(Scriptable* Sender, Trigger* parameters) -{ - ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, "GLOBAL" ); - ieDword value2 = CheckVariable(Sender, parameters->string1Parameter, "GLOBAL" ); - return ( value1 < value2 ); -} - -int GameScript::LocalsEqual(Scriptable* Sender, Trigger* parameters) -{ - ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, "LOCALS" ); - ieDword value2 = CheckVariable(Sender, parameters->string1Parameter, "LOCALS" ); - return ( value1 == value2 ); -} - -int GameScript::LocalsGT(Scriptable* Sender, Trigger* parameters) -{ - ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, "LOCALS" ); - ieDword value2 = CheckVariable(Sender, parameters->string1Parameter, "LOCALS" ); - return ( value1 > value2 ); -} - -int GameScript::LocalsLT(Scriptable* Sender, Trigger* parameters) -{ - ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, "LOCALS" ); - ieDword value2 = CheckVariable(Sender, parameters->string1Parameter, "LOCALS" ); - return ( value1 < value2 ); -} - -int GameScript::RealGlobalTimerExact(Scriptable* Sender, Trigger* parameters) -{ - bool valid=true; - - ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, parameters->string1Parameter, &valid ); - if (valid && value1) { - ieDword value2 = core->GetGame()->RealTime; - if ( value1 == value2 ) return 1; - } - return 0; -} - -int GameScript::RealGlobalTimerExpired(Scriptable* Sender, Trigger* parameters) -{ - bool valid=true; - - ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, parameters->string1Parameter, &valid ); - if (valid && value1) { - if ( value1 < core->GetGame()->RealTime ) return 1; - } - return 0; -} - -int GameScript::RealGlobalTimerNotExpired(Scriptable* Sender, Trigger* parameters) -{ - bool valid=true; - - ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, parameters->string1Parameter, &valid ); - if (valid && value1) { - if ( value1 > core->GetGame()->RealTime ) return 1; - } - return 0; -} - -int GameScript::GlobalTimerExact(Scriptable* Sender, Trigger* parameters) -{ - bool valid=true; - - ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, parameters->string1Parameter, &valid ); - if (valid) { - if ( value1 == core->GetGame()->GameTime ) return 1; - } - return 0; -} - -int GameScript::GlobalTimerExpired(Scriptable* Sender, Trigger* parameters) -{ - bool valid=true; - - ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, parameters->string1Parameter, &valid ); - if (valid && value1) { - if ( value1 < core->GetGame()->GameTime ) return 1; - } - return 0; -} - -//globaltimernotexpired returns false if the timer doesn't exist -int GameScript::GlobalTimerNotExpired(Scriptable* Sender, Trigger* parameters) -{ - bool valid=true; - - ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, parameters->string1Parameter, &valid ); - if (valid && value1) { - if ( value1 > core->GetGame()->GameTime ) return 1; - } - return 0; -} - -//globaltimerstarted returns false if the timer doesn't exist -//is it the same as globaltimernotexpired? -int GameScript::GlobalTimerStarted(Scriptable* Sender, Trigger* parameters) -{ - bool valid=true; - - ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, parameters->string1Parameter, &valid ); - if (valid && value1) { - if ( value1 > core->GetGame()->GameTime ) return 1; - } - return 0; -} - -int GameScript::WasInDialog(Scriptable* Sender, Trigger* /*parameters*/) -{ - return Sender->MatchTrigger(trigger_wasindialog); -} - -int GameScript::OnCreation(Scriptable* Sender, Trigger* /*parameters*/) -{ - return Sender->MatchTrigger(trigger_oncreation); -} - -int GameScript::NumItemsParty(Scriptable* /*Sender*/, Trigger* parameters) -{ - int cnt = 0; - Game *game=core->GetGame(); - - int i = game->GetPartySize(true); - while(i--) { - Actor *actor = game->GetPC(i, true); - cnt+=actor->inventory.CountItems(parameters->string0Parameter,1); - } - return cnt==parameters->int0Parameter; -} - -int GameScript::NumItemsPartyGT(Scriptable* /*Sender*/, Trigger* parameters) -{ - int cnt = 0; - Game *game=core->GetGame(); - - int i = game->GetPartySize(true); - while(i--) { - Actor *actor = game->GetPC(i, true); - cnt+=actor->inventory.CountItems(parameters->string0Parameter,1); - } - return cnt>parameters->int0Parameter; -} - -int GameScript::NumItemsPartyLT(Scriptable* /*Sender*/, Trigger* parameters) -{ - int cnt = 0; - Game *game=core->GetGame(); - - int i = game->GetPartySize(true); - while(i--) { - Actor *actor = game->GetPC(i, true); - cnt+=actor->inventory.CountItems(parameters->string0Parameter,1); - } - return cntint0Parameter; -} - -int GameScript::NumItems(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - - Inventory *inv = NULL; - switch (tar->Type) { - case ST_ACTOR: - inv = &(((Actor *) tar)->inventory); - break; - case ST_CONTAINER: - inv = &(((Container *) tar)->inventory); - break; - default:; - } - if (!inv) { - return 0; - } - - int cnt = inv->CountItems(parameters->string0Parameter,1); - return cnt==parameters->int0Parameter; -} - -int GameScript::TotalItemCnt(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if ( !tar || tar->Type!=ST_ACTOR) { - return 0; - } - Actor *actor = (Actor *) tar; - int cnt = actor->inventory.CountItems("",1); //shall we count heaps or not? - return cnt==parameters->int0Parameter; -} - -int GameScript::TotalItemCntExclude(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if ( !tar || tar->Type!=ST_ACTOR) { - return 0; - } - Actor *actor = (Actor *) tar; - int cnt = actor->inventory.CountItems("",1)-actor->inventory.CountItems(parameters->string0Parameter,1); //shall we count heaps or not? - return cnt==parameters->int0Parameter; -} - -int GameScript::NumItemsGT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - - Inventory *inv = NULL; - switch (tar->Type) { - case ST_ACTOR: - inv = &(((Actor *) tar)->inventory); - break; - case ST_CONTAINER: - inv = &(((Container *) tar)->inventory); - break; - default:; - } - if (!inv) { - return 0; - } - - int cnt = inv->CountItems(parameters->string0Parameter,1); - return cnt>parameters->int0Parameter; -} - -int GameScript::TotalItemCntGT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if ( !tar || tar->Type!=ST_ACTOR) { - return 0; - } - Actor *actor = (Actor *) tar; - int cnt = actor->inventory.CountItems("",1); //shall we count heaps or not? - return cnt>parameters->int0Parameter; -} - -int GameScript::TotalItemCntExcludeGT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if ( !tar || tar->Type!=ST_ACTOR) { - return 0; - } - Actor *actor = (Actor *) tar; - int cnt = actor->inventory.CountItems("",1)-actor->inventory.CountItems(parameters->string0Parameter,1); //shall we count heaps or not? - return cnt>parameters->int0Parameter; -} - -int GameScript::NumItemsLT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - - Inventory *inv = NULL; - switch (tar->Type) { - case ST_ACTOR: - inv = &(((Actor *) tar)->inventory); - break; - case ST_CONTAINER: - inv = &(((Container *) tar)->inventory); - break; - default:; - } - if (!inv) { - return 0; - } - - int cnt = inv->CountItems(parameters->string0Parameter,1); - return cntint0Parameter; -} - -int GameScript::TotalItemCntLT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if ( !tar || tar->Type!=ST_ACTOR) { - return 0; - } - Actor *actor = (Actor *) tar; - int cnt = actor->inventory.CountItems("",1); //shall we count heaps or not? - return cntint0Parameter; -} - -int GameScript::TotalItemCntExcludeLT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if ( !tar || tar->Type!=ST_ACTOR) { - return 0; - } - Actor *actor = (Actor *) tar; - int cnt = actor->inventory.CountItems("",1)-actor->inventory.CountItems(parameters->string0Parameter,1); //shall we count heaps or not? - return cntint0Parameter; -} - -//the int0 parameter is an addition, normally it is 0 -int GameScript::Contains(Scriptable* Sender, Trigger* parameters) -{ -//actually this should be a container - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if ( !tar || tar->Type!=ST_CONTAINER) { - return 0; - } - Container *cnt = (Container *) tar; - if (HasItemCore(&cnt->inventory, parameters->string0Parameter, parameters->int0Parameter) ) { - return 1; - } - return 0; -} - -int GameScript::StoreHasItem(Scriptable* /*Sender*/, Trigger* parameters) -{ - return StoreHasItemCore(parameters->string0Parameter, parameters->string1Parameter); -} - -//the int0 parameter is an addition, normally it is 0 -int GameScript::HasItem(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if ( !scr ) { - return 0; - } - Inventory *inventory; - switch (scr->Type) { - case ST_ACTOR: - inventory = &( (Actor *) scr)->inventory; - break; - case ST_CONTAINER: - inventory = &( (Container *) scr)->inventory; - break; - default: - inventory = NULL; - break; - } - if (inventory && HasItemCore(inventory, parameters->string0Parameter, parameters->int0Parameter) ) { - return 1; - } - return 0; -} - -int GameScript::ItemIsIdentified(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if ( !scr || scr->Type!=ST_ACTOR) { - return 0; - } - Actor *actor = (Actor *) scr; - if (HasItemCore(&actor->inventory, parameters->string0Parameter, IE_INV_ITEM_IDENTIFIED) ) { - return 1; - } - return 0; -} - -/** if the string is zero, then it will return true if there is any item in the slot (BG2)*/ -/** if the string is non-zero, it will return true, if the given item was in the slot (IWD2)*/ -int GameScript::HasItemSlot(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if ( !scr || scr->Type!=ST_ACTOR) { - return 0; - } - Actor *actor = (Actor *) scr; - //this might require a conversion of the slots - if (actor->inventory.HasItemInSlot(parameters->string0Parameter, parameters->int0Parameter) ) { - return 1; - } - return 0; -} - -//this is a GemRB extension -//HasItemTypeSlot(Object, SLOT, ItemType) -//returns true if the item in SLOT is of ItemType -int GameScript::HasItemTypeSlot(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if ( !scr || scr->Type!=ST_ACTOR) { - return 0; - } - Inventory *inv = &((Actor *) scr)->inventory; - if (parameters->int0Parameter>=inv->GetSlotCount()) { - return 0; - } - CREItem *slot = inv->GetSlotItem(parameters->int0Parameter); - if (!slot) { - return 0; - } - Item *itm = gamedata->GetItem(slot->ItemResRef); - int itemtype = itm->ItemType; - gamedata->FreeItem(itm, slot->ItemResRef, 0); - if (itemtype==parameters->int1Parameter) { - return 1; - } - return 0; -} - -int GameScript::HasItemEquipped(Scriptable * Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if ( !scr || scr->Type!=ST_ACTOR) { - return 0; - } - Actor *actor = (Actor *) scr; - if (actor->inventory.HasItem(parameters->string0Parameter, IE_INV_ITEM_EQUIPPED) ) { - return 1; - } - return 0; -} - -int GameScript::Acquired(Scriptable * Sender, Trigger* parameters) -{ - if ( Sender->Type!=ST_ACTOR) { - return 0; - } - Actor *actor = (Actor *) Sender; - if (actor->inventory.HasItem(parameters->string0Parameter, IE_INV_ITEM_ACQUIRED) ) { - return 1; - } - return 0; -} - -/** 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) -{ - Game *game=core->GetGame(); - - int i = game->GetPartySize(true); - while(i--) { - Actor *actor = game->GetPC(i, true); - if (HasItemCore(&actor->inventory, parameters->string0Parameter, parameters->int0Parameter) ) { - return 1; - } - } - return 0; -} - -int GameScript::PartyHasItemIdentified(Scriptable * /*Sender*/, Trigger* parameters) -{ - Game *game=core->GetGame(); - - int i = game->GetPartySize(true); - while(i--) { - Actor *actor = game->GetPC(i, true); - if (HasItemCore(&actor->inventory, parameters->string0Parameter, IE_INV_ITEM_IDENTIFIED) ) { - return 1; - } - } - return 0; -} - -int GameScript::InventoryFull( Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type!=ST_ACTOR) { - return 0; - } - Actor *actor = (Actor *) tar; - if (actor->inventory.FindCandidateSlot( SLOT_INVENTORY, 0 )==-1) { - return 1; - } - return 0; -} - -int GameScript::HasInnateAbility(Scriptable *Sender, Trigger *parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type!=ST_ACTOR) { - return 0; - } - Actor *actor = (Actor *) tar; - if (parameters->string0Parameter[0]) { - return actor->spellbook.HaveSpell(parameters->string0Parameter, 0); - } - return actor->spellbook.HaveSpell(parameters->int0Parameter, 0); -} - -int GameScript::HaveSpell(Scriptable *Sender, Trigger *parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return 0; - } - Actor *actor = (Actor *) Sender; - if (parameters->string0Parameter[0]) { - return actor->spellbook.HaveSpell(parameters->string0Parameter, 0); - } - return actor->spellbook.HaveSpell(parameters->int0Parameter, 0); -} - -int GameScript::HaveAnySpells(Scriptable* Sender, Trigger* /*parameters*/) -{ - if (Sender->Type!=ST_ACTOR) { - return 0; - } - Actor *actor = (Actor *) Sender; - return actor->spellbook.HaveSpell("", 0); -} - -int GameScript::HaveSpellParty(Scriptable* /*Sender*/, Trigger *parameters) -{ - Game *game=core->GetGame(); - - int i = game->GetPartySize(true); - - if (parameters->string0Parameter[0]) { - while(i--) { - Actor *actor = game->GetPC(i, true); - if (actor->spellbook.HaveSpell(parameters->string0Parameter, 0) ) { - return 1; - } - } - } else { - while(i--) { - Actor *actor = game->GetPC(i, true); - if (actor->spellbook.HaveSpell(parameters->int0Parameter, 0) ) { - return 1; - } - } - } - return 0; -} - -int GameScript::KnowSpell(Scriptable *Sender, Trigger *parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return 0; - } - Actor *actor = (Actor *) Sender; - if (parameters->string0Parameter[0]) { - return actor->spellbook.KnowSpell(parameters->string0Parameter); - } - return actor->spellbook.KnowSpell(parameters->int0Parameter); -} - -int GameScript::True(Scriptable * /* Sender*/, Trigger * /*parameters*/) -{ - return 1; -} - -//in fact this could be used only on Sender, but we want to enhance these -//triggers and actions to accept an object argument whenever possible. -//0 defaults to Myself (Sender) -int GameScript::NumTimesTalkedTo(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - scr = Sender; - } - if (scr->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) scr; - return actor->TalkCount == (ieDword) parameters->int0Parameter ? 1 : 0; -} - -int GameScript::NumTimesTalkedToGT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - scr = Sender; - } - if (scr->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) scr; - return actor->TalkCount > (ieDword) parameters->int0Parameter ? 1 : 0; -} - -int GameScript::NumTimesTalkedToLT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - scr = Sender; - } - if (scr->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) scr; - return actor->TalkCount < (ieDword) parameters->int0Parameter ? 1 : 0; -} - -int GameScript::NumTimesInteracted(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - scr = Sender; - } - if (scr->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) scr; - ieDword npcid = parameters->int0Parameter; - if (npcid>=MAX_INTERACT) return 0; - if (!actor->PCStats) return 0; - return actor->PCStats->Interact[npcid] == (ieDword) parameters->int1Parameter ? 1 : 0; -} - -int GameScript::NumTimesInteractedGT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - scr = Sender; - } - if (scr->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) scr; - ieDword npcid = parameters->int0Parameter; - if (npcid>=MAX_INTERACT) return 0; - if (!actor->PCStats) return 0; - return actor->PCStats->Interact[npcid] > (ieDword) parameters->int1Parameter ? 1 : 0; -} - -int GameScript::NumTimesInteractedLT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - scr = Sender; - } - if (scr->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) scr; - ieDword npcid = parameters->int0Parameter; - if (npcid>=MAX_INTERACT) return 0; - if (!actor->PCStats) return 0; - return actor->PCStats->Interact[npcid] < (ieDword) parameters->int1Parameter ? 1 : 0; -} - -//GemRB specific -//interacting npc counts were restricted to 24 -//gemrb will increase a local variable in the interacting npc, with the scriptname of the -//target npc -int GameScript::NumTimesInteractedObject(Scriptable* Sender, Trigger* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return 0; - } - - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - return 0; - } - if (scr->Type != ST_ACTOR) { - return 0; - } - Actor* tar = ( Actor* ) scr; - return CheckVariable(Sender, tar->GetScriptName(), "LOCALS") == (ieDword) parameters->int0Parameter ? 1 : 0; -} - -int GameScript::NumTimesInteractedObjectGT(Scriptable* Sender, Trigger* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return 0; - } - - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - return 0; - } - if (scr->Type != ST_ACTOR) { - return 0; - } - Actor* tar = ( Actor* ) scr; - return CheckVariable(Sender, tar->GetScriptName(), "LOCALS") > (ieDword) parameters->int0Parameter ? 1 : 0; -} - -int GameScript::NumTimesInteractedObjectLT(Scriptable* Sender, Trigger* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return 0; - } - - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - return 0; - } - if (scr->Type != ST_ACTOR) { - return 0; - } - Actor* tar = ( Actor* ) scr; - return CheckVariable(Sender, tar->GetScriptName(), "LOCALS") < (ieDword) parameters->int0Parameter ? 1 : 0; -} - -int GameScript::ObjectActionListEmpty(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - return 0; - } - - // added CurrentAction as part of blocking action fixes - if (scr->GetCurrentAction() || scr->GetNextAction()) { - return 0; - } - return 1; -} - -int GameScript::ActionListEmpty(Scriptable* Sender, Trigger* /*parameters*/) -{ - // added CurrentAction as part of blocking action fixes - if (Sender->GetCurrentAction() || Sender->GetNextAction()) { - return 0; - } - return 1; -} - -int GameScript::False(Scriptable* /*Sender*/, Trigger* /*parameters*/) -{ - return 0; -} - -/* i guess this is a range of circle edges (instead of centers) */ -int GameScript::PersonalSpaceDistance(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - return 0; - } - int range = parameters->int0Parameter; - - int distance = PersonalDistance(Sender, scr); - if (distance <= ( range * 10 )) { - return 1; - } - return 0; -} - -int GameScript::Range(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - return 0; - } - int distance = SquaredMapDistance(Sender, scr); - return DiffCore(distance, (parameters->int0Parameter+1)*(parameters->int0Parameter+1), parameters->int1Parameter); -} - -int GameScript::InLine(Scriptable* Sender, Trigger* parameters) -{ - Map *map = Sender->GetCurrentArea(); - if (!map) { - return 0; - } - - Scriptable* scr1 = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr1) { - return 0; - } - - //looking for a scriptable by scriptname only - Scriptable* scr2 = map->GetActor( parameters->string0Parameter, 0 ); - if (!scr2) { - scr2 = GetActorObject(map->GetTileMap(), parameters->string0Parameter); - } - if (!scr2) { - return 0; - } - - double fdm1 = SquaredDistance(Sender, scr1); - double fdm2 = SquaredDistance(Sender, scr2); - double fd12 = SquaredDistance(scr1, scr2); - double dm1 = sqrt(fdm1); - double dm2 = sqrt(fdm2); - - if (fdm1>fdm2 || fd12>fdm2) { - return 0; - } - double angle = acos(( fdm2 + fdm1 - fd12 ) / (2*dm1*dm2)); - if (angle*180.0*M_PI<30.0) return 1; - return 0; -} - -//PST -int GameScript::AtLocation( Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - if ( (tar->Pos.x==parameters->pointParameter.x) && - (tar->Pos.y==parameters->pointParameter.y) ) { - return 1; - } - return 0; -} - -//in pst this is a point -//in iwd2 this is not a point -int GameScript::NearLocation(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - return 0; - } - if (parameters->pointParameter.isnull()) { - Point p((short) parameters->int0Parameter, (short) parameters->int1Parameter); - int distance = PersonalDistance(p, scr); - if (distance <= ( parameters->int2Parameter * 10 )) { - return 1; - } - return 0; - } - //personaldistance is needed for modron constructs in PST maze - int distance = PersonalDistance(parameters->pointParameter, scr); - if (distance <= ( parameters->int0Parameter * 10 )) { - return 1; - } - return 0; -} - -int GameScript::NearSavedLocation(Scriptable* Sender, Trigger* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return 0; - } - if (core->HasFeature(GF_HAS_KAPUTZ)) { - // we don't understand how this works in pst yet - return 1; - } - Actor *actor = (Actor *) Sender; - Point p( (short) actor->GetStat(IE_SAVEDXPOS), (short) actor->GetStat(IE_SAVEDYPOS) ); - // should this be PersonalDistance? - int distance = Distance(p, Sender); - if (distance <= ( parameters->int0Parameter * 10 )) { - return 1; - } - return 0; -} - -int GameScript::Or(Scriptable* /*Sender*/, Trigger* parameters) -{ - return parameters->int0Parameter; -} - -int GameScript::TriggerTrigger(Scriptable* Sender, Trigger* parameters) -{ - return Sender->MatchTrigger(trigger_trigger, parameters->int0Parameter); -} - -int GameScript::WalkedToTrigger(Scriptable* Sender, Trigger* parameters) -{ - /*Actor *target = Sender->GetCurrentArea()->GetActorByGlobalID(Sender->LastTrigger); - if (!target) { - return 0; - } - if (PersonalDistance(target, Sender) > 3*MAX_OPERATING_DISTANCE ) { - return 0; - } - //now objects suicide themselves if they are empty objects - //so checking an empty object is easier - if (parameters->objectParameter == NULL) { - Sender->AddTrigger (&Sender->LastTrigger); - return 1; - } - if (MatchActor(Sender, Sender->LastTrigger, parameters->objectParameter)) { - Sender->AddTrigger (&Sender->LastTrigger); - return 1; - } - return 0;*/ - return Sender->MatchTriggerWithObject(trigger_walkedtotrigger, parameters->objectParameter); -} - -int GameScript::Clicked(Scriptable* Sender, Trigger* parameters) -{ - return Sender->MatchTriggerWithObject(trigger_clicked, parameters->objectParameter); -} - -int GameScript::Disarmed(Scriptable* Sender, Trigger* parameters) -{ - return Sender->MatchTriggerWithObject(trigger_disarmed, parameters->objectParameter); -} - -//stealing from a store failed, owner triggered -int GameScript::StealFailed(Scriptable* Sender, Trigger* parameters) -{ - return Sender->MatchTriggerWithObject(trigger_disarmfailed, parameters->objectParameter); -} - -int GameScript::PickpocketFailed(Scriptable* Sender, Trigger* parameters) -{ - return Sender->MatchTriggerWithObject(trigger_pickpocketfailed, parameters->objectParameter); -} - -int GameScript::PickLockFailed(Scriptable* Sender, Trigger* parameters) -{ - return Sender->MatchTriggerWithObject(trigger_picklockfailed, parameters->objectParameter); -} - -int GameScript::OpenFailed(Scriptable* Sender, Trigger* parameters) -{ - return Sender->MatchTriggerWithObject(trigger_failedtoopen, parameters->objectParameter); -} - -int GameScript::DisarmFailed(Scriptable* Sender, Trigger* parameters) -{ - return Sender->MatchTriggerWithObject(trigger_disarmfailed, parameters->objectParameter); -} - -//opened for doors/containers (using lastEntered) -int GameScript::Opened(Scriptable* Sender, Trigger* parameters) -{ - return Sender->MatchTriggerWithObject(trigger_opened, parameters->objectParameter); -} - -//closed for doors (using lastTrigger) -int GameScript::Closed(Scriptable* Sender, Trigger* parameters) -{ - return Sender->MatchTriggerWithObject(trigger_closed, parameters->objectParameter); -} - -//unlocked for doors/containers (using lastUnlocked) -int GameScript::Unlocked(Scriptable* Sender, Trigger* parameters) -{ - return Sender->MatchTriggerWithObject(trigger_unlocked, parameters->objectParameter); -} - -int GameScript::Entered(Scriptable* Sender, Trigger* parameters) -{ - return Sender->MatchTriggerWithObject(trigger_entered, parameters->objectParameter); -} - -int GameScript::HarmlessEntered(Scriptable* Sender, Trigger* parameters) -{ - return Sender->MatchTriggerWithObject(trigger_harmlessentered, parameters->objectParameter); -} - -int GameScript::IsOverMe(Scriptable* Sender, Trigger* parameters) -{ - if (Sender->Type != ST_PROXIMITY) { - return 0; - } - Highlightable *trap = (Highlightable *)Sender; - - Targets *tgts = GetAllObjects(Sender->GetCurrentArea(), Sender, parameters->objectParameter, GA_NO_DEAD); - int ret = 0; - if (tgts) { - targetlist::iterator m; - const targettype *tt = tgts->GetFirstTarget(m, ST_ACTOR); - while (tt) { - Actor *actor = (Actor *) tt->actor; - if (trap->IsOver(actor->Pos)) { - ret = 1; - break; - } - tt = tgts->GetNextTarget(m, ST_ACTOR); - } - } - delete tgts; - return ret; -} - -//this function is different in every engines, if you use a string0parameter -//then it will be considered as a variable check -//you can also use an object parameter (like in iwd) -int GameScript::Dead(Scriptable* Sender, Trigger* parameters) -{ - if (parameters->string0Parameter[0]) { - ieDword value; - ieVariable Variable; - - if (core->HasFeature( GF_HAS_KAPUTZ )) { - value = CheckVariable( Sender, parameters->string0Parameter, "KAPUTZ"); - } else { - snprintf( Variable, 32, core->GetDeathVarFormat(), parameters->string0Parameter ); - } - value = CheckVariable( Sender, Variable, "GLOBAL" ); - if (value>0) { - return 1; - } - return 0; - } - Scriptable* target = GetActorFromObject( Sender, parameters->objectParameter ); - if (!target) { - return 1; - } - if (target->Type != ST_ACTOR) { - return 1; - } - Actor* actor = ( Actor* ) target; - if (actor->GetStat( IE_STATE_ID ) & STATE_DEAD) { - return 1; - } - return 0; -} - -int GameScript::CreatureHidden(Scriptable* Sender, Trigger* /*parameters*/) -{ - if (Sender->Type!=ST_ACTOR) { - return 0; - } - Actor *act=(Actor *) Sender; - - //this stuff is not completely clear, but HoW has a flag for this - //and GemRB uses the avatarremoval stat for it. - //HideCreature also sets this stat, so... - if (act->GetStat(IE_AVATARREMOVAL)) { - return 1; - } - - if (act->GetInternalFlag()&IF_VISIBLE) { - return 0; - } - return 1; -} -int GameScript::BecameVisible(Scriptable* Sender, Trigger* /*parameters*/) -{ - return Sender->MatchTrigger(trigger_becamevisible); -} - -int GameScript::Die(Scriptable* Sender, Trigger* /*parameters*/) -{ - return Sender->MatchTrigger(trigger_die); -} - -int GameScript::Died(Scriptable* Sender, Trigger* parameters) -{ - return Sender->MatchTriggerWithObject(trigger_died, parameters->objectParameter); -} - -int GameScript::PartyMemberDied(Scriptable* Sender, Trigger* parameters) -{ - return Sender->MatchTriggerWithObject(trigger_partymemberdied, parameters->objectParameter); -} - -int GameScript::NamelessBitTheDust(Scriptable* Sender, Trigger* /*parameters*/) -{ - return Sender->MatchTrigger(trigger_namelessbitthedust); -} - -int GameScript::Killed(Scriptable* Sender, Trigger* parameters) -{ - return Sender->MatchTriggerWithObject(trigger_killed, parameters->objectParameter); -} - -int GameScript::Race(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - return 0; - } - if (scr->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) scr; - return ID_Race(actor, parameters->int0Parameter); -} - -int GameScript::Gender(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - return 0; - } - if (scr->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) scr; - return ID_Gender(actor, parameters->int0Parameter); -} - -int GameScript::HP(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - return 0; - } - if (scr->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) scr; - if ((signed) actor->GetBase( IE_HITPOINTS ) == parameters->int0Parameter) { - return 1; - } - return 0; -} - -int GameScript::HPGT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - return 0; - } - if (scr->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) scr; - if ( (signed) actor->GetBase( IE_HITPOINTS ) > parameters->int0Parameter) { - return 1; - } - return 0; -} - -int GameScript::HPLT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - return 0; - } - if (scr->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) scr; - if ( (signed) actor->GetBase( IE_HITPOINTS ) < parameters->int0Parameter) { - return 1; - } - return 0; -} - -//these triggers work on the current damage (not the last damage) -/* they are identical to HPLost -int GameScript::DamageTaken(Scriptable* Sender, Trigger* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) Sender; - int damage = actor->GetStat(IE_MAXHITPOINTS)-actor->GetBase(IE_HITPOINTS); - if (damage==(int) parameters->int0Parameter) { - return 1; - } - return 0; -} - -int GameScript::DamageTakenGT(Scriptable* Sender, Trigger* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) Sender; - int damage = actor->GetStat(IE_MAXHITPOINTS)-actor->GetBase(IE_HITPOINTS); - if (damage>(int) parameters->int0Parameter) { - return 1; - } - return 0; -} - -int GameScript::DamageTakenLT(Scriptable* Sender, Trigger* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) Sender; - int damage = actor->GetStat(IE_MAXHITPOINTS)-actor->GetBase(IE_HITPOINTS); - if (damage<(int) parameters->int0Parameter) { - return 1; - } - return 0; -} -*/ - -int GameScript::HPLost(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - return 0; - } - if (scr->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) scr; - //max-current - if ( (signed) actor->GetStat(IE_MAXHITPOINTS)-(signed) actor->GetBase( IE_HITPOINTS ) == (signed) parameters->int0Parameter) { - return 1; - } - return 0; -} - -int GameScript::HPLostGT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - return 0; - } - if (scr->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) scr; - //max-current - if ( (signed) actor->GetStat(IE_MAXHITPOINTS)-(signed) actor->GetBase( IE_HITPOINTS ) > (signed) parameters->int0Parameter) { - return 1; - } - return 0; -} - -int GameScript::HPLostLT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - return 0; - } - if (scr->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) scr; - //max-current - if ( (signed) actor->GetStat(IE_MAXHITPOINTS)-(signed) actor->GetBase( IE_HITPOINTS ) < (signed) parameters->int0Parameter) { - return 1; - } - return 0; -} - -int GameScript::HPPercent(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - return 0; - } - if (GetHPPercent( scr ) == parameters->int0Parameter) { - return 1; - } - return 0; -} - -int GameScript::HPPercentGT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - return 0; - } - if (GetHPPercent( scr ) > parameters->int0Parameter) { - return 1; - } - return 0; -} - -int GameScript::HPPercentLT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - return 0; - } - if (GetHPPercent( scr ) < parameters->int0Parameter) { - return 1; - } - return 0; -} - -int GameScript::XP(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - return 0; - } - if (scr->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) scr; - if (actor->GetStat( IE_XP ) == (unsigned) parameters->int0Parameter) { - return 1; - } - return 0; -} - -int GameScript::XPGT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - return 0; - } - if (scr->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) scr; - if (actor->GetStat( IE_XP ) > (unsigned) parameters->int0Parameter) { - return 1; - } - return 0; -} - -int GameScript::XPLT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr) { - return 0; - } - if (scr->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) scr; - if (actor->GetStat( IE_XP ) < (unsigned) parameters->int0Parameter) { - return 1; - } - return 0; -} - -int GameScript::CheckSkill(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* target = GetActorFromObject( Sender, parameters->objectParameter ); - if (!target) { - return 0; - } - if (target->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) target; - int sk = actor->GetSkill( parameters->int1Parameter ); - if (sk<0) return 0; - if ( sk == parameters->int0Parameter) { - return 1; - } - return 0; -} -int GameScript::CheckStat(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* target = GetActorFromObject( Sender, parameters->objectParameter ); - if (!target) { - return 0; - } - if (target->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) target; - if ( (signed) actor->GetStat( parameters->int1Parameter ) == parameters->int0Parameter) { - return 1; - } - return 0; -} - -int GameScript::CheckSkillGT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - int sk = actor->GetSkill( parameters->int1Parameter ); - if (sk<0) return 0; - if ( sk > parameters->int0Parameter) { - return 1; - } - return 0; -} - -int GameScript::CheckStatGT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - if ( (signed) actor->GetStat( parameters->int1Parameter ) > parameters->int0Parameter) { - return 1; - } - return 0; -} - -int GameScript::CheckSkillLT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - int sk = actor->GetSkill( parameters->int1Parameter ); - if (sk<0) return 0; - if ( sk < parameters->int0Parameter) { - return 1; - } - return 0; -} - -int GameScript::CheckStatLT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - if ( (signed) actor->GetStat( parameters->int1Parameter ) < parameters->int0Parameter) { - return 1; - } - return 0; -} - -/* i believe this trigger is the same as 'MarkObject' action - except that if it cannot set the marked object, it returns false */ -int GameScript::SetLastMarkedObject(Scriptable* Sender, Trigger* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return 0; - } - Actor *scr = (Actor *) Sender; - - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type != ST_ACTOR) { - return 0; - } - scr->LastMarked = tar->GetGlobalID(); - return 1; -} - -int GameScript::IsSpellTargetValid(Scriptable* Sender, Trigger* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return 0; - } - Actor *scr = (Actor *) Sender; - - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - Actor *actor = NULL; - if (tar->Type == ST_ACTOR) { - actor = (Actor *) tar; - } - - int flags = parameters->int1Parameter; - if (!(flags & MSO_IGNORE_NULL) && !actor) { - return 0; - } - if (!(flags & MSO_IGNORE_INVALID) && actor && actor->InvalidSpellTarget() ) { - return 0; - } - int splnum = parameters->int0Parameter; - if (!(flags & MSO_IGNORE_HAVE) && !scr->spellbook.HaveSpell(splnum, 0) ) { - return 0; - } - int range; - if ((flags & MSO_IGNORE_RANGE) || !actor) { - range = 0; - } else { - range = Distance(scr, actor); - } - if (!(flags & MSO_IGNORE_INVALID) && actor->InvalidSpellTarget(splnum, scr, range)) { - return 0; - } - return 1; -} - -//This trigger seems to always return true for actors... -//Always manages to set spell to 0, otherwise it sets if there was nothing set earlier -int GameScript::SetMarkedSpell_Trigger(Scriptable* Sender, Trigger* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return 0; - } - Actor *scr = (Actor *) Sender; - if (parameters->int0Parameter) { - if (scr->LastMarkedSpell) { - return 1; - } - if (!scr->spellbook.HaveSpell(parameters->int0Parameter, 0) ) { - return 1; - } - } - - //TODO: check if spell exists (not really important) - scr->LastMarkedSpell = parameters->int0Parameter; - return 1; -} - -int GameScript::ForceMarkedSpell_Trigger(Scriptable* Sender, Trigger* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return 0; - } - Actor *scr = (Actor *) Sender; - scr->LastMarkedSpell = parameters->int0Parameter; - return 1; -} - -int GameScript::IsMarkedSpell(Scriptable* Sender, Trigger* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return 0; - } - Actor *scr = (Actor *) Sender; - return scr->LastMarkedSpell == parameters->int0Parameter; -} - - -int GameScript::See(Scriptable* Sender, Trigger* parameters) -{ - int see = SeeCore(Sender, parameters, 0); - //don't mark LastSeen for clear!!! - if (Sender->Type==ST_ACTOR && see) { - Actor *act = (Actor *) Sender; - //save lastseen as lastmarked - //FIXME: what is this doing? - act->LastMarked = act->LastSeen; - //Sender->AddTrigger (&act->LastSeen); - } - return see; -} - -int GameScript::Detect(Scriptable* Sender, Trigger* parameters) -{ - parameters->int0Parameter=1; //seedead/invis - int see = SeeCore(Sender, parameters, 0); - if (!see) { - return 0; - } - return 1; -} - -int GameScript::LOS(Scriptable* Sender, Trigger* parameters) -{ - int see=SeeCore(Sender, parameters, 1); - if (!see) { - return 0; - } - return Range(Sender, parameters); //same as range -} - -int GameScript::NumCreatures(Scriptable* Sender, Trigger* parameters) -{ - int value = GetObjectCount(Sender, parameters->objectParameter); - return value == parameters->int0Parameter; -} - -int GameScript::NumCreaturesAtMyLevel(Scriptable* Sender, Trigger* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return 0; - } - int level = ((Actor *) Sender)->GetXPLevel(true); - int value; - - if (parameters->int0Parameter) { - value = GetObjectLevelCount(Sender, parameters->objectParameter); - } else { - value = GetObjectCount(Sender, parameters->objectParameter); - } - return value == level; -} - -int GameScript::NumCreaturesLT(Scriptable* Sender, Trigger* parameters) -{ - int value = GetObjectCount(Sender, parameters->objectParameter); - return value < parameters->int0Parameter; -} - -int GameScript::NumCreaturesLTMyLevel(Scriptable* Sender, Trigger* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return 0; - } - int level = ((Actor *) Sender)->GetXPLevel(true); - int value; - - if (parameters->int0Parameter) { - value = GetObjectLevelCount(Sender, parameters->objectParameter); - } else { - value = GetObjectCount(Sender, parameters->objectParameter); - } - return value < level; -} - -int GameScript::NumCreaturesGT(Scriptable* Sender, Trigger* parameters) -{ - int value = GetObjectCount(Sender, parameters->objectParameter); - return value > parameters->int0Parameter; -} - -int GameScript::NumCreaturesGTMyLevel(Scriptable* Sender, Trigger* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return 0; - } - int level = ((Actor *) Sender)->GetXPLevel(true); - int value; - - if (parameters->int0Parameter) { - value = GetObjectLevelCount(Sender, parameters->objectParameter); - } else { - value = GetObjectCount(Sender, parameters->objectParameter); - } - return value > level; -} - -int GameScript::NumCreatureVsParty(Scriptable* Sender, Trigger* parameters) -{ - //creating object on the spot - if (!parameters->objectParameter) { - parameters->objectParameter = new Object(); - } - int value = GetObjectCount(Sender, parameters->objectParameter); - value -= core->GetGame()->GetPartySize(true); - return value == parameters->int0Parameter; -} - -int GameScript::NumCreatureVsPartyGT(Scriptable* Sender, Trigger* parameters) -{ - if (!parameters->objectParameter) { - parameters->objectParameter = new Object(); - } - int value = GetObjectCount(Sender, parameters->objectParameter); - value -= core->GetGame()->GetPartySize(true); - return value > parameters->int0Parameter; -} - -int GameScript::NumCreatureVsPartyLT(Scriptable* Sender, Trigger* parameters) -{ - if (!parameters->objectParameter) { - parameters->objectParameter = new Object(); - } - int value = GetObjectCount(Sender, parameters->objectParameter); - value -= core->GetGame()->GetPartySize(true); - return value < parameters->int0Parameter; -} - -int GameScript::Morale(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - return (signed) actor->GetStat(IE_MORALEBREAK) == parameters->int0Parameter; -} - -int GameScript::MoraleGT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - return (signed) actor->GetStat(IE_MORALEBREAK) > parameters->int0Parameter; -} - -int GameScript::MoraleLT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - return (signed) actor->GetStat(IE_MORALEBREAK) < parameters->int0Parameter; -} - -int GameScript::CheckSpellState(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - if (parameters->int0Parameter>255) { - return 0; - } - unsigned int position = parameters->int0Parameter>>5; - unsigned int bit = 1<<(parameters->int0Parameter&31); - if (actor->GetStat(IE_SPLSTATE_ID1+position) & bit) { - return 1; - } - return 0; -} - -int GameScript::StateCheck(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - if (actor->GetStat(IE_STATE_ID) & parameters->int0Parameter) { - return 1; - } - return 0; -} - -int GameScript::ExtendedStateCheck(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - if (actor->GetStat(IE_EXTSTATE_ID) & parameters->int0Parameter) { - return 1; - } - return 0; -} - -int GameScript::NotStateCheck(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - if (actor->GetStat(IE_STATE_ID) & ~parameters->int0Parameter) { - return 1; - } - return 0; -} - -int GameScript::RandomNum(Scriptable* /*Sender*/, Trigger* parameters) -{ - if (parameters->int0Parameter<0) { - return 0; - } - if (parameters->int1Parameter<0) { - return 0; - } - return parameters->int1Parameter-1 == RandomNumValue%parameters->int0Parameter; -} - -int GameScript::RandomNumGT(Scriptable* /*Sender*/, Trigger* parameters) -{ - if (parameters->int0Parameter<0) { - return 0; - } - if (parameters->int1Parameter<0) { - return 0; - } - return parameters->int1Parameter-1 < RandomNumValue%parameters->int0Parameter; -} - -int GameScript::RandomNumLT(Scriptable* /*Sender*/, Trigger* parameters) -{ - if (parameters->int0Parameter<0) { - return 0; - } - if (parameters->int1Parameter<0) { - return 0; - } - return parameters->int1Parameter-1 > RandomNumValue%parameters->int0Parameter; -} - -int GameScript::OpenState(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - if (InDebug&ID_TRIGGERS) { - printMessage("GameScript", "Couldn't find door/container:%s\n", LIGHT_RED, - parameters->objectParameter? parameters->objectParameter->objectName:""); - print("Sender: %s\n", Sender->GetScriptName() ); - } - return 0; - } - switch(tar->Type) { - case ST_DOOR: - { - Door *door =(Door *) tar; - return !door->IsOpen() == !parameters->int0Parameter; - } - case ST_CONTAINER: - { - Container *cont = (Container *) tar; - return !(cont->Flags&CONT_LOCKED) == !parameters->int0Parameter; - } - default:; //to remove a warning - } - printMessage("GameScript", "Not a door/container:%s\n", LIGHT_RED, - tar->GetScriptName()); - return 0; -} - -int GameScript::IsLocked(Scriptable * Sender, Trigger *parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - printMessage("GameScript", "Couldn't find door/container:%s\n", LIGHT_RED, - parameters->objectParameter? parameters->objectParameter->objectName:""); - print("Sender: %s\n", Sender->GetScriptName() ); - return 0; - } - switch(tar->Type) { - case ST_DOOR: - { - Door *door =(Door *) tar; - return !!(door->Flags&DOOR_LOCKED); - } - case ST_CONTAINER: - { - Container *cont = (Container *) tar; - return !!(cont->Flags&CONT_LOCKED); - } - default:; //to remove a warning - } - printMessage("GameScript", "Not a door/container:%s\n", LIGHT_RED, - tar->GetScriptName()); - return 0; -} - -int GameScript::Level(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - if (tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - // FIXME: what about multiclasses or dualclasses? - return actor->GetStat(IE_LEVEL) == (unsigned) parameters->int0Parameter; -} - -//this is just a hack, actually multiclass should be available -int GameScript::ClassLevel(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - if (tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - - if (!ID_Class( actor, parameters->int0Parameter) ) - return 0; - // FIXME: compare the requested level - return actor->GetStat(IE_LEVEL) == (unsigned) parameters->int1Parameter; -} - -// iwd2 and pst have different order of parameters: -// ClassLevelGT(Protagonist,MAGE,89) -// LevelInClass(Myself,10,CLERIC) -int GameScript::LevelInClass(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - if (tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - - if (!ID_ClassMask( actor, parameters->int1Parameter) ) - return 0; - // FIXME: compare the requested level - return actor->GetStat(IE_LEVEL) == (unsigned) parameters->int0Parameter; -} - -int GameScript::LevelGT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - if (tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - return actor->GetStat(IE_LEVEL) > (unsigned) parameters->int0Parameter; -} - -//this is just a hack, actually multiclass should be available -int GameScript::ClassLevelGT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - if (tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - if (!ID_Class( actor, parameters->int0Parameter) ) - return 0; - return actor->GetStat(IE_LEVEL) > (unsigned) parameters->int1Parameter; -} - -int GameScript::LevelInClassGT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - if (tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - - if (!ID_ClassMask( actor, parameters->int1Parameter) ) - return 0; - return actor->GetStat(IE_LEVEL) > (unsigned) parameters->int0Parameter; -} - -int GameScript::LevelLT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - if (tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - return actor->GetStat(IE_LEVEL) < (unsigned) parameters->int0Parameter; -} - -int GameScript::ClassLevelLT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - if (tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - if (!ID_Class( actor, parameters->int0Parameter) ) - return 0; - return actor->GetStat(IE_LEVEL) < (unsigned) parameters->int1Parameter; -} - -int GameScript::LevelInClassLT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - if (tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - - if (!ID_ClassMask( actor, parameters->int1Parameter) ) - return 0; - return actor->GetStat(IE_LEVEL) < (unsigned) parameters->int0Parameter; -} - -int GameScript::UnselectableVariable(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - return tar->UnselectableTimer == (unsigned) parameters->int0Parameter; -} - -int GameScript::UnselectableVariableGT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - return tar->UnselectableTimer > (unsigned) parameters->int0Parameter; -} - -int GameScript::UnselectableVariableLT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - return tar->UnselectableTimer < (unsigned) parameters->int0Parameter; -} - -int GameScript::AreaCheck(Scriptable* Sender, Trigger* parameters) -{ - if (!strnicmp(Sender->GetCurrentArea()->GetScriptName(), parameters->string0Parameter, 8)) { - return 1; - } - return 0; -} - -int GameScript::AreaCheckObject(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - - if (!tar) { - return 0; - } - if (!strnicmp(tar->GetCurrentArea()->GetScriptName(), parameters->string0Parameter, 8)) { - return 1; - } - return 0; -} - -//lame iwd2 uses a numeric area identifier, this reduces its usability -int GameScript::CurrentAreaIs(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - - if (!tar) { - return 0; - } - ieResRef arearesref; - snprintf(arearesref, 8, "AR%04d", parameters->int0Parameter); - if (!strnicmp(tar->GetCurrentArea()->GetScriptName(), arearesref, 8)) { - return 1; - } - return 0; -} - -//lame bg2 uses a constant areaname prefix, this reduces its usability -//but in the spirit of flexibility, gemrb extension allows arbitrary prefixes -int GameScript::AreaStartsWith(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - - if (!tar) { - return 0; - } - ieResRef arearesref; - if (parameters->string0Parameter[0]) { - strnlwrcpy(arearesref, parameters->string0Parameter, 8); - } else { - strnlwrcpy(arearesref, "AR30", 8); //InWatchersKeep - } - int i = strlen(arearesref); - if (!strnicmp(tar->GetCurrentArea()->GetScriptName(), arearesref, i)) { - return 1; - } - return 0; -} - -int GameScript::EntirePartyOnMap(Scriptable* Sender, Trigger* /*parameters*/) -{ - Map *map = Sender->GetCurrentArea(); - Game *game=core->GetGame(); - int i=game->GetPartySize(true); - while (i--) { - Actor *actor=game->GetPC(i,true); - if (actor->GetCurrentArea()!=map) { - return 0; - } - } - return 1; -} - -int GameScript::AnyPCOnMap(Scriptable* Sender, Trigger* /*parameters*/) -{ - Map *map = Sender->GetCurrentArea(); - Game *game=core->GetGame(); - int i=game->GetPartySize(true); - while (i--) { - Actor *actor=game->GetPC(i,true); - if (actor->GetCurrentArea()==map) { - return 1; - } - } - return 0; -} - -int GameScript::InActiveArea(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - if (core->GetGame()->GetCurrentArea() == tar->GetCurrentArea()) { - return 1; - } - return 0; -} - -int GameScript::InMyArea(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - if (Sender->GetCurrentArea() == tar->GetCurrentArea()) { - return 1; - } - return 0; -} - -int GameScript::AreaType(Scriptable* Sender, Trigger* parameters) -{ - Map *map=Sender->GetCurrentArea(); - return (map->AreaType¶meters->int0Parameter)>0; -} - -int GameScript::IsExtendedNight( Scriptable* Sender, Trigger* /*parameters*/) -{ - Map *map=Sender->GetCurrentArea(); - if (map->AreaType&AT_EXTENDED_NIGHT) { - return 1; - } - return 0; -} - -int GameScript::AreaFlag(Scriptable* Sender, Trigger* parameters) -{ - Map *map=Sender->GetCurrentArea(); - return (map->AreaFlags¶meters->int0Parameter)>0; -} - -int GameScript::AreaRestDisabled(Scriptable* Sender, Trigger* /*parameters*/) -{ - Map *map=Sender->GetCurrentArea(); - if (map->AreaFlags&2) { - return 1; - } - return 0; -} - -//new optional parameter: size of actor (to reach target) -int GameScript::TargetUnreachable(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type != ST_ACTOR) { - return 1; //well, if it doesn't exist it is unreachable - } - Map *map=Sender->GetCurrentArea(); - if (!map) { - return 1; - } - unsigned int size = parameters->int0Parameter; - - if (!size) { - if (Sender->Type==ST_ACTOR) { - size = ((Movable *) Sender)->size; - } - else { - size = 1; - } - } - return map->TargetUnreachable( Sender->Pos, tar->Pos, size); -} - -int GameScript::PartyCountEQ(Scriptable* /*Sender*/, Trigger* parameters) -{ - return core->GetGame()->GetPartySize(0)==parameters->int0Parameter; -} - -int GameScript::PartyCountLT(Scriptable* /*Sender*/, Trigger* parameters) -{ - return core->GetGame()->GetPartySize(0)int0Parameter; -} - -int GameScript::PartyCountGT(Scriptable* /*Sender*/, Trigger* parameters) -{ - return core->GetGame()->GetPartySize(0)>parameters->int0Parameter; -} - -int GameScript::PartyCountAliveEQ(Scriptable* /*Sender*/, Trigger* parameters) -{ - return core->GetGame()->GetPartySize(1)==parameters->int0Parameter; -} - -int GameScript::PartyCountAliveLT(Scriptable* /*Sender*/, Trigger* parameters) -{ - return core->GetGame()->GetPartySize(1)int0Parameter; -} - -int GameScript::PartyCountAliveGT(Scriptable* /*Sender*/, Trigger* parameters) -{ - return core->GetGame()->GetPartySize(1)>parameters->int0Parameter; -} - -int GameScript::LevelParty(Scriptable* /*Sender*/, Trigger* parameters) -{ - return core->GetGame()->GetPartyLevel(1)==parameters->int0Parameter; -} - -int GameScript::LevelPartyLT(Scriptable* /*Sender*/, Trigger* parameters) -{ - return core->GetGame()->GetPartyLevel(1)int0Parameter; -} - -int GameScript::LevelPartyGT(Scriptable* /*Sender*/, Trigger* parameters) -{ - return core->GetGame()->GetPartyLevel(1)>parameters->int0Parameter; -} - -int GameScript::PartyGold(Scriptable* /*Sender*/, Trigger* parameters) -{ - return core->GetGame()->PartyGold == (ieDword) parameters->int0Parameter; -} - -int GameScript::PartyGoldGT(Scriptable* /*Sender*/, Trigger* parameters) -{ - return core->GetGame()->PartyGold > (ieDword) parameters->int0Parameter; -} - -int GameScript::PartyGoldLT(Scriptable* /*Sender*/, Trigger* parameters) -{ - return core->GetGame()->PartyGold < (ieDword) parameters->int0Parameter; -} - -int GameScript::OwnsFloaterMessage(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - return tar->textDisplaying; -} - -int GameScript::InCutSceneMode(Scriptable* /*Sender*/, Trigger* /*parameters*/) -{ - return core->InCutSceneMode(); -} - -int GameScript::Proficiency(Scriptable* Sender, Trigger* parameters) -{ - unsigned int idx = parameters->int0Parameter; - if (idx>31) { - return 0; - } - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - if (tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - return (signed) actor->GetStat(IE_PROFICIENCYBASTARDSWORD+idx) == parameters->int1Parameter; -} - -int GameScript::ProficiencyGT(Scriptable* Sender, Trigger* parameters) -{ - unsigned int idx = parameters->int0Parameter; - if (idx>31) { - return 0; - } - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - if (tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - return (signed) actor->GetStat(IE_PROFICIENCYBASTARDSWORD+idx) > parameters->int1Parameter; -} - -int GameScript::ProficiencyLT(Scriptable* Sender, Trigger* parameters) -{ - unsigned int idx = parameters->int0Parameter; - if (idx>31) { - return 0; - } - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - if (tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - return (signed) actor->GetStat(IE_PROFICIENCYBASTARDSWORD+idx) < parameters->int1Parameter; -} - -//this is a PST specific stat, shows how many free proficiency slots we got -//we use an unused stat for it -int GameScript::ExtraProficiency(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - if (tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - return (signed) actor->GetStat(IE_FREESLOTS) == parameters->int0Parameter; -} - -int GameScript::ExtraProficiencyGT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - if (tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - return (signed) actor->GetStat(IE_FREESLOTS) > parameters->int0Parameter; -} - -int GameScript::ExtraProficiencyLT(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - if (tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - return (signed) actor->GetStat(IE_FREESLOTS) < parameters->int0Parameter; -} - -int GameScript::Internal(Scriptable* Sender, Trigger* parameters) -{ - unsigned int idx = parameters->int0Parameter; - if (idx>15) { - return 0; - } - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - if (tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - return (signed) actor->GetStat(IE_INTERNAL_0+idx) == parameters->int1Parameter; -} - -int GameScript::InternalGT(Scriptable* Sender, Trigger* parameters) -{ - unsigned int idx = parameters->int0Parameter; - if (idx>15) { - return 0; - } - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - if (tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - return (signed) actor->GetStat(IE_INTERNAL_0+idx) > parameters->int1Parameter; -} - -int GameScript::InternalLT(Scriptable* Sender, Trigger* parameters) -{ - unsigned int idx = parameters->int0Parameter; - if (idx>15) { - return 0; - } - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - if (tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - return (signed) actor->GetStat(IE_INTERNAL_0+idx) < parameters->int1Parameter; -} - -//we check if target is currently in dialog or not -int GameScript::NullDialog(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - if (tar->Type != ST_ACTOR) { - return 0; - } - GameControl *gc = core->GetGameControl(); - if ( (tar->GetGlobalID() != gc->dialoghandler->targetID) && (tar->GetGlobalID() != gc->dialoghandler->speakerID) ) { - return 1; - } - return 0; -} - -//this one checks scriptname (deathvar), i hope it is right -//IsScriptName depends on this too -//Name is another (similar function) -int GameScript::CalledByName(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - if (tar->Type != ST_ACTOR) { - return 0; - } - Actor *actor = (Actor *) tar; - if (stricmp(actor->GetScriptName(), parameters->string0Parameter) ) { - return 0; - } - return 1; -} - -//This is checking on the character's name as it was typed in -int GameScript::CharName(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter ); - if (!scr || scr->Type!=ST_ACTOR) { - return 0; - } - Actor* actor = (Actor *) scr; - if (!strnicmp(actor->ShortName, parameters->string0Parameter, 32) ) { - return 1; - } - return 0; -} - -int GameScript::AnimationID(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - if (tar->Type != ST_ACTOR) { - return 0; - } - Actor *actor = (Actor *) tar; - if ((ieWord) actor->GetStat(IE_ANIMATION_ID) == (ieWord) parameters->int0Parameter) { - return 1; - } - return 0; -} - -int GameScript::AnimState(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - if (tar->Type != ST_ACTOR) { - return 0; - } - Actor *actor = (Actor *) tar; - return actor->GetStance() == parameters->int0Parameter; -} - -//this trigger uses hours -int GameScript::Time(Scriptable* /*Sender*/, Trigger* parameters) -{ - return (core->GetGame()->GameTime/AI_UPDATE_TIME)%7200/300 == (ieDword) parameters->int0Parameter; -} - -//this trigger uses hours -int GameScript::TimeGT(Scriptable* /*Sender*/, Trigger* parameters) -{ - return (core->GetGame()->GameTime/AI_UPDATE_TIME)%7200/300 > (ieDword) parameters->int0Parameter; -} - -//this trigger uses hours -int GameScript::TimeLT(Scriptable* /*Sender*/, Trigger* parameters) -{ - return (core->GetGame()->GameTime/AI_UPDATE_TIME)%7200/300 < (ieDword) parameters->int0Parameter; -} - -int GameScript::HotKey(Scriptable* Sender, Trigger* parameters) -{ - return Sender->MatchTrigger(trigger_hotkey, parameters->int0Parameter); -} - -int GameScript::CombatCounter(Scriptable* /*Sender*/, Trigger* parameters) -{ - return core->GetGame()->CombatCounter == (ieDword) parameters->int0Parameter; -} - -int GameScript::CombatCounterGT(Scriptable* /*Sender*/, Trigger* parameters) -{ - return core->GetGame()->CombatCounter > (ieDword) parameters->int0Parameter; -} - -int GameScript::CombatCounterLT(Scriptable* /*Sender*/, Trigger* parameters) -{ - return core->GetGame()->CombatCounter < (ieDword) parameters->int0Parameter; -} - -int GameScript::TrapTriggered(Scriptable* Sender, Trigger* parameters) -{ - return Sender->MatchTriggerWithObject(trigger_traptriggered, parameters->objectParameter); -} - -int GameScript::InteractingWith(Scriptable* Sender, Trigger* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return 0; - } - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type != ST_ACTOR) { - return 0; - } - GameControl *gc = core->GetGameControl(); - if (Sender->GetGlobalID() != gc->dialoghandler->targetID && Sender->GetGlobalID() != gc->dialoghandler->speakerID) { - return 0; - } - if (tar->GetGlobalID() != gc->dialoghandler->targetID && tar->GetGlobalID() != gc->dialoghandler->speakerID) { - return 0; - } - return 1; -} - -int GameScript::LastPersonTalkedTo(Scriptable* Sender, Trigger* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return 0; - } - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type != ST_ACTOR) { - return 0; - } - Actor *scr = (Actor *) Sender; - if (MatchActor(Sender, scr->LastTalker, parameters->objectParameter)) { - return 1; - } - return 0; -} - -int GameScript::IsRotation(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - if ( actor->GetOrientation() == parameters->int0Parameter ) { - return 1; - } - return 0; -} - -//GemRB currently stores the saved location in a local variable, but it is -//actually stored in the .gam structure (only for PCs) -int GameScript::IsFacingSavedRotation(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type!=ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - if (actor->GetOrientation() == actor->GetStat(IE_SAVEDFACE) ) { - return 1; - } - return 0; -} - -int GameScript::IsFacingObject(Scriptable* Sender, Trigger* parameters) -{ - if (Sender->Type != ST_ACTOR) { - return 0; - } - Scriptable* target = GetActorFromObject( Sender, parameters->objectParameter ); - if (!target) { - return 0; - } - Actor* actor = ( Actor* ) Sender; - if (actor->GetOrientation()==GetOrient( target->Pos, actor->Pos ) ) { - return 1; - } - return 0; -} - -int GameScript::AttackedBy(Scriptable* Sender, Trigger* parameters) -{ - return Sender->MatchTriggerWithObject(trigger_attackedby, parameters->objectParameter, parameters->int0Parameter); - /*if (Sender->Type!=ST_ACTOR) { - return 0; - } - Actor *scr = (Actor *) Sender; - Targets *tgts = GetAllObjects(Sender->GetCurrentArea(), Sender, parameters->objectParameter, GA_NO_DEAD); - int ret = 0; - int AStyle = parameters->int0Parameter; - //iterate through targets to get the actor - if (tgts) { - targetlist::iterator m; - const targettype *tt = tgts->GetFirstTarget(m, ST_ACTOR); - while (tt) { - Actor *actor = (Actor *) tt->actor; - //if (actor->LastTarget == scr->GetID()) { - if (scr->LastAttacker == actor->GetGlobalID()) { - if (!AStyle || (AStyle==actor->GetAttackStyle()) ) { - scr->AddTrigger(&scr->LastAttacker); - ret = 1; - break; - } - } - tt = tgts->GetNextTarget(m, ST_ACTOR); - } - } - delete tgts; - return ret;*/ -} - -int GameScript::TookDamage(Scriptable* Sender, Trigger* /*parameters*/) -{ - return Sender->MatchTrigger(trigger_tookdamage); - /*if (Sender->Type!=ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) Sender; - //zero damage doesn't count? - if (actor->LastHitter && actor->LastDamage) { - Sender->AddTrigger(&actor->LastHitter); - return 1; - } - return 0;*/ -} - -int GameScript::HitBy(Scriptable* Sender, Trigger* parameters) -{ - return Sender->MatchTriggerWithObject(trigger_attackedby, parameters->objectParameter, parameters->int0Parameter); -} - -int GameScript::Heard(Scriptable* Sender, Trigger* parameters) -{ - return Sender->MatchTriggerWithObject(trigger_heard, parameters->objectParameter, parameters->int0Parameter); -} - -int GameScript::LastMarkedObject_Trigger(Scriptable* Sender, Trigger* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) Sender; - if (MatchActor(Sender, actor->LastMarked, parameters->objectParameter)) { - //don't mark this object for clear - //Sender->AddTrigger(&actor->LastSeen); - return 1; - } - return 0; -} - -int GameScript::HelpEX(Scriptable* Sender, Trigger* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return 0; - } - int stat; - switch (parameters->int0Parameter) { - case 1: stat = IE_EA; break; - case 2: stat = IE_GENERAL; break; - case 3: stat = IE_RACE; break; - case 4: stat = IE_CLASS; break; - case 5: stat = IE_SPECIFIC; break; - case 6: stat = IE_SEX; break; - case 7: stat = IE_ALIGNMENT; break; - default: return 0; - } - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type!=ST_ACTOR) { - //a non actor checking for help? - return 0; - } - Actor* actor = ( Actor* ) tar; - Actor* help = Sender->GetCurrentArea()->GetActorByGlobalID(actor->LastHelp); - if (!help) { - //no help required - return 0; - } - if (actor->GetStat(stat)==help->GetStat(stat) ) { - // FIXME - //Sender->AddTrigger(&actor->LastHelp); - return 1; - } - return 0; -} - -int GameScript::Help_Trigger(Scriptable* Sender, Trigger* parameters) -{ - return Sender->MatchTriggerWithObject(trigger_help, parameters->objectParameter); -} - -int GameScript::ReceivedOrder(Scriptable* Sender, Trigger* parameters) -{ - return Sender->MatchTriggerWithObject(trigger_receivedorder, parameters->objectParameter, parameters->int0Parameter); -} - -int GameScript::Joins(Scriptable* Sender, Trigger* parameters) -{ - return Sender->MatchTriggerWithObject(trigger_joins, parameters->objectParameter); - /*if(Sender->Type!=ST_ACTOR) { - return 0; - } - Actor * actor = ( Actor* ) Sender; - //this trigger is sent only to PCs in a party - if(!actor->PCStats) { - return 0; - } - if (MatchActor(Sender, actor->PCStats->LastJoined, parameters->objectParameter)) { - Sender->AddTrigger(&actor->PCStats->LastJoined); - return 1; - } - return 0;*/ -} - -int GameScript::Leaves(Scriptable* Sender, Trigger* parameters) -{ - return Sender->MatchTriggerWithObject(trigger_leaves, parameters->objectParameter); - /*if(Sender->Type!=ST_ACTOR) { - return 0; - } - Actor * actor = ( Actor* ) Sender; - //this trigger is sent only to PCs in a party - if(!actor->PCStats) { - return 0; - } - if (MatchActor(Sender, actor->PCStats->LastLeft, parameters->objectParameter)) { - Sender->AddTrigger(&actor->PCStats->LastLeft); - return 1; - } - return 0;*/ -} - -int GameScript::FallenPaladin(Scriptable* Sender, Trigger* /*parameters*/) -{ - if (Sender->Type!=ST_ACTOR) { - return 0; - } - Actor* act = ( Actor* ) Sender; - return (act->GetStat(IE_MC_FLAGS) & MC_FALLEN_PALADIN)!=0; -} - -int GameScript::FallenRanger(Scriptable* Sender, Trigger* /*parameters*/) -{ - if (Sender->Type!=ST_ACTOR) { - return 0; - } - Actor* act = ( Actor* ) Sender; - return (act->GetStat(IE_MC_FLAGS) & MC_FALLEN_RANGER)!=0; -} - -int GameScript::NightmareModeOn(Scriptable* /*Sender*/, Trigger* /*parameters*/) -{ - ieDword diff; - - core->GetDictionary()->Lookup("Nightmare Mode", diff); - if (diff) { - return 1; - } - return 0; -} - -int GameScript::Difficulty(Scriptable* /*Sender*/, Trigger* parameters) -{ - ieDword diff; - - core->GetDictionary()->Lookup("Difficulty Level", diff); - int mode = parameters->int1Parameter; - //hack for compatibility - if (!mode) { - mode = EQUALS; - } - return DiffCore(diff, (ieDword) parameters->int0Parameter, mode); -} - -int GameScript::DifficultyGT(Scriptable* /*Sender*/, Trigger* parameters) -{ - ieDword diff; - - core->GetDictionary()->Lookup("Difficulty Level", diff); - return diff>(ieDword) parameters->int0Parameter; -} - -int GameScript::DifficultyLT(Scriptable* /*Sender*/, Trigger* parameters) -{ - ieDword diff; - - core->GetDictionary()->Lookup("Difficulty Level", diff); - return diff<(ieDword) parameters->int0Parameter; -} - -int GameScript::Vacant(Scriptable* Sender, Trigger* /*parameters*/) -{ - if (Sender->Type!=ST_AREA) { - return 0; - } - Map *map = (Map *) Sender; - if ( map->CanFree() ) { - return 1; - } - return 0; -} - -//this trigger always checks the right hand weapon? -int GameScript::InWeaponRange(Scriptable* Sender, Trigger* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return 0; - } - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar) { - return 0; - } - Actor *actor = (Actor *) Sender; - WeaponInfo wi; - unsigned int wrange = 0; - ITMExtHeader *header = actor->GetWeapon(wi, false); - if (header) { - wrange = wi.range; - } - header = actor->GetWeapon(wi, true); - if (header && (wi.range>wrange)) { - wrange = wi.range; - } - if ( PersonalDistance( Sender, tar ) <= wrange * 10 ) { - return 1; - } - return 0; -} - -//this implementation returns only true if there is a bow wielded -//but there is no ammo for it -//if the implementation should sign 'no ranged attack possible' -//then change some return values -//in bg2/iwd2 it doesn't accept an object (the object parameter is gemrb ext.) -int GameScript::OutOfAmmo(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* scr = Sender; - if (parameters->objectParameter) { - scr = GetActorFromObject( Sender, parameters->objectParameter ); - } - if ( !scr || scr->Type!=ST_ACTOR) { - return 0; - } - Actor *actor = (Actor *) scr; - WeaponInfo wi; - ITMExtHeader *header = actor->GetWeapon(wi, false); - //no bow wielded? - if (!header || header->AttackType!=ITEM_AT_BOW) { - return 0; - } - //we either have a projectile (negative) or an empty bow (positive) - //so we should find a negative slot, positive slot means: OutOfAmmo - if (actor->inventory.GetEquipped()<0) { - return 0; - } - //out of ammo - return 1; -} - -//returns true if a weapon is equipped (with more than 0 range) -//if a bow is equipped without projectile, it is useless! -//please notice how similar is this to OutOfAmmo -int GameScript::HaveUsableWeaponEquipped(Scriptable* Sender, Trigger* /*parameters*/) -{ - if (Sender->Type!=ST_ACTOR) { - return 0; - } - Actor *actor = (Actor *) Sender; - WeaponInfo wi; - ITMExtHeader *header = actor->GetWeapon(wi, false); - - //bows are not usable (because if they are loaded, the equipped - //weapon is the projectile) - if (!header || header->AttackType==ITEM_AT_BOW) { - return 0; - } - //only fist we have, it is not qualified as weapon? - if (actor->inventory.GetEquippedSlot() == actor->inventory.GetFistSlot()) { - return 0; - } - return 1; -} - -int GameScript::HasWeaponEquipped(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type!=ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - if (actor->inventory.GetEquippedSlot() == IW_NO_EQUIPPED) { - return 0; - } - return 1; -} - -int GameScript::PCInStore( Scriptable* /*Sender*/, Trigger* /*parameters*/) -{ - if (core->GetCurrentStore()) { - return 1; - } - return 0; -} - -//this checks if the launch point is onscreen, a more elaborate check -//would see if any piece of the Scriptable is onscreen, what is the original -//behaviour? -int GameScript::OnScreen( Scriptable* Sender, Trigger* /*parameters*/) -{ - Region vp = core->GetVideoDriver()->GetViewport(); - if (vp.PointInside(Sender->Pos) ) { - return 1; - } - return 0; -} - -int GameScript::IsPlayerNumber( Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type!=ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - if (actor->InParty == parameters->int0Parameter) { - return 1; - } - return 0; -} - -int GameScript::PCCanSeePoint( Scriptable* /*Sender*/, Trigger* parameters) -{ - Map* map = core->GetGame()->GetCurrentArea(); - if (map->IsVisible(parameters->pointParameter, false) ) { - return 1; - } - return 0; -} - -//i'm clueless about this trigger -int GameScript::StuffGlobalRandom( Scriptable* Sender, Trigger* parameters) -{ - unsigned int max=parameters->int0Parameter+1; - ieDword Value; - if (max) { - Value = RandomNumValue%max; - } else { - Value = RandomNumValue; - } - SetVariable( Sender, parameters->string0Parameter, Value ); - if (Value) { - return 1; - } - return 0; -} - -int GameScript::IsCreatureAreaFlag( Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type!=ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - if (actor->GetStat(IE_MC_FLAGS) & parameters->int0Parameter) { - return 1; - } - return 0; -} - -int GameScript::IsPathCriticalObject( Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type!=ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - if (actor->GetStat(IE_MC_FLAGS) & MC_PLOT_CRITICAL) { - return 1; - } - return 0; -} - -// 0 - ability, 1 - number, 2 - mode -int GameScript::ChargeCount( Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type!=ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - int Slot = actor->inventory.FindItem(parameters->string0Parameter,0); - if (Slot<0) { - return 0; - } - CREItem *item = actor->inventory.GetSlotItem (Slot); - if (!item) {//bah - return 0; - } - if (parameters->int0Parameter>2) { - return 0; - } - int charge = item->Usages[parameters->int0Parameter]; - switch (parameters->int2Parameter) { - case DM_EQUAL: - if (charge == parameters->int1Parameter) - return 1; - break; - case DM_LESS: - if (charge < parameters->int1Parameter) - return 1; - break; - case DM_GREATER: - if (charge > parameters->int1Parameter) - return 1; - break; - default: - return 0; - } - return 0; -} - -// no idea if it checks only alive partymembers -int GameScript::CheckPartyLevel( Scriptable* /*Sender*/, Trigger* parameters) -{ - if (core->GetGame()->GetPartyLevel(false)int0Parameter) { - return 0; - } - return 1; -} - -// no idea if it checks only alive partymembers -int GameScript::CheckPartyAverageLevel( Scriptable* /*Sender*/, Trigger* parameters) -{ - int level = core->GetGame()->GetPartyLevel(false); - switch (parameters->int1Parameter) { - case DM_EQUAL: - if (level ==parameters->int0Parameter) { - return 1; - } - break; - case DM_LESS: - if (level < parameters->int0Parameter) { - return 1; - } - break; - case DM_GREATER: - if (level > parameters->int0Parameter) { - return 1; - } - break; - default: - return 0; - } - return 1; -} - -int GameScript::CheckDoorFlags( Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type!=ST_DOOR) { - return 0; - } - Door* door = ( Door* ) tar; - if (door->Flags¶meters->int0Parameter) { - return 1; - } - return 0; -} - -// works only on animations? -// Be careful when converting to GetActorFromObject, it won't return animations (those are not scriptable) -int GameScript::Frame( Scriptable* Sender, Trigger* parameters) -{ - //to avoid a crash - if (!parameters->objectParameter) { - return 0; - } - AreaAnimation* anim = Sender->GetCurrentArea()->GetAnimation(parameters->objectParameter->objectName); - if (!anim) { - return 0; - } - int frame = anim->frame; - if ((frame>=parameters->int0Parameter) && - (frame<=parameters->int1Parameter) ) { - return 1; - } - return 0; -} - -//Modalstate in IWD2 allows specifying an object -int GameScript::ModalState( Scriptable* Sender, Trigger* parameters) -{ - Scriptable *scr; - - if (parameters->objectParameter) { - scr = GetActorFromObject( Sender, parameters->objectParameter ); - } else { - scr = Sender; - } - if (scr->Type!=ST_ACTOR) { - return 0; - } - Actor *actor = (Actor *) scr; - - if (actor->ModalState==(ieDword) parameters->int0Parameter) { - return 1; - } - return 0; -} - -/* a special redundant trigger for iwd2 - could do something extra */ -int GameScript::IsCreatureHiddenInShadows( Scriptable* Sender, Trigger* /*parameters*/) -{ - if (Sender->Type!=ST_ACTOR) { - return 0; - } - Actor *actor = (Actor *) Sender; - - if (actor->ModalState==MS_STEALTH) { - return 1; - } - return 0; -} - -int GameScript::IsWeather( Scriptable* /*Sender*/, Trigger* parameters) -{ - Game *game = core->GetGame(); - ieDword weather = game->WeatherBits & parameters->int0Parameter; - if (weather == (ieDword) parameters->int1Parameter) { - return 1; - } - return 0; -} - -int GameScript::Delay( Scriptable* Sender, Trigger* parameters) -{ - ieDword delay = (ieDword) parameters->int0Parameter; - if (delay<=1) { - return 1; - } - - return (Sender->ScriptTicks % delay) <= Sender->IdleTicks; -} - -int GameScript::TimeOfDay(Scriptable* /*Sender*/, Trigger* parameters) -{ - ieDword timeofday = (core->GetGame()->GameTime/AI_UPDATE_TIME)%7200/1800; - - if (timeofday==(ieDword) parameters->int0Parameter) { - return 1; - } - return 0; -} - -//this is a PST action, it's using delta, not diffmode -int GameScript::RandomStatCheck(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type!=ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - - ieDword stat = actor->GetStat(parameters->int0Parameter); - ieDword value = Bones(parameters->int2Parameter); - switch(parameters->int1Parameter) { - case DM_SET: - if (stat==value) - return 1; - break; - case DM_LOWER: - if (statvalue) - return 1; - break; - } - return 0; -} - -int GameScript::PartyRested(Scriptable* Sender, Trigger* /*parameters*/) -{ - return Sender->MatchTrigger(trigger_partyrested); -} - -int GameScript::IsWeaponRanged(Scriptable* Sender, Trigger* parameters) -{ - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type!=ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - if (actor->inventory.GetEquipped()<0) { - return 1; - } - return 0; -} - -//HoW applies sequence on area animations -int GameScript::Sequence(Scriptable* Sender, Trigger* parameters) -{ - //to avoid a crash, check if object is NULL - if (parameters->objectParameter) { - AreaAnimation *anim = Sender->GetCurrentArea()->GetAnimation(parameters->objectParameter->objectName); - if (anim) { - //this is the cycle count for the area animation - //very much like stance for avatar anims - if (anim->sequence==parameters->int0Parameter) { - return 1; - } - return 0; - } - } - - Scriptable *tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - if (actor->GetStance()==parameters->int0Parameter) { - return 1; - } - return 0; -} - -int GameScript::TimerExpired(Scriptable* Sender, Trigger* parameters) -{ - if (Sender->TimerExpired(parameters->int0Parameter) ) { - return 1; - } - return 0; -} - -int GameScript::TimerActive(Scriptable* Sender, Trigger* parameters) -{ - if (Sender->TimerActive(parameters->int0Parameter) ) { - return 1; - } - return 0; -} - -int GameScript::ActuallyInCombat(Scriptable* /*Sender*/, Trigger* /*parameters*/) -{ - Game *game=core->GetGame(); - if (game->AnyPCInCombat()) return 1; - return 0; -} - -int GameScript::InMyGroup(Scriptable* Sender, Trigger* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return 0; - } - - Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type!=ST_ACTOR) { - return 0; - } -/* IESDP SUCKS - if (GetGroup( (Actor *) tar)==GetGroup( (Actor *) Sender) ) { - return 1; - } -*/ - if ( ((Actor *) tar)->GetStat(IE_SPECIFIC)==((Actor *) tar)->GetStat(IE_SPECIFIC) ) { - return 1; - } - return 0; -} - -int GameScript::AnyPCSeesEnemy(Scriptable* /*Sender*/, Trigger* /*parameters*/) -{ - Game *game = core->GetGame(); - unsigned int i = (unsigned int) game->GetLoadedMapCount(); - while(i--) { - Map *map = game->GetMap(i); - if (map->AnyPCSeesEnemy()) { - return 1; - } - } - return 0; -} - -int GameScript::Unusable(Scriptable* Sender, Trigger* parameters) -{ - if (Sender->Type!=ST_ACTOR) { - return 0; - } - Actor *actor = (Actor *) Sender; - - Item *item = gamedata->GetItem(parameters->string0Parameter); - int ret; - if (actor->Unusable(item)) { - ret = 0; - } else { - ret = 1; - } - gamedata->FreeItem(item, parameters->string0Parameter, true); - return ret; -} - -int GameScript::HasBounceEffects(Scriptable* Sender, Trigger* parameters) -{ - Scriptable *tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - if (actor->GetStat(IE_BOUNCE)) return 1; - return 0; -} - -int GameScript::HasImmunityEffects(Scriptable* Sender, Trigger* parameters) -{ - Scriptable *tar = GetActorFromObject( Sender, parameters->objectParameter ); - if (!tar || tar->Type != ST_ACTOR) { - return 0; - } - Actor* actor = ( Actor* ) tar; - if (actor->GetStat(IE_IMMUNITY)) return 1; - return 0; -} - -// this is a GemRB specific trigger, to transfer some system variables -// to a global (game variable), it will always return true, and the -// variable could be checked in a subsequent trigger (like triggersetglobal) - -#define SYSV_SCREENFLAGS 0 -#define SYSV_CONTROLSTATUS 1 -#define SYSV_REPUTATION 2 -#define SYSV_PARTYGOLD 3 - -int GameScript::SystemVariable_Trigger(Scriptable* Sender, Trigger* parameters) -{ - ieDword value; - - switch (parameters->int0Parameter) { - case SYSV_SCREENFLAGS: - value = core->GetGameControl()->GetScreenFlags(); - break; - case SYSV_CONTROLSTATUS: - value = core->GetGame()->ControlStatus; - break; - case SYSV_REPUTATION: - value = core->GetGame()->Reputation; - break; - case SYSV_PARTYGOLD: - value = core->GetGame()->PartyGold; - break; - default: - return 0; - } - - SetVariable(Sender, parameters->string0Parameter, value); - return 1; -} - -int GameScript::SpellCast(Scriptable* Sender, Trigger* parameters) -{ - return Sender->MatchTriggerWithObject(trigger_spellcast, parameters->objectParameter, parameters->int0Parameter); - /*if(parameters->int0Parameter) { - unsigned int param = 2000+parameters->int0Parameter%1000; - if (param!=Sender->LastSpellSeen) { - return 0; - } - } - if(MatchActor(Sender, Sender->LastCasterSeen, parameters->objectParameter)) { - Sender->AddTrigger(&Sender->LastCasterSeen); - return 1; - } - return 0;*/ -} - -int GameScript::SpellCastPriest(Scriptable* Sender, Trigger* parameters) -{ - return Sender->MatchTriggerWithObject(trigger_spellcastpriest, parameters->objectParameter, parameters->int0Parameter); - /*if(parameters->int0Parameter) { - unsigned int param = 1000+parameters->int0Parameter%1000; - if (param!=Sender->LastSpellSeen) { - return 0; - } - } - if(MatchActor(Sender, Sender->LastCasterSeen, parameters->objectParameter)) { - Sender->AddTrigger(&Sender->LastCasterSeen); - return 1; - } - return 0;*/ -} - -int GameScript::SpellCastInnate(Scriptable* Sender, Trigger* parameters) -{ - return Sender->MatchTriggerWithObject(trigger_spellcastinnate, parameters->objectParameter, parameters->int0Parameter); - /*if(parameters->int0Parameter) { - unsigned int param = 3000+parameters->int0Parameter%1000; - if (param!=Sender->LastSpellSeen) { - return 0; - } - } - if(MatchActor(Sender, Sender->LastCasterSeen, parameters->objectParameter)) { - Sender->AddTrigger(&Sender->LastCasterSeen); - return 1; - } - return 0;*/ -} - -int GameScript::SpellCastOnMe(Scriptable* Sender, Trigger* parameters) -{ - return Sender->MatchTriggerWithObject(trigger_spellcastonme, parameters->objectParameter, parameters->int0Parameter); - /*if(parameters->int0Parameter) { - if ((ieDword) parameters->int0Parameter!=Sender->LastSpellOnMe) { - return 0; - } - } - if(MatchActor(Sender, Sender->LastCasterOnMe, parameters->objectParameter)) { - Sender->AddTrigger(&Sender->LastCasterOnMe); - return 1; - } - return 0;*/ -} - -int GameScript::CalendarDay(Scriptable* /*Sender*/, Trigger* parameters) -{ - int day = core->GetCalendar()->GetCalendarDay(core->GetGame()->GameTime/AI_UPDATE_TIME/7200); - if(day == parameters->int0Parameter) { - return 1; - } - return 0; -} - -int GameScript::CalendarDayGT(Scriptable* /*Sender*/, Trigger* parameters) -{ - int day = core->GetCalendar()->GetCalendarDay(core->GetGame()->GameTime/AI_UPDATE_TIME/7200); - if(day > parameters->int0Parameter) { - return 1; - } - return 0; -} - -int GameScript::CalendarDayLT(Scriptable* /*Sender*/, Trigger* parameters) -{ - int day = core->GetCalendar()->GetCalendarDay(core->GetGame()->GameTime/AI_UPDATE_TIME/7200); - if(day < parameters->int0Parameter) { - return 1; - } - return 0; -} - -//NT Returns true only if the active CRE was turned by the specified priest or paladin. -int GameScript::TurnedBy(Scriptable* Sender, Trigger* parameters) -{ - return Sender->MatchTriggerWithObject(trigger_turnedby, parameters->objectParameter); -} diff --git a/project/jni/application/gemrb/gemrb/core/GlobalTimer.cpp b/project/jni/application/gemrb/gemrb/core/GlobalTimer.cpp deleted file mode 100644 index 1319d68b3..000000000 --- a/project/jni/application/gemrb/gemrb/core/GlobalTimer.cpp +++ /dev/null @@ -1,340 +0,0 @@ -/* 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 "GlobalTimer.h" - -#include "ControlAnimation.h" -#include "Game.h" -#include "Interface.h" -#include "Video.h" -#include "GUI/GameControl.h" - -GlobalTimer::GlobalTimer(void) -{ - //AI_UPDATE_TIME: how many AI updates in a second - interval = ( 1000 / AI_UPDATE_TIME ); - Init(); -} - -GlobalTimer::~GlobalTimer(void) -{ - std::vector::iterator i; - for(i = animations.begin(); i != animations.end(); ++i) { - delete (*i); - } -} - -void GlobalTimer::Init() -{ - fadeToCounter = 0; - fadeFromCounter = 0; - fadeFromMax = 0; - fadeToMax = 0; - waitCounter = 0; - shakeCounter = 0; - startTime = 0; //forcing an update - speed = 0; - ClearAnimations(); -} - -void GlobalTimer::Freeze() -{ - unsigned long thisTime; - unsigned long advance; - - thisTime = GetTickCount(); - advance = thisTime - startTime; - if ( advance < interval) { - return; - } - startTime = thisTime; - Game* game = core->GetGame(); - if (!game) { - return; - } - game->RealTime++; - - ieDword count = advance/interval; - // pst/bg2 do this, if you fix it for another game, wrap it in a check - DoFadeStep(count); - - // show scrolling cursor while paused - GameControl* gc = core->GetGameControl(); - if (gc) - gc->UpdateScrolling(); -} - -bool GlobalTimer::ViewportIsMoving() -{ - return (goal.x!=currentVP.x) || (goal.y!=currentVP.y); -} - -void GlobalTimer::SetMoveViewPort(ieDword x, ieDword y, int spd, bool center) -{ - speed=spd; - currentVP=core->GetVideoDriver()->GetViewport(); - if (center) { - x-=currentVP.w/2; - y-=currentVP.h/2; - } - goal.x=(short) x; - goal.y=(short) y; -} - -void GlobalTimer::DoStep(int count) -{ - Video *video = core->GetVideoDriver(); - - int x = currentVP.x; - int y = currentVP.y; - if ( (x != goal.x) || (y != goal.y)) { - if (speed) { - if (xgoal.x) x=goal.x; - } else { - x-=speed; - if (xgoal.y) y=goal.y; - } else { - y-=speed; - if (y>1); - y += (rand()%shakeY) - (shakeY>>1); - } - } - video->MoveViewportTo(x,y); -} - -bool GlobalTimer::Update() -{ - Map *map; - Game *game; - GameControl* gc; - unsigned long thisTime; - unsigned long advance; - - gc = core->GetGameControl(); - if (gc) - gc->UpdateScrolling(); - - UpdateAnimations(); - - thisTime = GetTickCount(); - - if (!startTime) { - startTime = thisTime; - return false; - } - - advance = thisTime - startTime; - if ( advance < interval) { - return false; - } - ieDword count = advance/interval; - DoStep(count); - DoFadeStep(count); - if (!gc) { - goto end; - } - game = core->GetGame(); - if (!game) { - goto end; - } - map = game->GetCurrentArea(); - if (!map) { - goto end; - } - //do spell effects expire in dialogs? - //if yes, then we should remove this condition - if (!(gc->GetDialogueFlags()&DF_IN_DIALOG) ) { - map->UpdateFog(); - map->UpdateEffects(); - if (thisTime) { - //this measures in-world time (affected by effects, actions, etc) - game->AdvanceTime(1); - } - } - //this measures time spent in the game (including pauses) - if (thisTime) { - game->RealTime++; - } -end: - startTime = thisTime; - return true; -} - - -void GlobalTimer::DoFadeStep(ieDword count) { - Video *video = core->GetVideoDriver(); - if (fadeToCounter) { - fadeToCounter-=count; - if (fadeToCounter<0) { - fadeToCounter=0; - } - video->SetFadePercent( ( ( fadeToMax - fadeToCounter ) * 100 ) / fadeToMax ); - //bug/patch #1837747 made this unneeded - //goto end; //hmm, freeze gametime? - } - //i think this 'else' is needed now because of the 'goto' cut above - else if (fadeFromCounter!=fadeFromMax) { - if (fadeFromCounter>fadeFromMax) { - fadeFromCounter-=count; - if (fadeFromCounterfadeFromMax) { - fadeToCounter=fadeFromMax; - } - video->SetFadePercent( ( ( fadeFromMax - fadeFromCounter ) * 100 ) / fadeFromMax ); - //bug/patch #1837747 made this unneeded - //goto end; //freeze gametime? - } - } - if (fadeFromCounter==fadeFromMax) { - video->SetFadePercent( 0 ); - } -} - -void GlobalTimer::SetFadeToColor(unsigned long Count) -{ - if(!Count) { - Count = 64; - } - fadeToCounter = Count; - fadeToMax = fadeToCounter; - //stay black for a while - fadeFromCounter = 128; - fadeFromMax = 0; -} - -void GlobalTimer::SetFadeFromColor(unsigned long Count) -{ - if(!Count) { - Count = 64; - } - fadeFromCounter = 0; - fadeFromMax = Count; -} - -void GlobalTimer::SetWait(unsigned long Count) -{ - waitCounter = Count; -} - -void GlobalTimer::AddAnimation(ControlAnimation* ctlanim, unsigned long time) -{ - AnimationRef* anim; - unsigned long thisTime; - - thisTime = GetTickCount(); - time += thisTime; - - // if there are no free animation reference objects, - // alloc one, else take the first free one - if (first_animation == 0) - anim = new AnimationRef; - else { - anim = animations.front (); - animations.erase (animations.begin()); - first_animation--; - } - - // fill in data - anim->time = time; - anim->ctlanim = ctlanim; - - // and insert it into list of other anim refs, sorted by time - for (std::vector::iterator it = animations.begin() + first_animation; it != animations.end (); it++) { - if ((*it)->time > time) { - animations.insert( it, anim ); - anim = NULL; - break; - } - } - if (anim) - animations.push_back( anim ); -} - -void GlobalTimer::RemoveAnimation(ControlAnimation* ctlanim) -{ - // Animation refs for given control are not physically removed, - // but just marked by erasing ptr to the control. They will be - // collected when they get to the front of the vector - for (std::vector::iterator it = animations.begin() + first_animation; it != animations.end (); it++) { - if ((*it)->ctlanim == ctlanim) { - (*it)->ctlanim = NULL; - } - } -} - -void GlobalTimer::UpdateAnimations() -{ - unsigned long thisTime; - thisTime = GetTickCount(); - while (animations.begin() + first_animation != animations.end()) { - AnimationRef* anim = animations[first_animation]; - if (anim->ctlanim == NULL) { - first_animation++; - continue; - } - - if (anim->time <= thisTime) { - anim->ctlanim->UpdateAnimation(); - first_animation++; - continue; - } - break; - } -} - -void GlobalTimer::ClearAnimations() -{ - first_animation = (unsigned int) animations.size(); -} - -void GlobalTimer::SetScreenShake(unsigned long shakeX, unsigned long shakeY, - unsigned long Count) -{ - this->shakeX = shakeX; - this->shakeY = shakeY; - shakeCounter = Count+1; -} diff --git a/project/jni/application/gemrb/gemrb/core/GlobalTimer.h b/project/jni/application/gemrb/gemrb/core/GlobalTimer.h deleted file mode 100644 index bcb933102..000000000 --- a/project/jni/application/gemrb/gemrb/core/GlobalTimer.h +++ /dev/null @@ -1,78 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ -#ifndef GLOBALTIMER_H -#define GLOBALTIMER_H - -#include "exports.h" -#include "win32def.h" - -#include "Region.h" - -#include - -class ControlAnimation; - -struct AnimationRef -{ - ControlAnimation *ctlanim; - unsigned long time; -}; - - -class GEM_EXPORT GlobalTimer { -private: - unsigned long startTime; - unsigned long interval; - - int fadeToCounter, fadeToMax; - int fadeFromCounter, fadeFromMax; - unsigned long waitCounter; - int shakeCounter; - unsigned long shakeX, shakeY; - unsigned int first_animation; - std::vector animations; - //move viewport to this coordinate - Point goal; - int speed; - Region currentVP; - - void DoFadeStep(ieDword count); -public: - GlobalTimer(void); - ~GlobalTimer(void); -public: - void Init(); - void Freeze(); - bool Update(); - bool ViewportIsMoving(); - void DoStep(int count); - void SetMoveViewPort(ieDword x, ieDword y, int spd, bool center); - void SetFadeToColor(unsigned long Count); - void SetFadeFromColor(unsigned long Count); - void SetWait(unsigned long Count); - void SetScreenShake(unsigned long shakeX, unsigned long shakeY, - unsigned long Count); - void AddAnimation(ControlAnimation* ctlanim, unsigned long time); - void RemoveAnimation(ControlAnimation* ctlanim); - void ClearAnimations(); - void UpdateAnimations(); -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/Holder.h b/project/jni/application/gemrb/gemrb/core/Holder.h deleted file mode 100644 index 170a4c87e..000000000 --- a/project/jni/application/gemrb/gemrb/core/Holder.h +++ /dev/null @@ -1,95 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#ifndef HOLDER_H -#define HOLDER_H - -#include -#include - -template -class Held { -public: - Held() : RefCount(0) {} - void acquire() { ++RefCount; } - void release() { assert(RefCount && "Broken Held usage."); - if (!--RefCount) delete static_cast(this); } - size_t GetRefCount() { return RefCount; } -private: - size_t RefCount; -}; - -/** - * @class Holder - * Intrusive smart pointer. - * - * The class T must have member function acquire and release, such that - * acquire increases the refcount, and release decreses the refcount and - * frees the object if needed. - * - * Derived class of Holder shouldn't add member variables. That way, - * they can freely converted to Holder without slicing. - */ - -template -class Holder { -public: - Holder(T* ptr = NULL) - : ptr(ptr) - { - if (ptr) - ptr->acquire(); - } - ~Holder() - { - if (ptr) - ptr->release(); - } - Holder(const Holder& rhs) - : ptr(rhs.ptr) - { - if (ptr) - ptr->acquire(); - } - Holder& operator=(const Holder& rhs) - { - if (rhs.ptr) - rhs.ptr->acquire(); - if (ptr) - ptr->release(); - ptr = rhs.ptr; - return *this; - } - T& operator*() const { return *ptr; } - T* operator->() const { return ptr; } - bool operator!() const { return !ptr; } -#include "operatorbool.h" - OPERATOR_BOOL(Holder,T,ptr) - T* get() const { return ptr; } - void release() { - if (ptr) - ptr->release(); - ptr = NULL; - } -protected: - T *ptr; -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/Image.cpp b/project/jni/application/gemrb/gemrb/core/Image.cpp deleted file mode 100644 index 8b03e095b..000000000 --- a/project/jni/application/gemrb/gemrb/core/Image.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2007 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "Image.h" - -#include "Interface.h" -#include "Video.h" - -Image::Image(unsigned int w, unsigned int h) - : height(h), width(w), data(new Color[height*width]) -{ -} - -Image::~Image() -{ - delete[] data; -} - -Sprite2D* Image::GetSprite2D() -{ - union { - Color color; - ieDword Mask; - } r = {{ 0xFF, 0x00, 0x00, 0x00 }}, - g = {{ 0x00, 0xFF, 0x00, 0x00 }}, - b = {{ 0x00, 0x00, 0xFF, 0x00 }}, - a = {{ 0x00, 0x00, 0x00, 0xFF }}; - void *pixels = malloc(sizeof(Color) * height*width); - memcpy(pixels, data, sizeof(Color)*height*width); - return core->GetVideoDriver()->CreateSprite(width, height, 32, - r.Mask, g.Mask, b.Mask, a.Mask, pixels); -} diff --git a/project/jni/application/gemrb/gemrb/core/Image.h b/project/jni/application/gemrb/gemrb/core/Image.h deleted file mode 100644 index 9628d6561..000000000 --- a/project/jni/application/gemrb/gemrb/core/Image.h +++ /dev/null @@ -1,61 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2007 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef IMAGE_H -#define IMAGE_H - -#include "RGBAColor.h" -#include "exports.h" - -class Sprite2D; - -class GEM_EXPORT Image { -public: - Image(unsigned int height, unsigned int width); - ~Image(); - Color GetPixel(unsigned int x, unsigned int y) const - { - if (x >= width || y >= height) { - static const Color black = { 0, 0, 0, 0 }; - return black; - } - return data[width*y+x]; - - } - void SetPixel(unsigned int x, unsigned int y, Color idx) - { - if (x >= width || y >= height) - return; - data[width*y+x] = idx; - - } - unsigned int GetHeight() const - { - return height; - } - unsigned int GetWidth() const - { - return width; - } - Sprite2D *GetSprite2D(); -private: - unsigned int height, width; - Color *data; -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/ImageFactory.cpp b/project/jni/application/gemrb/gemrb/core/ImageFactory.cpp deleted file mode 100644 index 17ad0d0c6..000000000 --- a/project/jni/application/gemrb/gemrb/core/ImageFactory.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2007 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "ImageFactory.h" - -#include "Interface.h" -#include "Video.h" - -ImageFactory::ImageFactory(const char* ResRef, Sprite2D* bitmap_) - : FactoryObject( ResRef, IE_BMP_CLASS_ID ), bitmap(bitmap_) -{ - -} - -ImageFactory::~ImageFactory(void) -{ - core->GetVideoDriver()->FreeSprite( bitmap ); -} - -Sprite2D* ImageFactory::GetSprite2D() const -{ - bitmap->acquire(); - return bitmap; -} - diff --git a/project/jni/application/gemrb/gemrb/core/ImageFactory.h b/project/jni/application/gemrb/gemrb/core/ImageFactory.h deleted file mode 100644 index c0576d99f..000000000 --- a/project/jni/application/gemrb/gemrb/core/ImageFactory.h +++ /dev/null @@ -1,40 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2007 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#ifndef IMAGEFACTORY_H -#define IMAGEFACTORY_H - -#include "exports.h" -#include "globals.h" - -#include "FactoryObject.h" -#include "Sprite2D.h" - -class GEM_EXPORT ImageFactory : public FactoryObject { -private: - Sprite2D* bitmap; -public: - ImageFactory(const char* ResRef, Sprite2D* bitmap); - ~ImageFactory(void); - - Sprite2D* GetSprite2D() const; -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/ImageMgr.cpp b/project/jni/application/gemrb/gemrb/core/ImageMgr.cpp deleted file mode 100644 index 3275d3e13..000000000 --- a/project/jni/application/gemrb/gemrb/core/ImageMgr.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "ImageMgr.h" - -#include "win32def.h" - -#include "ImageFactory.h" -#include "Interface.h" -#include "Video.h" - -const TypeID ImageMgr::ID = { "ImageMgr" }; - -ImageMgr::ImageMgr(void) -{ -} - -ImageMgr::~ImageMgr(void) -{ -} - -Bitmap* ImageMgr::GetBitmap() -{ - unsigned int height = GetHeight(); - unsigned int width = GetWidth(); - Bitmap *data = new Bitmap(width, height); - - printMessage("ImageMgr", "Don't know how to handle 24bit bitmap from %s...", WHITE, - str->filename ); - printStatus( "ERROR", LIGHT_RED ); - - Sprite2D *spr = GetSprite2D(); - - for (unsigned int y = 0; y < height; y++) { - for (unsigned int x = 0; x < width; x++) { - data->SetAt(x,y, spr->GetPixel(x,y).r); - } - } - - core->GetVideoDriver()->FreeSprite(spr); - - return data; -} - -Image* ImageMgr::GetImage() -{ - unsigned int height = GetHeight(); - unsigned int width = GetWidth(); - Image *data = new Image(width, height); - - Sprite2D *spr = GetSprite2D(); - - for (unsigned int y = 0; y < height; y++) { - for (unsigned int x = 0; x < width; x++) { - data->SetPixel(x,y, spr->GetPixel(x,y)); - } - } - - core->GetVideoDriver()->FreeSprite(spr); - - return data; -} - -void ImageMgr::GetPalette(int /*colors*/, Color* /*pal*/) -{ - printMessage("ImageMgr", "Can't get non-existant palette from %s... ", WHITE, - str->filename); - printStatus("ERROR", LIGHT_RED); -} - -ImageFactory* ImageMgr::GetImageFactory(const char* ResRef) -{ - ImageFactory* fact = new ImageFactory( ResRef, GetSprite2D() ); - return fact; -} diff --git a/project/jni/application/gemrb/gemrb/core/ImageMgr.h b/project/jni/application/gemrb/gemrb/core/ImageMgr.h deleted file mode 100644 index 40d4709eb..000000000 --- a/project/jni/application/gemrb/gemrb/core/ImageMgr.h +++ /dev/null @@ -1,68 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#ifndef IMAGEMGR_H -#define IMAGEMGR_H - -#include "exports.h" - -#include "Bitmap.h" -#include "Image.h" -#include "Resource.h" -#include "Sprite2D.h" -#include "System/DataStream.h" - -class ImageFactory; - -/** - * Base class for Image plugins. - */ -class GEM_EXPORT ImageMgr : public Resource { -public: - static const TypeID ID; -public: - ImageMgr(void); - virtual ~ImageMgr(void); - /** Returns a \ref Sprite2D containing the image. */ - virtual Sprite2D* GetSprite2D() = 0; - virtual Image* GetImage(); - virtual Bitmap* GetBitmap(); - /** - * Returns image palette. - * - * @param[in] colors Number of colors to return. - * @param[out] pal Array to fill with colors. - * - * This does nothing if there is no palette. - */ - virtual void GetPalette(int colors, Color* pal); - /** Returns the width of the image */ - virtual int GetWidth() = 0; - /** Returns the height of the image */ - virtual int GetHeight() = 0; - /** - * Returns a \ref ImageFactory for the current image. - * - * @param[in] ResRef name of image represented by factory. - */ - ImageFactory* GetImageFactory(const char* ResRef); -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/ImageWriter.cpp b/project/jni/application/gemrb/gemrb/core/ImageWriter.cpp deleted file mode 100644 index 4c2eae78b..000000000 --- a/project/jni/application/gemrb/gemrb/core/ImageWriter.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2007 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "ImageWriter.h" - -ImageWriter::ImageWriter(void) -{ -} - -ImageWriter::~ImageWriter(void) -{ -} diff --git a/project/jni/application/gemrb/gemrb/core/ImageWriter.h b/project/jni/application/gemrb/gemrb/core/ImageWriter.h deleted file mode 100644 index a02a44b7b..000000000 --- a/project/jni/application/gemrb/gemrb/core/ImageWriter.h +++ /dev/null @@ -1,35 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2007 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef IMAGEWRITER_H -#define IMAGEWRITER_H - -#include "Plugin.h" -#include "Sprite2D.h" -#include "System/DataStream.h" - -class GEM_EXPORT ImageWriter : public Plugin { -public: - ImageWriter(void); - ~ImageWriter(void); - - /** Writes an Sprite2D to a stream and frees the sprite. */ - virtual void PutImage(DataStream *output, Sprite2D *sprite) = 0; -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/IndexedArchive.cpp b/project/jni/application/gemrb/gemrb/core/IndexedArchive.cpp deleted file mode 100644 index e39eb6891..000000000 --- a/project/jni/application/gemrb/gemrb/core/IndexedArchive.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#include "IndexedArchive.h" - -IndexedArchive::IndexedArchive(void) -{ -} - -IndexedArchive::~IndexedArchive(void) -{ -} diff --git a/project/jni/application/gemrb/gemrb/core/IndexedArchive.h b/project/jni/application/gemrb/gemrb/core/IndexedArchive.h deleted file mode 100644 index 3938ceee9..000000000 --- a/project/jni/application/gemrb/gemrb/core/IndexedArchive.h +++ /dev/null @@ -1,36 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -#ifndef INDEXEDARCHIVE_H -#define INDEXEDARCHIVE_H - -#include "globals.h" - -#include "Plugin.h" - -class GEM_EXPORT IndexedArchive : public Plugin { -public: - IndexedArchive(void); - virtual ~IndexedArchive(void); - virtual int OpenArchive(const char* filename) = 0; - virtual DataStream* GetStream(unsigned long Resource, unsigned long Type) = 0; -}; - -#endif diff --git a/project/jni/application/gemrb/gemrb/core/IniSpawn.cpp b/project/jni/application/gemrb/gemrb/core/IniSpawn.cpp deleted file mode 100644 index 374ecc956..000000000 --- a/project/jni/application/gemrb/gemrb/core/IniSpawn.cpp +++ /dev/null @@ -1,717 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2007 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -// This class handles the special spawn structures of planescape torment -// (stored in .ini format) - -#include "IniSpawn.h" - -#include "win32def.h" - -#include "CharAnimations.h" -#include "Game.h" -#include "GameData.h" -#include "Interface.h" -#include "Map.h" -#include "PluginMgr.h" -#include "GameScript/GSUtils.h" -#include "GameScript/Matching.h" -#include "Scriptable/Actor.h" - -static const int StatValues[9]={ -IE_EA, IE_FACTION, IE_TEAM, IE_GENERAL, IE_RACE, IE_CLASS, IE_SPECIFIC, -IE_SEX, IE_ALIGNMENT }; - -IniSpawn::IniSpawn(Map *owner) -{ - map = owner; - NamelessSpawnArea[0] = 0; - NamelessState = 35; - NamelessVar = NULL; - namelessvarcount = 0; - Locals = NULL; - localscount = 0; - eventspawns = NULL; - eventcount = 0; - last_spawndate = 0; -} - -IniSpawn::~IniSpawn() -{ - if (eventspawns) { - delete[] eventspawns; - } -} - -static Holder GetIniFile(const ieResRef DefaultArea) -{ - //the lack of spawn ini files is not a serious problem, happens all the time - if (!gamedata->Exists( DefaultArea, IE_INI_CLASS_ID)) { - return NULL; - } - - DataStream* inifile = gamedata->GetResource( DefaultArea, IE_INI_CLASS_ID ); - if (!inifile) { - return NULL; - } - if (!core->IsAvailable( IE_INI_CLASS_ID )) { - printStatus( "ERROR", LIGHT_RED ); - printMessage( "IniSpawn","No INI Importer Available.\n",LIGHT_RED ); - return NULL; - } - - PluginHolder ini(IE_INI_CLASS_ID); - ini->Open(inifile); - return ini; -} - -/*** initializations ***/ - -static inline int CountElements(const char *s, char separator) -{ - int ret = 1; - while(*s) { - if (*s==separator) ret++; - s++; - } - return ret; -} - -static inline void GetElements(const char *s, ieResRef *storage, int count) -{ - while(count--) { - ieResRef *field = storage+count; - strnuprcpy(*field, s, sizeof(ieResRef)-1); - for(size_t i=0;iGetKeyAsString(crittername,"spec_var",NULL); - if (s) { - if ((strlen(s)>9) && s[6]==':' && s[7]==':') { - strnuprcpy(critter.SpecContext, s, 6); - strnlwrcpy(critter.SpecVar, s+8, 32); - } else { - strnuprcpy(critter.SpecContext, "GLOBAL", 6); - strnlwrcpy(critter.SpecVar, s, 32); - } - } - - //add this to specvar at each spawn - ps = inifile->GetKeyAsInt(crittername,"spec_var_inc", 0); - critter.SpecVarInc=ps; - - //use this value with spec_var_operation to determine spawn - ps = inifile->GetKeyAsInt(crittername,"spec_var_value",0); - critter.SpecVarValue=ps; - //this operation uses DiffCore - s = inifile->GetKeyAsString(crittername,"spec_var_operation",""); - critter.SpecVarOperator=GetDiffMode(s); - //the amount of critters to spawn - critter.TotalQuantity = inifile->GetKeyAsInt(crittername,"spec_qty",1); - critter.SpawnCount = inifile->GetKeyAsInt(crittername,"create_qty",critter.TotalQuantity); - - //the creature resource(s) - s = inifile->GetKeyAsString(crittername,"cre_file",NULL); - if (s) { - critter.creaturecount = CountElements(s,','); - critter.CreFile=new ieResRef[critter.creaturecount]; - GetElements(s, critter.CreFile, critter.creaturecount); - } else { - printMessage("IniSpawn", "Invalid spawn entry: %s\n", LIGHT_RED, crittername); - } - - s = inifile->GetKeyAsString(crittername,"point_select",NULL); - - if (s) { - ps=s[0]; - } else { - ps=0; - } - - s = inifile->GetKeyAsString(crittername,"spawn_point",NULL); - if (s) { - //expect more than one spawnpoint - if (ps=='r') { - //select one of the spawnpoints randomly - int count = core->Roll(1,CountElements(s,']'),-1); - //go to the selected spawnpoint - while(count--) { - while(*s++!=']') ; - } - } - //parse the selected spawnpoint - int x,y,o; - if (sscanf(s,"[%d.%d:%d]", &x, &y, &o)==3) { - critter.SpawnPoint.x=(short) x; - critter.SpawnPoint.y=(short) y; - critter.Orientation=o; - } else { - if (sscanf(s,"[%d.%d]", &x, &y)==2) { - critter.SpawnPoint.x=(short) x; - critter.SpawnPoint.y=(short) y; - critter.Orientation=core->Roll(1,16,-1); - } - } - } - - //store or retrieve spawn point - s = inifile->GetKeyAsString(crittername,"spawn_point_global", NULL); - if (s) { - switch (ps) { - case 'e': - critter.SpawnPoint.fromDword(CheckVariable(map, s+8,s)); - break; - default: - //see save_selected_point - //SetVariable(map, s+8, s, critter.SpawnPoint.asDword()); - break; - } - } - - //take facing from variable - s = inifile->GetKeyAsString(crittername,"spawn_facing_global", NULL); - if (s) { - switch (ps) { - case 'e': - critter.Orientation=(int) CheckVariable(map, s+8,s); - break; - default: - //see save_selected_point - //SetVariable(map, s+8, s, (ieDword) critter.Orientation); - break; - } - } - - s = inifile->GetKeyAsString(crittername,"save_selected_point",NULL); - if (s) { - if ((strlen(s)>9) && s[6]==':' && s[7]==':') { - SetVariable(map, s+8, s, critter.SpawnPoint.asDword()); - } else { - SetVariable(map, s, "GLOBAL", critter.SpawnPoint.asDword()); - } - } - s = inifile->GetKeyAsString(crittername,"save_selected_facing",NULL); - if (s) { - if ((strlen(s)>9) && s[6]==':' && s[7]==':') { - SetVariable(map, s+8, s, (ieDword) critter.Orientation); - } else { - SetVariable(map, s, "GLOBAL", (ieDword) critter.Orientation); - } - } - - //sometimes only the orientation is given, the point is stored in a variable - ps = inifile->GetKeyAsInt(crittername,"facing",-1); - if (ps!=-1) critter.Orientation = ps; - ps = inifile->GetKeyAsInt(crittername, "ai_ea",-1); - if (ps!=-1) critter.SetSpec[AI_EA] = (ieByte) ps; - ps = inifile->GetKeyAsInt(crittername, "ai_team",-1); - if (ps!=-1) critter.SetSpec[AI_TEAM] = (ieByte) ps; - ps = inifile->GetKeyAsInt(crittername, "ai_general",-1); - if (ps!=-1) critter.SetSpec[AI_GENERAL] = (ieByte) ps; - ps = inifile->GetKeyAsInt(crittername, "ai_race",-1); - if (ps!=-1) critter.SetSpec[AI_RACE] = (ieByte) ps; - ps = inifile->GetKeyAsInt(crittername, "ai_class",-1); - if (ps!=-1) critter.SetSpec[AI_CLASS] = (ieByte) ps; - ps = inifile->GetKeyAsInt(crittername, "ai_specifics",-1); - if (ps!=-1) critter.SetSpec[AI_SPECIFICS] = (ieByte) ps; - ps = inifile->GetKeyAsInt(crittername, "ai_gender",-1); - if (ps!=-1) critter.SetSpec[AI_GENDER] = (ieByte) ps; - ps = inifile->GetKeyAsInt(crittername, "ai_alignment",-1); - if (ps!=-1) critter.SetSpec[AI_ALIGNMENT] = (ieByte) ps; - - s = inifile->GetKeyAsString(crittername,"spec",NULL); - if (s) { - int x[9]; - - ps = sscanf(s,"[%d.%d.%d.%d.%d.%d.%d.%d.%d]", x, x+1, x+2, x+3, x+4, x+5, - x+6, x+7, x+8); - if (ps == 0) { - strnuprcpy(critter.ScriptName, s, 32); - critter.Flags|=CF_CHECK_NAME; - memset(critter.Spec,-1,sizeof(critter.Spec)); - } else { - while(ps--) { - critter.Spec[ps]=(ieByte) x[ps]; - } - } - } - - s = inifile->GetKeyAsString(crittername,"script_name",NULL); - if (s) { - strnuprcpy(critter.ScriptName, s, 32); - } - - //iwd2 script names (override remains the same) - //special 1 == area - s = inifile->GetKeyAsString(crittername,"script_special_1",NULL); - if (s) { - strnuprcpy(critter.AreaScript,s, 8); - } - //special 2 == class - s = inifile->GetKeyAsString(crittername,"script_special_2",NULL); - if (s) { - strnuprcpy(critter.ClassScript,s, 8); - } - //special 3 == general - s = inifile->GetKeyAsString(crittername,"script_special_3",NULL); - if (s) { - strnuprcpy(critter.GeneralScript,s, 8); - } - //team == specific - s = inifile->GetKeyAsString(crittername,"script_team",NULL); - if (s) { - strnuprcpy(critter.SpecificScript,s, 8); - } - - //combat == race - s = inifile->GetKeyAsString(crittername,"script_combat",NULL); - if (s) { - strnuprcpy(critter.RaceScript,s, 8); - } - //movement == default - s = inifile->GetKeyAsString(crittername,"script_movement",NULL); - if (s) { - strnuprcpy(critter.DefaultScript,s, 8); - } - - //pst script names - s = inifile->GetKeyAsString(crittername,"script_override",NULL); - if (s) { - strnuprcpy(critter.OverrideScript,s, 8); - } - s = inifile->GetKeyAsString(crittername,"script_class",NULL); - if (s) { - strnuprcpy(critter.ClassScript,s, 8); - } - s = inifile->GetKeyAsString(crittername,"script_race",NULL); - if (s) { - strnuprcpy(critter.RaceScript,s, 8); - } - s = inifile->GetKeyAsString(crittername,"script_general",NULL); - if (s) { - strnuprcpy(critter.GeneralScript,s, 8); - } - s = inifile->GetKeyAsString(crittername,"script_default",NULL); - if (s) { - strnuprcpy(critter.DefaultScript,s, 8); - } - s = inifile->GetKeyAsString(crittername,"script_area",NULL); - if (s) { - strnuprcpy(critter.AreaScript,s, 8); - } - s = inifile->GetKeyAsString(crittername,"script_specifics",NULL); - if (s) { - strnuprcpy(critter.SpecificScript,s, 8); - } - s = inifile->GetKeyAsString(crittername,"dialog",NULL); - if (s) { - strnuprcpy(critter.Dialog,s, 8); - } - - //flags - if (inifile->GetKeyAsBool(crittername,"death_scriptname",false)) { - critter.Flags|=CF_DEATHVAR; - } - //don't spawn when spawnpoint is visible - if (inifile->GetKeyAsBool(crittername,"ignore_can_see",false)) { - critter.Flags|=CF_IGNORECANSEE; - } - //unsure, but could be similar to previous - if (inifile->GetKeyAsBool(crittername,"check_view_port", false)) { - critter.Flags|=CF_CHECKVIEWPORT; - } - //unknown, this is used only in pst - if (inifile->GetKeyAsBool(crittername,"check_crowd", false)) { - critter.Flags|=CF_CHECKCROWD; - } - //unknown, this is used only in pst - if (inifile->GetKeyAsBool(crittername,"find_safest_point", false)) { - critter.Flags|=CF_SAFESTPOINT; - } - //disable spawn based on game difficulty - if (inifile->GetKeyAsBool(crittername,"area_diff_1", false)) { - critter.Flags|=CF_NO_DIFF_1; - } - if (inifile->GetKeyAsBool(crittername,"area_diff_2", false)) { - critter.Flags|=CF_NO_DIFF_2; - } - if (inifile->GetKeyAsBool(crittername,"area_diff_3", false)) { - critter.Flags|=CF_NO_DIFF_3; - } -} - -void IniSpawn::ReadSpawnEntry(DataFileMgr *inifile, const char *entryname, SpawnEntry &entry) -{ - const char *s; - - entry.interval = (unsigned int) inifile->GetKeyAsInt(entryname,"interval",0); - //don't default to NULL here, some entries may be missing in original game - //an empty default string here will create an empty but consistent entry - s = inifile->GetKeyAsString(entryname,"critters",""); - int crittercount = CountElements(s,','); - entry.crittercount=crittercount; - entry.critters=new CritterEntry[crittercount]; - ieVariable *critters = new ieVariable[crittercount]; - GetElements(s, critters, crittercount); - while(crittercount--) { - ReadCreature(inifile, critters[crittercount], entry.critters[crittercount]); - } - delete[] critters; -} - -/* set by action */ -void IniSpawn::SetNamelessDeath(const ieResRef area, Point &pos, ieDword state) -{ - strnuprcpy(NamelessSpawnArea, area, 8); - NamelessSpawnPoint = pos; - NamelessState = state; -} - -void IniSpawn::InitSpawn(const ieResRef DefaultArea) -{ - const char *s; - - Holder inifile = GetIniFile(DefaultArea); - if (!inifile) { - strnuprcpy(NamelessSpawnArea, DefaultArea, 8); - return; - } - - s = inifile->GetKeyAsString("nameless","destare",DefaultArea); - strnuprcpy(NamelessSpawnArea, s, 8); - s = inifile->GetKeyAsString("nameless","point","[0.0]"); - int x,y; - if (sscanf(s,"[%d.%d]", &x, &y)!=2) { - x=0; - y=0; - } - NamelessSpawnPoint.x=x; - NamelessSpawnPoint.y=y; - //35 - already standing - //36 - getting up - NamelessState = inifile->GetKeyAsInt("nameless","state",36); - - namelessvarcount = inifile->GetKeysCount("namelessvar"); - if (namelessvarcount) { - NamelessVar = new VariableSpec[namelessvarcount]; - for (y=0;yGetKeyNameByIndex("namelessvar",y); - strnlwrcpy(NamelessVar[y].Name, Key, 32); - NamelessVar[y].Value = inifile->GetKeyAsInt("namelessvar",Key,0); - } - } - - localscount = inifile->GetKeysCount("locals"); - if (localscount) { - Locals = new VariableSpec[localscount]; - for (y=0;yGetKeyNameByIndex("locals",y); - strnlwrcpy(Locals[y].Name, Key, 32); - Locals[y].Value = inifile->GetKeyAsInt("locals",Key,0); - } - } - - s = inifile->GetKeyAsString("spawn_main","enter",NULL); - if (s) { - ReadSpawnEntry(inifile.get(), s, enterspawn); - } - s = inifile->GetKeyAsString("spawn_main","events",NULL); - if (s) { - eventcount = CountElements(s,','); - eventspawns = new SpawnEntry[eventcount]; - ieVariable *events = new ieVariable[eventcount]; - GetElements(s, events, eventcount); - int ec = eventcount; - while(ec--) { - ReadSpawnEntry(inifile.get(), events[ec], eventspawns[ec]); - } - delete[] events; - } - //maybe not correct - InitialSpawn(); -} - - -/*** events ***/ - -//respawn nameless after he bit the dust -void IniSpawn::RespawnNameless() -{ - Game *game = core->GetGame(); - Actor *nameless = game->GetPC(0, false); - - if (NamelessSpawnPoint.isnull()) { - core->GetGame()->JoinParty(nameless,JP_INITPOS); - NamelessSpawnPoint=nameless->Pos; - strnuprcpy(NamelessSpawnArea, nameless->Area, 8); - } - - nameless->Resurrect(); - //hardcoded!!! - if (NamelessState==36) { - nameless->SetStance(IE_ANI_PST_START); - } - int i; - - for (i=0;iGetPartySize(false);i++) { - MoveBetweenAreasCore(game->GetPC(i, false),NamelessSpawnArea,NamelessSpawnPoint,-1, true); - } - - //certain variables are set when nameless dies - for (i=0;i=0) { - // dunno if this should be negated - if (!DiffCore(specvar, critter.SpecVarValue, critter.SpecVarOperator) ) { - return; - } - } else { - //ar0203 in PST seems to want the check this way. - //if other areas conflict and you want to use (!specvar), - //please research further - //researched further - ar0203 respawns only if specvar is 1 - if (!specvar) { - return; - } - } - } - - if (!(critter.Flags&CF_IGNORECANSEE)) { - if (map->IsVisible(critter.SpawnPoint, false) ) { - return; - } - } - - if (critter.Flags&CF_NO_DIFF_MASK) { - ieDword difficulty; - ieDword diff_bit; - - core->GetDictionary()->Lookup("Difficulty Level", difficulty); - switch (difficulty) - { - case 0: - diff_bit = CF_NO_DIFF_1; - break; - case 1: - diff_bit = CF_NO_DIFF_2; - break; - case 2: - diff_bit = CF_NO_DIFF_3; - break; - default: - diff_bit = 0; - } - if (critter.Flags&diff_bit) { - return; - } - } - - if (critter.ScriptName[0] && (critter.Flags&CF_CHECK_NAME) ) { - //maybe this one needs to be using getobjectcount as well - //currently we cannot count objects with scriptname??? - if (map->GetActor( critter.ScriptName, 0 )) { - return; - } - } else { - //Object *object = new Object(); - Object object; - //objectfields based on spec - object.objectFields[0]=critter.Spec[0]; - object.objectFields[1]=critter.Spec[1]; - object.objectFields[2]=critter.Spec[2]; - object.objectFields[3]=critter.Spec[3]; - object.objectFields[4]=critter.Spec[4]; - object.objectFields[5]=critter.Spec[5]; - object.objectFields[6]=critter.Spec[6]; - object.objectFields[7]=critter.Spec[7]; - object.objectFields[8]=critter.Spec[8]; - int cnt = GetObjectCount(map, &object); - if (cnt>=critter.TotalQuantity) { - return; - } - } - - int x = core->Roll(1,critter.creaturecount,-1); - Actor* cre = gamedata->GetCreature(critter.CreFile[x]); - if (!cre) { - return; - } - - SetVariable(map, critter.SpecVar, critter.SpecContext, specvar+(ieDword) critter.SpecVarInc); - map->AddActor(cre); - for (x=0;x<9;x++) { - if (critter.SetSpec[x]) { - cre->SetBase(StatValues[x], critter.SetSpec[x]); - } - } - cre->SetPosition( critter.SpawnPoint, 0, 0);//maybe critters could be repositioned - cre->SetOrientation(critter.Orientation,false); - if (critter.ScriptName[0]) { - cre->SetScriptName(critter.ScriptName); - } - if (critter.OverrideScript[0]) { - cre->SetScript(critter.OverrideScript, SCR_OVERRIDE); - } - if (critter.ClassScript[0]) { - cre->SetScript(critter.ClassScript, SCR_CLASS); - } - if (critter.RaceScript[0]) { - cre->SetScript(critter.RaceScript, SCR_RACE); - } - if (critter.GeneralScript[0]) { - cre->SetScript(critter.GeneralScript, SCR_GENERAL); - } - if (critter.DefaultScript[0]) { - cre->SetScript(critter.DefaultScript, SCR_DEFAULT); - } - if (critter.AreaScript[0]) { - cre->SetScript(critter.AreaScript, SCR_AREA); - } - if (critter.SpecificScript[0]) { - cre->SetScript(critter.SpecificScript, SCR_SPECIFICS); - } - if (critter.Dialog[0]) { - cre->SetDialog(critter.Dialog); - } -} - -void IniSpawn::SpawnGroup(SpawnEntry &event) -{ - if (!event.critters) { - return; - } - unsigned int interval = event.interval; - if (interval) { - if(core->GetGame()->GameTime/interval<=last_spawndate/interval) { - return; - } - } - last_spawndate=core->GetGame()->GameTime; - - for(int i=0;iSpawnCount;j++) { - SpawnCreature(*critter); - } - } -} - -//execute the initial spawn -void IniSpawn::InitialSpawn() -{ - SpawnGroup(enterspawn); - //these variables are set when entering first - for (int i=0;i.ini files - * @author The GemRB Project - */ - -#ifndef INISPAWN_H -#define INISPAWN_H - -#include "exports.h" -#include "ie_types.h" - -#include "DataFileMgr.h" -#include "Region.h" - -class Map; - -/** - * @struct CritterEntry - */ - -//critter flags -#define CF_IGNORECANSEE 1 -#define CF_DEATHVAR 2 -#define CF_NO_DIFF_1 4 -#define CF_NO_DIFF_2 8 -#define CF_NO_DIFF_3 16 -#define CF_CHECKVIEWPORT 32 -#define CF_CHECKCROWD 64 -#define CF_SAFESTPOINT 128 -#define CF_NO_DIFF_MASK 28 -#define CF_CHECK_NAME 256 -//spec ids flags -#define AI_EA 0 -#define AI_FACTION 1 -#define AI_TEAM 2 -#define AI_GENERAL 3 -#define AI_RACE 4 -#define AI_CLASS 5 -#define AI_SPECIFICS 6 -#define AI_GENDER 7 -#define AI_ALIGNMENT 8 - -//spawn point could be: -// s - single -// r - random -// e - preset -// save_select_point saves the spawnpoint - -struct CritterEntry { - int creaturecount; - ieResRef *CreFile; //spawn one of these creatures - ieByte Spec[9]; //existance check IDS qualifier - ieByte SetSpec[9]; //set IDS qualifier - ieVariable ScriptName; //existance check scripting name - ieVariable SpecVar; //condition variable - ieResRef SpecContext; //condition variable context - ieResRef OverrideScript; //override override script - ieResRef ClassScript; //overrride class script - ieResRef RaceScript; //override race script - ieResRef GeneralScript; //override general script - ieResRef DefaultScript; //override default script - ieResRef AreaScript; //override area script - ieResRef SpecificScript; //override specific script - ieResRef Dialog; //override dialog - ieVariable SpawnPointVar; //spawn point saved location - Point SpawnPoint; //spawn point - int SpecVarOperator; //operation performed on spec var - int SpecVarValue; //using this value with the operation - int SpecVarInc; //add this to spec var at each spawn - int Orientation; //spawn orientation - int Flags; //CF_IGNORENOSEE, CF_DEATHVAR, etc - int TotalQuantity; //total number - int SpawnCount; //create quantity -}; - -/** - * @class SpawnEntry - */ -class SpawnEntry { -public: - ieDword interval; - int crittercount; - CritterEntry *critters; - SpawnEntry() { - interval = 0; - crittercount = 0; - critters = NULL; - } - ~SpawnEntry() { - if (critters) { - for (int i=0;i -#endif - -#include "Interface.h" - -#include "exports.h" -#include "globals.h" -#include "strrefs.h" -#include "win32def.h" - -#include "ActorMgr.h" -#include "AmbientMgr.h" -#include "AnimationMgr.h" -#include "ArchiveImporter.h" -#include "Audio.h" -#include "Calendar.h" -#include "DataFileMgr.h" -#include "DialogHandler.h" -#include "DialogMgr.h" -#include "DisplayMessage.h" -#include "EffectMgr.h" -#include "EffectQueue.h" -#include "Factory.h" -#include "Game.h" -#include "GameData.h" -#include "GlobalTimer.h" -#include "ImageMgr.h" -#include "ItemMgr.h" -#include "KeyMap.h" -#include "MapMgr.h" -#include "MoviePlayer.h" -#include "MusicMgr.h" -#include "Palette.h" -#include "PluginLoader.h" -#include "PluginMgr.h" -#include "ProjectileServer.h" -#include "SaveGameIterator.h" -#include "SaveGameMgr.h" -#include "ScriptEngine.h" -#include "ScriptedAnimation.h" -#include "SoundMgr.h" -#include "SpellMgr.h" -#include "StoreMgr.h" -#include "StringMgr.h" -#include "SymbolMgr.h" -#include "TileMap.h" -#include "Video.h" -#include "WindowMgr.h" -#include "WorldMapMgr.h" -#include "GameScript/GameScript.h" -#include "GUI/Button.h" -#include "GUI/Console.h" -#include "GUI/EventMgr.h" -#include "GUI/GameControl.h" -#include "GUI/Label.h" -#include "GUI/MapControl.h" -#include "GUI/Window.h" -#include "GUI/WorldMapControl.h" -#include "Scriptable/Container.h" -#include "System/FileStream.h" -#include "System/VFS.h" - -#if defined(__HAIKU__) -#include -#endif - -#include -#include -#include - -GEM_EXPORT Interface* core; - -#ifdef WIN32 -GEM_EXPORT HANDLE hConsole; -#endif - -//use DialogF.tlk if the protagonist is female, that's why we leave space -static const char dialogtlk[] = "dialog.tlk\0"; - -static int MaximumAbility = 25; -static ieWordSigned *strmod = NULL; -static ieWordSigned *strmodex = NULL; -static ieWordSigned *intmod = NULL; -static ieWordSigned *dexmod = NULL; -static ieWordSigned *conmod = NULL; -static ieWordSigned *chrmod = NULL; -static ieWordSigned *lorebon = NULL; -static ieWordSigned *wisbon = NULL; -static int **reputationmod = NULL; -static ieVariable IWD2DeathVarFormat = "_DEAD%s"; -static ieVariable DeathVarFormat = "SPRITE_IS_DEAD%s"; - -Interface::Interface(int iargc, char* iargv[]) -{ - argc = iargc; - argv = iargv; -#ifdef WIN32 - hConsole = GetStdHandle( STD_OUTPUT_HANDLE ); -#endif - textcolor( LIGHT_WHITE ); - print( "GemRB Core Version v%s Loading...\n", VERSION_GEMRB ); - - // default to the correct endianswitch - ieWord endiantest = 1; - if (((char *)&endiantest)[1] == 1) { - // big-endian - DataStream::SetEndianSwitch(true); - } - - unsigned int i; - for(i=0;i<256;i++) { - pl_uppercase[i]=(ieByte) toupper(i); - pl_lowercase[i]=(ieByte) tolower(i); - } - - projserv = NULL; - VideoDriverName = "sdl"; - AudioDriverName = "openal"; - vars = NULL; - tokens = NULL; - lists = NULL; - RtRows = NULL; - sgiterator = NULL; - game = NULL; - calendar = NULL; - keymap = NULL; - worldmap = NULL; - CurrentStore = NULL; - CurrentContainer = NULL; - UseContainer = false; - InfoTextPalette = NULL; - timer = NULL; - displaymsg = NULL; - evntmgr = NULL; - console = NULL; - slottypes = NULL; - slotmatrix = NULL; - - ModalWindow = NULL; - tooltip_x = 0; - tooltip_y = 0; - tooltip_currtextw = 0; - tooltip_ctrl = NULL; - plugin_flags = NULL; - - pal16 = NULL; - pal32 = NULL; - pal256 = NULL; - - GUIEnhancements = 0; - - CursorCount = 0; - Cursors = NULL; - - mousescrollspd = 10; - - strncpy( GameType, "auto", sizeof( GameType )-1); - ConsolePopped = false; - CheatFlag = false; - FogOfWar = 1; - QuitFlag = QF_NORMAL; - EventFlag = EF_CONTROL; -#ifndef WIN32 - CaseSensitive = true; //this is the default value, so CD1/CD2 will be resolved -#else - CaseSensitive = false; -#endif - GameOnCD = false; - SkipIntroVideos = false; - DrawFPS = false; - KeepCache = false; - TouchScrollAreas = false; - TooltipDelay = 100; - IgnoreOriginalINI = 0; - FullScreen = 0; - GUIScriptsPath[0] = 0; - GamePath[0] = 0; - SavePath[0] = 0; - GemRBPath[0] = 0; - PluginsPath[0] = 0; - CachePath[0] = 0; - GemRBOverridePath[0] = 0; - GameName[0] = 0; - - strncpy( GameOverridePath, "override", sizeof(GameOverridePath) ); - strncpy( GameSoundsPath, "sounds", sizeof(GameSoundsPath) ); - strncpy( GameScriptsPath, "scripts", sizeof(GameScriptsPath) ); - strncpy( GamePortraitsPath, "portraits", sizeof(GamePortraitsPath) ); - strncpy( GameCharactersPath, "characters", sizeof(GameCharactersPath) ); - strncpy( GameDataPath, "data", sizeof(GameDataPath) ); - strncpy( INIConfig, "baldur.ini", sizeof(INIConfig) ); - strncpy( ButtonFont, "STONESML", sizeof(ButtonFont) ); - strncpy( TooltipFont, "STONESML", sizeof(TooltipFont) ); - strncpy( MovieFont, "STONESML", sizeof(MovieFont) ); - strncpy( ScrollCursorBam, "CURSARW", sizeof(ScrollCursorBam) ); - strncpy( GlobalScript, "BALDUR", sizeof(GlobalScript) ); - strncpy( WorldMapName[0], "WORLDMAP", sizeof(ieResRef) ); - memset( WorldMapName[1], 0, sizeof(ieResRef) ); - strncpy( Palette16, "MPALETTE", sizeof(Palette16) ); - strncpy( Palette32, "PAL32", sizeof(Palette32) ); - strncpy( Palette256, "MPAL256", sizeof(Palette256) ); - strcpy( TooltipBackResRef, "\0" ); - for (int size = 0; size < MAX_CIRCLE_SIZE; size++) { - strcpy( GroundCircleBam[size], "\0" ); - GroundCircleScale[size] = 0; - } - TooltipColor.r = 0; - TooltipColor.g = 255; - TooltipColor.b = 0; - TooltipColor.a = 255; - TooltipMargin = 10; - - TooltipBack = NULL; - DraggedItem = NULL; - DraggedPortrait = 0; - DefSound = NULL; - DSCount = -1; - memset(GameFeatures, 0, sizeof( GameFeatures )); - //GameFeatures = 0; - //GameFeatures2 = 0; - memset( WindowFrames, 0, sizeof( WindowFrames )); - memset( GroundCircles, 0, sizeof( GroundCircles )); - memset(FogSprites, 0, sizeof( FogSprites )); - AreaAliasTable = NULL; - ItemExclTable = NULL; - ItemDialTable = NULL; - ItemDial2Table = NULL; - ItemTooltipTable = NULL; - update_scripts = false; - SpecialSpellsCount = -1; - SpecialSpells = NULL; - - gamedata = new GameData(); -} - -#define FreeResourceVector(type, variable) \ -{ \ - size_t i=variable.size(); \ - while(i--) { \ - if (variable[i]) { \ - delete variable[i]; \ - } \ - } \ - variable.clear(); \ -} - -//2da lists are ieDword lists allocated by malloc -static void Release2daList(void *poi) -{ - free( (ieDword *) poi); -} - -static void ReleaseItemList(void *poi) -{ - delete ((ItemList *) poi); -} - -static void FreeAbilityTables() -{ - if (strmod) { - free(strmod); - } - strmod = NULL; - if (strmodex) { - free(strmodex); - } - strmodex = NULL; - if (intmod) { - free(intmod); - } - intmod = NULL; - if (dexmod) { - free(dexmod); - } - dexmod = NULL; - if (conmod) { - free(conmod); - } - conmod = NULL; - if (chrmod) { - free(chrmod); - } - chrmod = NULL; - if (lorebon) { - free(lorebon); - } - lorebon = NULL; - if (wisbon) { - free(wisbon); - } - wisbon = NULL; -} - -void Interface::FreeResRefTable(ieResRef *&table, int &count) -{ - if (table) { - free( table ); - count = -1; - } -} - -static void ReleaseItemTooltip(void *poi) -{ - free(poi); -} - -Interface::~Interface(void) -{ - DragItem(NULL,NULL); - delete AreaAliasTable; - - if (music) { - music->HardEnd(); - } - // stop any ambients which are still enqueued - if (AudioDriver) { - AmbientMgr *ambim = AudioDriver->GetAmbientMgr(); - if (ambim) ambim->deactivate(); - } - //destroy the highest objects in the hierarchy first! - delete game; - delete calendar; - delete worldmap; - delete keymap; - - FreeAbilityTables(); - - if (reputationmod) { - for (unsigned int i=0; i<20; i++) { - if (reputationmod[i]) { - free(reputationmod[i]); - } - } - free(reputationmod); - reputationmod=NULL; - } - - if (SpecialSpells) { - free(SpecialSpells); - } - SurgeSpells.clear(); - - PluginMgr::Get()->RunCleanup(); - - ReleaseMemoryActor(); - EffectQueue_ReleaseMemory(); - CharAnimations::ReleaseMemory(); - - FreeResRefTable(DefSound, DSCount); - - free( slottypes ); - free( slotmatrix ); - - delete sgiterator; - - if (Cursors) { - for (int i = 0; i < CursorCount; i++) { - video->FreeSprite( Cursors[i] ); - } - delete[] Cursors; - } - - FreeResourceVector( Font, fonts ); - FreeResourceVector( Window, windows ); - - size_t i; - for (i = 0; i < musiclist.size(); i++) { - free((void *)musiclist[i]); - } - - DamageInfoMap.clear(); - - ModalStates.clear(); - - delete plugin_flags; - - delete projserv; - - delete console; - - delete pal256; - delete pal32; - delete pal16; - - delete timer; - delete displaymsg; - - if (video) { - - for(i=0;iFreeSprite(FogSprites[i]); - } - - for(i=0;i<4;i++) { - video->FreeSprite(WindowFrames[i]); - } - - for (int size = 0; size < MAX_CIRCLE_SIZE; size++) { - for(i=0;i<6;i++) { - video->FreeSprite(GroundCircles[size][i]); - } - } - - if (TooltipBack) { - for(i=0;i<3;i++) { - //freesprite checks for null pointer - video->FreeSprite(TooltipBack[i]); - } - delete[] TooltipBack; - } - if (InfoTextPalette) { - gamedata->FreePalette(InfoTextPalette); - } - - video->SetDragCursor(NULL); - } - - delete evntmgr; - - delete vars; - delete tokens; - if (lists) { - lists->RemoveAll(Release2daList); - delete lists; - } - - if (RtRows) { - RtRows->RemoveAll(ReleaseItemList); - delete RtRows; - } - if (ItemExclTable) { - ItemExclTable->RemoveAll(NULL); - delete ItemExclTable; - } - if (ItemDialTable) { - ItemDialTable->RemoveAll(NULL); - delete ItemDialTable; - } - if (ItemDial2Table) { - ItemDial2Table->RemoveAll(NULL); - delete ItemDial2Table; - } - if (ItemTooltipTable) { - ItemTooltipTable->RemoveAll(ReleaseItemTooltip); - delete ItemTooltipTable; - } - - Map::ReleaseMemory(); - Actor::ReleaseMemory(); - - gamedata->ClearCaches(); - delete gamedata; - gamedata = NULL; - - // Removing all stuff from Cache, except bifs - if (!KeepCache) DelTree((const char *) CachePath, true); -} - -void Interface::SetWindowFrame(int i, Sprite2D *Picture) -{ - video->FreeSprite(WindowFrames[i]); - WindowFrames[i]=Picture; -} - -GameControl* Interface::StartGameControl() -{ - //making sure that our window is the first one - if (ConsolePopped) { - PopupConsole(); - } - DelAllWindows();//deleting ALL windows - gamedata->DelTable(0xffffu); //dropping ALL tables - Window* gamewin = new Window( 0xffff, 0, 0, (ieWord) Width, (ieWord) Height ); - gamewin->WindowPack[0]=0; - GameControl* gc = new GameControl(); - gc->XPos = 0; - gc->YPos = 0; - gc->Width = (ieWord) Width; - gc->Height = (ieWord) Height; - gc->Owner = gamewin; - gc->ControlID = 0x00000000; - gc->ControlType = IE_GUI_GAMECONTROL; - gamewin->AddControl( gc ); - AddWindow( gamewin ); - SetVisible( 0, WINDOW_VISIBLE ); - //setting the focus to the game control - evntmgr->SetFocused(gamewin, gc); - if (guiscript->LoadScript( "MessageWindow" )) { - guiscript->RunFunction( "MessageWindow", "OnLoad" ); - gc->UnhideGUI(); - } - - return gc; -} - -/* handle main loop events that might destroy or create windows -thus cannot be called from DrawWindows directly -these events are pending until conditions are right -*/ -void Interface::HandleEvents() -{ - GameControl *gc = GetGameControl(); - if (gc && (!gc->Owner || !gc->Owner->Visible)) { - gc=NULL; - } - - if (EventFlag&EF_SELECTION) { - EventFlag&=~EF_SELECTION; - guiscript->RunFunction( "GUICommonWindows", "SelectionChanged", false); - } - - if (EventFlag&EF_UPDATEANIM) { - EventFlag&=~EF_UPDATEANIM; - guiscript->RunFunction( "GUICommonWindows", "UpdateAnimation", false); - } - - if (EventFlag&EF_PORTRAIT) { - ieDword tmp = (ieDword) ~0; - vars->Lookup( "PortraitWindow", tmp ); - if (tmp != (ieDword) ~0) { - EventFlag&=~EF_PORTRAIT; - guiscript->RunFunction( "GUICommonWindows", "UpdatePortraitWindow" ); - } - } - - if (EventFlag&EF_ACTION) { - ieDword tmp = (ieDword) ~0; - vars->Lookup( "ActionsWindow", tmp ); - if (tmp != (ieDword) ~0) { - EventFlag&=~EF_ACTION; - guiscript->RunFunction( "GUICommonWindows", "UpdateActionsWindow" ); - } - } - - if ((EventFlag&EF_CONTROL) && gc) { - EventFlag&=~EF_CONTROL; - guiscript->RunFunction( "MessageWindow", "UpdateControlStatus" ); - //this is the only value we can use here - if (game->ControlStatus & CS_HIDEGUI) - gc->HideGUI(); - else - gc->UnhideGUI(); - return; - } - if ((EventFlag&EF_SHOWMAP) && gc) { - ieDword tmp = (ieDword) ~0; - vars->Lookup( "OtherWindow", tmp ); - if (tmp == (ieDword) ~0) { - EventFlag &= ~EF_SHOWMAP; - guiscript->RunFunction( "GUIMA", "ShowMap" ); - } - return; - } - - if (EventFlag&EF_SEQUENCER) { - EventFlag&=~EF_SEQUENCER; - guiscript->RunFunction( "GUIMG", "OpenSequencerWindow" ); - return; - } - - if (EventFlag&EF_IDENTIFY) { - EventFlag&=~EF_IDENTIFY; - // FIXME: Implement this. - guiscript->RunFunction( "GUICommonWindows", "OpenIdentifyWindow" ); - return; - } - if (EventFlag&EF_OPENSTORE) { - EventFlag&=~EF_OPENSTORE; - guiscript->RunFunction( "GUISTORE", "OpenStoreWindow" ); - return; - } - - if (EventFlag&EF_EXPANSION) { - EventFlag&=~EF_EXPANSION; - guiscript->RunFunction( "MessageWindow", "GameExpansion", false ); - return; - } - - if (EventFlag&EF_CREATEMAZE) { - EventFlag&=~EF_CREATEMAZE; - 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 -thus cannot be called from DrawWindows directly -*/ -void Interface::HandleFlags() -{ - //clear events because the context changed - EventFlag = EF_CONTROL; - - if (QuitFlag&(QF_QUITGAME|QF_EXITGAME) ) { - // when reaching this, quitflag should be 1 or 2 - // if Exitgame was set, we'll set Start.py too - QuitGame (QuitFlag&QF_EXITGAME); - QuitFlag &= ~(QF_QUITGAME|QF_EXITGAME); - } - - if (QuitFlag&QF_LOADGAME) { - QuitFlag &= ~QF_LOADGAME; - LoadGame(LoadGameIndex.get(), VersionOverride ); - LoadGameIndex.release(); - //after loading a game, always check if the game needs to be upgraded - } - - if (QuitFlag&QF_ENTERGAME) { - QuitFlag &= ~QF_ENTERGAME; - if (game) { - EventFlag|=EF_EXPANSION; - timer->Init(); - - //rearrange party slots - game->ConsolidateParty(); - GameControl* gc = StartGameControl(); - //switch map to protagonist - Actor* actor = GetFirstSelectedPC(true); - if (actor) { - gc->ChangeMap(actor, true); - } - } else { - printMessage("Core", "No game to enter...\n", LIGHT_RED); - QuitFlag = QF_QUITGAME; - } - } - - if (QuitFlag&QF_CHANGESCRIPT) { - QuitFlag &= ~QF_CHANGESCRIPT; - guiscript->LoadScript( NextScript ); - guiscript->RunFunction( NextScript, "OnLoad" ); - } -} - -static bool GenerateAbilityTables() -{ - FreeAbilityTables(); - - //range is: 0 - maximumability - int tablesize = MaximumAbility+1; - strmod = (ieWordSigned *) malloc (tablesize * 4 * sizeof(ieWordSigned) ); - if (!strmod) - return false; - strmodex = (ieWordSigned *) malloc (101 * 4 * sizeof(ieWordSigned) ); - if (!strmodex) - return false; - intmod = (ieWordSigned *) malloc (tablesize * 5 * sizeof(ieWordSigned) ); - if (!intmod) - return false; - dexmod = (ieWordSigned *) malloc (tablesize * 3 * sizeof(ieWordSigned) ); - if (!dexmod) - return false; - conmod = (ieWordSigned *) malloc (tablesize * 5 * sizeof(ieWordSigned) ); - if (!conmod) - return false; - chrmod = (ieWordSigned *) malloc (tablesize * 1 * sizeof(ieWordSigned) ); - if (!chrmod) - return false; - lorebon = (ieWordSigned *) malloc (tablesize * 1 * sizeof(ieWordSigned) ); - if (!lorebon) - return false; - wisbon = (ieWordSigned *) malloc (tablesize * 1 * sizeof(ieWordSigned) ); - if (!wisbon) - return false; - return true; -} - -bool Interface::ReadAbilityTable(const ieResRef tablename, ieWordSigned *mem, int columns, int rows) -{ - AutoTable tab(tablename); - if (!tab) { - return false; - } - //this is a hack for rows not starting at 0 in some cases - int fix = 0; - const char * tmp = tab->GetRowName(0); - if (tmp && (tmp[0]!='0')) { - fix = atoi(tmp); - for (int i=0;iQueryField(0,j),NULL,0 ); - } - } - } - for (int j=0;jQueryField(i,j),NULL,0 ); - } - } - return true; -} - -bool Interface::ReadAbilityTables() -{ - bool ret = GenerateAbilityTables(); - if (!ret) - return ret; - ret = ReadAbilityTable("strmod", strmod, 4, MaximumAbility + 1); - if (!ret) - return ret; - ret = ReadAbilityTable("strmodex", strmodex, 4, 101); - //3rd ed doesn't have strmodex, but has a maximum of 40 - if (!ret && (MaximumAbility<=25) ) - return ret; - ret = ReadAbilityTable("intmod", intmod, 5, MaximumAbility + 1); - if (!ret) - return ret; - ret = ReadAbilityTable("hpconbon", conmod, 5, MaximumAbility + 1); - if (!ret) - return ret; - if (!HasFeature(GF_3ED_RULES)) { - //no lorebon in iwd2??? - ret = ReadAbilityTable("lorebon", lorebon, 1, MaximumAbility + 1); - if (!ret) - return ret; - //no dexmod in iwd2??? - ret = ReadAbilityTable("dexmod", dexmod, 3, MaximumAbility + 1); - if (!ret) - return ret; - } - //this table is a single row (not a single column) - ret = ReadAbilityTable("chrmodst", chrmod, MaximumAbility + 1, 1); - if (!ret) - return ret; - if (HasFeature(GF_WISDOM_BONUS)) { - ret = ReadAbilityTable("wisxpbon", wisbon, 1, MaximumAbility + 1); - if (!ret) - return ret; - } - return true; -} - -bool Interface::ReadGameTimeTable() -{ - AutoTable table("gametime"); - if (!table) { - return false; - } - - Time.round_sec = atoi(table->QueryField("ROUND_SECONDS", "DURATION")); - Time.turn_sec = atoi(table->QueryField("TURN_SECONDS", "DURATION")); - Time.round_size = Time.round_sec * AI_UPDATE_TIME; - Time.rounds_per_turn = Time.turn_sec / Time.round_sec; - - return true; -} - -bool Interface::ReadSpecialSpells() -{ - int i; - bool result = true; - - AutoTable table("splspec"); - if (table) { - SpecialSpellsCount = table->GetRowCount(); - SpecialSpells = (SpellDescType *) malloc( sizeof(SpellDescType) * SpecialSpellsCount); - for (i=0;iGetRowName(i),8 ); - //if there are more flags, compose this value into a bitfield - SpecialSpells[i].value = atoi(table->QueryField(i,0) ); - } - } else { - result = false; - } - - table.load("wildmag"); - if (table) { - SurgeSpell ss; - for (i = 0; (unsigned)i < table->GetRowCount(); i++) { - strncpy(ss.spell, table->QueryField(i, 0), 8); - ss.message = strtol(table->QueryField(i, 1), NULL, 0); - // comment ignored - SurgeSpells.push_back(ss); - } - } else { - result = false; - } - - return result; -} - -int Interface::GetSpecialSpell(ieResRef resref) -{ - for (int i=0;iGetStat(IE_STATE_ID) & STATE_SILENCED ) { - if (!(sp&SP_SILENCE)) { - return 1; - } - } - - return 0; -} - -bool Interface::ReadAuxItemTables() -{ - int idx; - bool flag = true; - - if (ItemExclTable) { - ItemExclTable->RemoveAll(NULL); - } else { - ItemExclTable = new Variables(); - ItemExclTable->SetType(GEM_VARIABLES_INT); - } - - AutoTable aa; - - //don't report error when the file doesn't exist - if (aa.load("itemexcl")) { - idx = aa->GetRowCount(); - while (idx--) { - ieResRef key; - - strnlwrcpy(key,aa->GetRowName(idx),8); - ieDword value = strtol(aa->QueryField(idx,0),NULL,0); - ItemExclTable->SetAt(key, value); - } - } - if (ItemDialTable) { - ItemDialTable->RemoveAll(NULL); - } else { - ItemDialTable = new Variables(); - ItemDialTable->SetType(GEM_VARIABLES_INT); - } - if (ItemDial2Table) { - ItemDial2Table->RemoveAll(NULL); - } else { - ItemDial2Table = new Variables(); - ItemDial2Table->SetType(GEM_VARIABLES_STRING); - } - - //don't report error when the file doesn't exist - if (aa.load("itemdial")) { - idx = aa->GetRowCount(); - while (idx--) { - ieResRef key, dlgres; - - strnlwrcpy(key,aa->GetRowName(idx),8); - ieDword value = strtol(aa->QueryField(idx,0),NULL,0); - ItemDialTable->SetAt(key, value); - strnlwrcpy(dlgres,aa->QueryField(idx,1),8); - ItemDial2Table->SetAtCopy(key, dlgres); - } - } - - if (ItemTooltipTable) { - ItemTooltipTable->RemoveAll(ReleaseItemTooltip); - } else { - ItemTooltipTable = new Variables(); - ItemTooltipTable->SetType(GEM_VARIABLES_POINTER); - } - - //don't report error when the file doesn't exist - if (aa.load("tooltip")) { - idx = aa->GetRowCount(); - while (idx--) { - ieResRef key; - int *tmppoi = (int *) malloc(sizeof(int)*3); - - strnlwrcpy(key,aa->GetRowName(idx),8); - for (int i=0;i<3;i++) { - tmppoi[i] = atoi(aa->QueryField(idx,i)); - } - ItemTooltipTable->SetAt(key, (void*)tmppoi); - } - } - return flag; -} - -//Static -const char *Interface::GetDeathVarFormat() -{ - return DeathVarFormat; -} - -int Interface::GetItemExcl(const ieResRef itemname) const -{ - ieDword value; - - if (ItemExclTable && ItemExclTable->Lookup(itemname, value)) { - return (int) value; - } - return 0; -} - -int Interface::GetItemTooltip(const ieResRef itemname, int header, int identified) -{ - int *value = NULL; - - if (ItemTooltipTable) { - void* lookup = NULL; - ItemTooltipTable->Lookup(itemname, lookup); - value = (int*)lookup; - } - if (value && (value[header]>=0)) { - return value[header]; - } - Item *item = gamedata->GetItem(itemname); - if (!item) { - return -1; - } - int ret = identified?item->ItemNameIdentified:item->ItemName; - gamedata->FreeItem(item, itemname, 0); - return ret; -} - -int Interface::GetItemDialStr(const ieResRef itemname) const -{ - ieDword value; - - if (ItemDialTable && ItemDialTable->Lookup(itemname, value)) { - return (int) value; - } - return -1; -} - -//second value is the item dialog resource returned by this method -int Interface::GetItemDialRes(const ieResRef itemname, ieResRef retval) const -{ - if (ItemDial2Table && ItemDial2Table->Lookup(itemname, retval, sizeof(ieResRef))) { - return 1; - } - return 0; -} - -bool Interface::ReadAreaAliasTable(const ieResRef tablename) -{ - if (AreaAliasTable) { - AreaAliasTable->RemoveAll(NULL); - } else { - AreaAliasTable = new Variables(); - AreaAliasTable->SetType(GEM_VARIABLES_INT); - } - - AutoTable aa(tablename); - if (!aa) { - //don't report error when the file doesn't exist - return true; - } - - int idx = aa->GetRowCount(); - while (idx--) { - ieResRef key; - - strnlwrcpy(key,aa->GetRowName(idx),8); - ieDword value = atoi(aa->QueryField(idx,0)); - AreaAliasTable->SetAt(key, value); - } - return true; -} - -//this isn't const -int Interface::GetAreaAlias(const ieResRef areaname) const -{ - ieDword value; - - if (AreaAliasTable && AreaAliasTable->Lookup(areaname, value)) { - return (int) value; - } - return -1; -} - -bool Interface::ReadMusicTable(const ieResRef tablename, int col) { - AutoTable tm(tablename); - if (!tm) - return false; - - for (unsigned int i = 0; i < tm->GetRowCount(); i++) { - musiclist.push_back(strdup(tm->QueryField(i, col))); - } - - return true; -} - -bool Interface::ReadDamageTypeTable() { - AutoTable tm("dmgtypes"); - if (!tm) - return false; - - DamageInfoStruct di; - for (ieDword i = 0; i < tm->GetRowCount(); i++) { - di.strref = displaymsg->GetStringReference(atoi(tm->QueryField(i, 0))); - di.resist_stat = TranslateStat(tm->QueryField(i, 1)); - di.value = strtol(tm->QueryField(i, 2), (char **) NULL, 16); - di.iwd_mod_type = atoi(tm->QueryField(i, 3)); - DamageInfoMap.insert(std::make_pair ((ieDword)di.value, di)); - } - - return true; -} - -bool Interface::ReadReputationModTable() { - AutoTable tm("reputati"); - if (!tm) - return false; - - reputationmod = (int **) calloc(21, sizeof(int *)); - int cols = tm->GetColumnCount(); - for (unsigned int i=0; i<20; i++) { - reputationmod[i] = (int *) calloc(cols, sizeof(int)); - for (int j=0; jQueryField(i, j)); - } - } - - return true; -} - -bool Interface::ReadModalStates() -{ - AutoTable table("modal"); - if (!table) - return false; - - ModalStatesStruct ms; - for (unsigned short i = 0; i < table->GetRowCount(); i++) { - strncpy(ms.spell, table->QueryField(i, 0), 8); - strncpy(ms.action, table->QueryField(i, 1), 16); - ms.entering_str = atoi(table->QueryField(i, 2)); - ms.leaving_str = atoi(table->QueryField(i, 3)); - ms.failed_str = atoi(table->QueryField(i, 4)); - ms.aoe_spell = atoi(table->QueryField(i, 5)); - ModalStates.push_back(ms); - } - - return true; -} - -//Not a constant anymore, we let the caller set the entry to zero -char *Interface::GetMusicPlaylist(int SongType) const { - if (SongType < 0 || (unsigned int)SongType >= musiclist.size()) - return NULL; - - return musiclist[SongType]; -} - -static const Color white = {0xff,0xff,0xff,0xff}; -static const Color black = {0x00,0x00,0x00,0xff}; -static const Region bg( 0, 0, 100, 30 ); - -/** this is the main loop */ -void Interface::Main() -{ - ieDword brightness = 10; - ieDword contrast = 5; - ieDword speed = 10; - - vars->Lookup("Full Screen", FullScreen); - video->CreateDisplay( Width, Height, Bpp, FullScreen); - video->SetDisplayTitle( GameName, GameType ); - vars->Lookup("Brightness Correction", brightness); - vars->Lookup("Gamma Correction", contrast); - vars->Lookup("Mouse Scroll Speed", speed); - video->SetGamma(brightness, contrast); - SetMouseScrollSpeed((int) speed); - if (vars->Lookup("Tooltips", TooltipDelay)) { - // the games store the slider position*10, not the actual delay - TooltipDelay *= TOOLTIP_DELAY_FACTOR/10; - } - - Font* fps = GetFont( ( unsigned int ) 0 ); - char fpsstring[40]={"???.??? fps"}; - unsigned long frame = 0, time, timebase; - timebase = GetTickCount(); - double frames = 0.0; - Palette* palette = CreatePalette( white, black ); - do { - //don't change script when quitting is pending - - while (QuitFlag) { - HandleFlags(); - } - //eventflags are processed only when there is a game - if (EventFlag && game) { - HandleEvents(); - } - HandleGUIBehaviour(); - - GameLoop(); - DrawWindows(true); - if (DrawFPS) { - frame++; - time = GetTickCount(); - if (time - timebase > 1000) { - frames = ( frame * 1000.0 / ( time - timebase ) ); - timebase = time; - frame = 0; - sprintf( fpsstring, "%.3f fps", frames ); - } - video->DrawRect( bg, black ); - fps->Print( bg, - ( unsigned char * ) fpsstring, palette, - IE_FONT_ALIGN_LEFT | IE_FONT_ALIGN_MIDDLE, true ); - } - if (TickHook) - TickHook->call(); - } while (video->SwapBuffers() == GEM_OK); - gamedata->FreePalette( palette ); -} - -int Interface::ReadResRefTable(const ieResRef tablename, ieResRef *&data) -{ - int count = 0; - - if (data) { - free(data); - data = NULL; - } - AutoTable tm(tablename); - if (!tm) { - printStatus( "ERROR", LIGHT_RED ); - print( "Cannot find %s.2da.\n",tablename ); - return 0; - } - count = tm->GetRowCount(); - data = (ieResRef *) calloc( count, sizeof(ieResRef) ); - for (int i = 0; i < count; i++) { - strnlwrcpy( data[i], tm->QueryField( i, 0 ), 8 ); - //* marks an empty resource - if (data[i][0]=='*') { - data[i][0]=0; - } - } - return count; -} - -int Interface::LoadSprites() -{ - ieDword i; - int size; - if (!IsAvailable( IE_2DA_CLASS_ID )) { - print( "No 2DA Importer Available.\nTermination in Progress...\n" ); - return GEM_ERROR; - } - - //loading cursors - AnimationFactory* anim; - anim = (AnimationFactory*) gamedata->GetFactoryResource("cursors", IE_BAM_CLASS_ID); - if (anim) - { - CursorCount = anim->GetCycleCount(); - Cursors = new Sprite2D * [CursorCount]; - for (int i = 0; i < CursorCount; i++) { - Cursors[i] = anim->GetFrame( 0, (ieByte) i ); - } - } - printMessage( "Core", "Loading Cursors...", WHITE ); - - // this is the last existing cursor type - if (CursorCountSetCursor( Cursors[0], Cursors[1] ); - printStatus( "OK", LIGHT_GREEN ); - - // Load fog-of-war bitmaps - anim = (AnimationFactory*) gamedata->GetFactoryResource("fogowar", IE_BAM_CLASS_ID); - printMessage( "Core", "Loading Fog-Of-War bitmaps...", WHITE ); - if (!anim || anim->GetCycleSize( 0 ) != 8) { - // unknown type of fog anim - printStatus( "ERROR", LIGHT_RED ); - return GEM_ERROR; - } - - FogSprites[0] = NULL; - FogSprites[1] = anim->GetFrame( 0, 0 ); - FogSprites[2] = anim->GetFrame( 1, 0 ); - FogSprites[3] = anim->GetFrame( 2, 0 ); - - FogSprites[4] = video->MirrorSpriteVertical( FogSprites[1], false ); - - FogSprites[5] = NULL; - - FogSprites[6] = video->MirrorSpriteVertical( FogSprites[3], false ); - - FogSprites[7] = NULL; - - FogSprites[8] = video->MirrorSpriteHorizontal( FogSprites[2], false ); - - FogSprites[9] = video->MirrorSpriteHorizontal( FogSprites[3], false ); - - FogSprites[10] = NULL; - FogSprites[11] = NULL; - - FogSprites[12] = video->MirrorSpriteHorizontal( FogSprites[6], false ); - - FogSprites[16] = anim->GetFrame( 3, 0 ); - FogSprites[17] = anim->GetFrame( 4, 0 ); - FogSprites[18] = anim->GetFrame( 5, 0 ); - FogSprites[19] = anim->GetFrame( 6, 0 ); - - FogSprites[20] = video->MirrorSpriteVertical( FogSprites[17], false ); - - FogSprites[21] = NULL; - - FogSprites[23] = NULL; - - FogSprites[24] = video->MirrorSpriteHorizontal( FogSprites[18], false ); - - FogSprites[25] = anim->GetFrame( 7, 0 ); - - { - Sprite2D *tmpsprite = video->MirrorSpriteVertical( FogSprites[25], false ); - FogSprites[22] = video->MirrorSpriteHorizontal( tmpsprite, false ); - video->FreeSprite( tmpsprite ); - } - - FogSprites[26] = NULL; - FogSprites[27] = NULL; - - { - Sprite2D *tmpsprite = video->MirrorSpriteVertical( FogSprites[19], false ); - FogSprites[28] = video->MirrorSpriteHorizontal( tmpsprite, false ); - video->FreeSprite( tmpsprite ); - } - - i = 0; - vars->Lookup("3D Acceleration", i); - if (i) { - for(i=0;iCreateAlpha( FogSprites[i] ); - video->FreeSprite ( FogSprites[i] ); - FogSprites[i] = alphasprite; - } - } - } - - printStatus( "OK", LIGHT_GREEN ); - - // Load ground circle bitmaps (PST only) - //block required due to msvc6.0 incompatibility - for (size = 0; size < MAX_CIRCLE_SIZE; size++) { - if (GroundCircleBam[size][0]) { - anim = (AnimationFactory*) gamedata->GetFactoryResource(GroundCircleBam[size], IE_BAM_CLASS_ID); - if (!anim || anim->GetCycleCount() != 6) { - // unknown type of circle anim - printMessage( "Core", "Loading Ground circle bitmaps...", WHITE ); - printStatus( "ERROR", LIGHT_RED ); - return GEM_ERROR; - } - - for (int i = 0; i < 6; i++) { - Sprite2D* sprite = anim->GetFrame( 0, (ieByte) i ); - if (GroundCircleScale[size]) { - GroundCircles[size][i] = video->SpriteScaleDown( sprite, GroundCircleScale[size] ); - video->FreeSprite( sprite ); - } else { - GroundCircles[size][i] = sprite; - } - } - } - } - - printMessage( "Core", "Loading Ground circle bitmaps...", WHITE ); - printStatus( "OK", LIGHT_GREEN ); - - printMessage( "Core", "Loading Fonts...\n", WHITE ); - AutoTable tab("fonts"); - if (!tab) { - printStatus( "ERROR", LIGHT_RED ); - print( "Cannot find fonts.2da.\nTermination in Progress...\n" ); - return GEM_ERROR; - } else { - PluginHolder bamint(IE_BAM_CLASS_ID); - if (!bamint) { - printStatus( "ERROR", LIGHT_RED ); - print( "No BAM Importer Available.\nTermination in Progress...\n" ); - return GEM_ERROR; - } - DataStream* str = NULL; - - int count = tab->GetRowCount(); - for (int i = 0; i < count; i++) { - const char* ResRef = tab->QueryField( i, 0 ); - int needpalette = atoi( tab->QueryField( i, 1 ) ); - int first_char = atoi( tab->QueryField( i, 2 ) ); - str = gamedata->GetResource( ResRef, IE_BAM_CLASS_ID ); - if (!bamint->Open(str)) { - continue; - } - Font* fnt = bamint->GetFont(); - if (!fnt) { - continue; - } - strnlwrcpy( fnt->ResRef, ResRef, 8 ); - if (needpalette) { - - Color fore = {0xff, 0xff, 0xff, 0}; - Color back = {0x00, 0x00, 0x00, 0}; - if (!strnicmp( TooltipFont, ResRef, 8) ) { - if (TooltipColor.a==0xff) { - fore = TooltipColor; - } else { - fore = back; - back = TooltipColor; - } - } - Palette* pal = CreatePalette( fore, back ); - pal->CreateShadedAlphaChannel(); - fnt->SetPalette(pal); - gamedata->FreePalette( pal ); - } - fnt->SetFirstChar( (ieByte) first_char ); - fonts.push_back( fnt ); - } - - if (fonts.size() == 0) { - printMessage( "Core", "No default font loaded! ", WHITE ); - printStatus( "ERROR", LIGHT_RED ); - return GEM_ERROR; - } - if (GetFont( ButtonFont ) == NULL) { - printMessage("Core", "ButtonFont not loaded: %s ", WHITE, - ButtonFont); - printStatus( "WARNING", YELLOW ); - } - if (GetFont( MovieFont ) == NULL) { - printMessage("Core", "MovieFont not loaded: %s ", WHITE, - MovieFont); - printStatus( "WARNING", YELLOW ); - } - if (GetFont( TooltipFont ) == NULL) { - printMessage("Core", "TooltipFont not loaded: %s ", WHITE, - TooltipFont); - printStatus( "WARNING", YELLOW ); - } - } - printMessage( "Core", "Fonts Loaded...", WHITE ); - printStatus( "OK", LIGHT_GREEN ); - - if (TooltipBackResRef[0]) { - anim = (AnimationFactory*) gamedata->GetFactoryResource(TooltipBackResRef, IE_BAM_CLASS_ID); - printMessage( "Core", "Initializing Tooltips...", WHITE ); - if (!anim) { - printStatus( "ERROR", LIGHT_RED ); - return GEM_ERROR; - } - TooltipBack = new Sprite2D * [3]; - for (int i = 0; i < 3; i++) { - TooltipBack[i] = anim->GetFrame( 0, (ieByte) i ); - TooltipBack[i]->XPos = 0; - TooltipBack[i]->YPos = 0; - } - printStatus( "OK", LIGHT_GREEN ); - } - - return GEM_OK; -} - -int Interface::Init() -{ - plugin_flags = new Variables(); - plugin_flags->SetType( GEM_VARIABLES_INT ); - - printMessage( "Core", "Initializing the Event Manager...", WHITE ); - evntmgr = new EventMgr(); - - printMessage( "Core", "Initializing Lists Dictionary...", WHITE ); - lists = new Variables(); - if (!lists) { - printStatus( "ERROR", LIGHT_RED ); - return GEM_ERROR; - } - lists->SetType( GEM_VARIABLES_POINTER ); - - printMessage( "Core", "Initializing Variables Dictionary...", WHITE ); - vars = new Variables(); - if (!vars) { - printStatus( "ERROR", LIGHT_RED ); - return GEM_ERROR; - } - vars->SetType( GEM_VARIABLES_INT ); - vars->ParseKey(true); - - vars->SetAt( "Volume Ambients", 100 ); - vars->SetAt( "Volume Movie", 100 ); - vars->SetAt( "Volume Music", 100 ); - vars->SetAt( "Volume SFX", 100 ); - vars->SetAt( "Volume Voices", 100 ); - printStatus( "OK", LIGHT_GREEN ); - - if (!LoadConfig()) { - printMessage( "Core", "Could not load config file ", YELLOW); - printStatus( "ERROR", LIGHT_RED ); - return GEM_ERROR; - } - printMessage( "Core", "Starting Plugin Manager...\n", WHITE ); - PluginMgr *plugin = PluginMgr::Get(); - LoadPlugins(PluginsPath); - if (plugin && plugin->GetPluginCount()) { - printMessage( "Core", "Plugin Loading Complete...", WHITE ); - printStatus( "OK", LIGHT_GREEN ); - } else { - printMessage( "Core", "Plugin Loading Failed, check path...", YELLOW); - printStatus( "ERROR", LIGHT_RED ); - return GEM_ERROR; - } - plugin->RunInitializers(); - - time_t t; - t = time( NULL ); - srand( ( unsigned int ) t ); -#ifdef _DEBUG - FileStreamPtrCount = 0; -#endif - printMessage( "Core", "GemRB Core Initialization...\n", WHITE ); - printStatus( "OK", LIGHT_GREEN ); - printMessage( "Core", "Initializing Video Driver...", WHITE ); - video = ( Video * ) PluginMgr::Get()->GetDriver(&Video::ID, VideoDriverName.c_str()); - if (!video) { - printStatus( "ERROR", LIGHT_RED ); - print( "No Video Driver Available.\nTermination in Progress...\n" ); - return GEM_ERROR; - } - if (video->Init() == GEM_ERROR) { - printStatus( "ERROR", LIGHT_RED ); - print( "Cannot Initialize Video Driver.\nTermination in Progress...\n" ); - return GEM_ERROR; - } - Color defcolor={255,255,255,200}; - SetInfoTextColor(defcolor); - printStatus( "OK", LIGHT_GREEN ); - - { - printMessage( "Core", "Initializing Search Path...", WHITE ); - if (!IsAvailable( PLUGIN_RESOURCE_DIRECTORY )) { - print( "no DirectoryImporter! " ); - printStatus( "ERROR", LIGHT_RED ); - return GEM_ERROR; - } - - char path[_MAX_PATH]; - - PathJoin( path, CachePath, NULL); - gamedata->AddSource(path, "Cache", PLUGIN_RESOURCE_DIRECTORY); - - PathJoin( path, GemRBOverridePath, "override", GameType, NULL); - gamedata->AddSource(path, "GemRB Override", PLUGIN_RESOURCE_CACHEDDIRECTORY); - - size_t i; - for (i = 0; i < ModPath.size(); ++i) - gamedata->AddSource(ModPath[i].c_str(), "Mod paths", PLUGIN_RESOURCE_CACHEDDIRECTORY); - - PathJoin( path, GemRBOverridePath, "override", "shared", NULL); - gamedata->AddSource(path, "shared GemRB Override", PLUGIN_RESOURCE_CACHEDDIRECTORY); - - PathJoin( path, GamePath, GameOverridePath, NULL); - gamedata->AddSource(path, "Override", PLUGIN_RESOURCE_CACHEDDIRECTORY); - - PathJoin( path, GamePath, GameSoundsPath, NULL); - gamedata->AddSource(path, "Sounds", PLUGIN_RESOURCE_CACHEDDIRECTORY); - - PathJoin( path, GamePath, GameScriptsPath, NULL); - gamedata->AddSource(path, "Scripts", PLUGIN_RESOURCE_CACHEDDIRECTORY); - - PathJoin( path, GamePath, GamePortraitsPath, NULL); - gamedata->AddSource(path, "Portraits", PLUGIN_RESOURCE_CACHEDDIRECTORY); - - PathJoin( path, GamePath, GameDataPath, NULL); - gamedata->AddSource(path, "Data", PLUGIN_RESOURCE_CACHEDDIRECTORY); - - //IWD2 movies are on the CD but not in the BIF - char *description = strdup("CD1/data"); - for (i = 0; i < MAX_CD; i++) { - for (size_t j=0;jAddSource(path, description, PLUGIN_RESOURCE_CACHEDDIRECTORY); - } - } - free(description); - - printStatus( "OK", LIGHT_GREEN ); - } - - { - printMessage( "Core", "Initializing KEY Importer...", WHITE ); - char ChitinPath[_MAX_PATH]; - PathJoin( ChitinPath, GamePath, "chitin.key", NULL ); - if (!gamedata->AddSource(ChitinPath, "chitin.key", PLUGIN_RESOURCE_KEY)) { - printStatus( "ERROR", LIGHT_RED ); - 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" ); - - { - // 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_CACHEDDIRECTORY, RM_REPLACE_SAME_SOURCE); - } - - printMessage( "Core", "Reading Game Options...\n", WHITE ); - if (!LoadGemRBINI()) { - print( "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; - - printMessage( "Core", "Creating Projectile Server...\n", WHITE ); - projserv = new ProjectileServer(); - if (!projserv->GetHighestProjectileNumber()) { - printStatus( "ERROR", LIGHT_RED ); - print( "No projectiles are available...\n" ); - } - - printMessage( "Core", "Checking for Dialogue Manager...", WHITE ); - if (!IsAvailable( IE_TLK_CLASS_ID )) { - printStatus( "ERROR", LIGHT_RED ); - print( "No TLK Importer Available.\nTermination in Progress...\n" ); - return GEM_ERROR; - } - printStatus( "OK", LIGHT_GREEN ); - strings = PluginHolder(IE_TLK_CLASS_ID); - printMessage( "Core", "Loading Dialog.tlk file...", WHITE ); - char strpath[_MAX_PATH]; - PathJoin( strpath, GamePath, dialogtlk, NULL ); - FileStream* fs = FileStream::OpenFile(strpath); - if (!fs) { - printStatus( "ERROR", LIGHT_RED ); - print( "Cannot find Dialog.tlk.\nTermination in Progress...\n" ); - return GEM_ERROR; - } - printStatus( "OK", LIGHT_GREEN ); - strings->Open(fs); - - { - printMessage( "Core", "Loading Palettes...\n", WHITE ); - ResourceHolder pal16im(Palette16); - if (pal16im) - pal16 = pal16im->GetImage(); - ResourceHolder pal32im(Palette32); - if (pal32im) - pal32 = pal32im->GetImage(); - ResourceHolder pal256im(Palette256); - if (pal256im) - pal256 = pal256im->GetImage(); - if (!pal16 || !pal32 || !pal256) { - printStatus( "ERROR", LIGHT_RED ); - return GEM_ERROR; - } - printMessage( "Core", "Palettes Loaded\n", WHITE ); - } - - if (!IsAvailable( IE_BAM_CLASS_ID )) { - printStatus( "ERROR", LIGHT_RED ); - print( "No BAM Importer Available.\nTermination in Progress...\n" ); - return GEM_ERROR; - } - - printMessage( "Core", "Initializing stock sounds...\n", WHITE ); - DSCount = ReadResRefTable ("defsound", DefSound); - if (DSCount == 0) { - printStatus( "ERROR", LIGHT_RED ); - print( "Cannot find defsound.2da.\nTermination in Progress...\n" ); - return GEM_ERROR; - } - - printStatus( "OK", LIGHT_GREEN ); - printMessage( "Core", "Broadcasting Event Manager...", WHITE ); - video->SetEventMgr( evntmgr ); - printStatus( "OK", LIGHT_GREEN ); - printMessage( "Core", "Initializing Window Manager...", WHITE ); - windowmgr = PluginHolder(IE_CHU_CLASS_ID); - if (windowmgr == NULL) { - printStatus( "ERROR", LIGHT_RED ); - return GEM_ERROR; - } - printStatus( "OK", LIGHT_GREEN ); - - int ret = LoadSprites(); - if (ret) return ret; - - printMessage( "Core", "Setting up the Console...", WHITE ); - QuitFlag = QF_CHANGESCRIPT; - console = new Console(); - console->XPos = 0; - console->YPos = (ieWord) (Height - 25); - console->Width = (ieWord) Width; - console->Height = 25; - if (fonts.size() > 0) { - console->SetFont( fonts[0] ); - } - - Sprite2D *tmpsprite = GetCursorSprite(); - if (!tmpsprite) { - printStatus( "ERROR", LIGHT_RED ); - return GEM_ERROR; - } - console->SetCursor (tmpsprite); - printStatus( "OK", LIGHT_GREEN ); - - printMessage( "Core", "Starting up the Sound Driver...", WHITE ); - AudioDriver = ( Audio * ) PluginMgr::Get()->GetDriver(&Audio::ID, AudioDriverName.c_str()); - if (AudioDriver == NULL) { - printStatus( "ERROR", LIGHT_RED ); - return GEM_ERROR; - } - if (!AudioDriver->Init()) { - printStatus( "ERROR", LIGHT_RED ); - return GEM_ERROR; - } - printStatus( "OK", LIGHT_GREEN ); - - printMessage( "Core", "Allocating SaveGameIterator...", WHITE ); - sgiterator = new SaveGameIterator(); - if (sgiterator == NULL) { - printStatus( "ERROR", LIGHT_RED ); - return GEM_ERROR; - } - printStatus( "OK", LIGHT_GREEN ); - - //no need of strdup, variables do copy the key! - vars->SetAt( "SkipIntroVideos", (unsigned long)SkipIntroVideos ); - vars->SetAt( "GUIEnhancements", (unsigned long)GUIEnhancements ); - vars->SetAt( "TouchScrollAreas", (unsigned long)TouchScrollAreas ); - - printMessage( "Core", "Initializing Token Dictionary...", WHITE ); - tokens = new Variables(); - if (!tokens) { - printStatus( "ERROR", LIGHT_RED ); - return GEM_ERROR; - } - tokens->SetType( GEM_VARIABLES_STRING ); - printStatus( "OK", LIGHT_GREEN ); - - printMessage( "Core", "Initializing Music Manager...", WHITE ); - music = PluginHolder(IE_MUS_CLASS_ID); - if (!music) { - printStatus( "ERROR", LIGHT_RED ); - return GEM_ERROR; - } - printStatus( "OK", LIGHT_GREEN ); - - printMessage("Core", "Loading music list...\n", WHITE ); - if (HasFeature( GF_HAS_SONGLIST )) { - ret = ReadMusicTable("songlist", 1); - } else { - /*since bg1 and pst has no .2da for songlist, - we must supply one in the gemrb/override folder. - It should be: music.2da, first column is a .mus filename*/ - ret = ReadMusicTable("music", 0); - } - if (ret) { - printStatus( "OK", LIGHT_GREEN ); - } else { - printStatus( "NOT FOUND", YELLOW ); - } - - if (HasFeature( GF_RESDATA_INI )) { - printMessage( "Core", "Loading resource data File...", WHITE ); - INIresdata = PluginHolder(IE_INI_CLASS_ID); - DataStream* ds = gamedata->GetResource("resdata", IE_INI_CLASS_ID); - if (!INIresdata->Open(ds)) { - printStatus( "ERROR", LIGHT_RED ); - } else { - printStatus( "OK", LIGHT_GREEN ); - } - } - - if (HasFeature( GF_HAS_PARTY_INI )) { - printMessage( "Core", "Loading precreated teams setup...\n", WHITE ); - INIparty = PluginHolder(IE_INI_CLASS_ID); - char tINIparty[_MAX_PATH]; - PathJoin( tINIparty, GamePath, "Party.ini", NULL ); - FileStream* fs = FileStream::OpenFile( tINIparty ); - if (!INIparty->Open(fs)) { - printStatus( "ERROR", LIGHT_RED ); - } else { - printStatus( "OK", LIGHT_GREEN ); - } - } - - if (HasFeature(GF_IWD2_DEATHVARFORMAT)) { - memcpy(DeathVarFormat, IWD2DeathVarFormat, sizeof(ieVariable)); - } - - if (HasFeature( GF_HAS_BEASTS_INI )) { - printMessage( "Core", "Loading beasts definition File...\n", WHITE ); - INIbeasts = PluginHolder(IE_INI_CLASS_ID); - char tINIbeasts[_MAX_PATH]; - PathJoin( tINIbeasts, GamePath, "beast.ini", NULL ); - // FIXME: crashes if file does not open - FileStream* fs = FileStream::OpenFile( tINIbeasts ); - if (!INIbeasts->Open(fs)) { - printStatus( "ERROR", LIGHT_RED ); - } else { - printStatus( "OK", LIGHT_GREEN ); - } - - printMessage( "Core", "Loading quests definition File...\n", WHITE ); - INIquests = PluginHolder(IE_INI_CLASS_ID); - char tINIquests[_MAX_PATH]; - PathJoin( tINIquests, GamePath, "quests.ini", NULL ); - // FIXME: crashes if file does not open - FileStream* fs2 = FileStream::OpenFile( tINIquests ); - if (!INIquests->Open(fs2)) { - printStatus( "ERROR", LIGHT_RED ); - } else { - printStatus( "OK", LIGHT_GREEN ); - } - } - game = NULL; - calendar = NULL; - keymap = NULL; - - timer = new GlobalTimer(); - printMessage( "Core", "Bringing up the Global Timer...", WHITE ); - if (!timer) { - printStatus( "ERROR", LIGHT_RED ); - return GEM_ERROR; - } - printStatus( "OK", LIGHT_GREEN ); - - ret = Init_EffectQueue(); - printMessage( "Core", "Initializing effects...", WHITE ); - if (!ret) { - printStatus( "ERROR", LIGHT_RED ); - return GEM_ERROR; - } - printStatus( "OK", LIGHT_GREEN ); - - ret = InitItemTypes(); - printMessage( "Core", "Initializing Inventory Management...", WHITE ); - if (!ret) { - printStatus( "ERROR", LIGHT_RED ); - return GEM_ERROR; - } - printStatus( "OK", LIGHT_GREEN ); - - displaymsg = new DisplayMessage(); - printMessage( "Core", "Initializing string constants...", WHITE ); - if (!displaymsg) { - printStatus( "ERROR", LIGHT_RED ); - return GEM_ERROR; - } - printStatus( "OK", LIGHT_GREEN ); - - ret = ReadRandomItems(); - printMessage( "Core", "Initializing random treasure...", WHITE ); - if (ret) { - printStatus( "OK", LIGHT_GREEN ); - } - else { - printStatus( "ERROR", LIGHT_RED ); - } - - ret = ReadAbilityTables(); - printMessage( "Core", "Initializing ability tables...", WHITE ); - if (!ret) { - printStatus( "ERROR", LIGHT_RED ); - return GEM_ERROR; - } - printStatus( "OK", LIGHT_GREEN ); - - ret = ReadReputationModTable(); - printMessage( "Core", "Reading reputation mod table...", WHITE); - if (ret) { - printStatus( "OK", LIGHT_GREEN ); - } else { - printStatus( "NOT FOUND", LIGHT_RED ); - } - - if ( gamedata->Exists("WMAPLAY", IE_2DA_CLASS_ID) ) { - ret = ReadAreaAliasTable( "WMAPLAY" ); - printMessage( "Core", "Initializing area aliases...", WHITE ); - if (ret) { - printStatus( "OK", LIGHT_GREEN ); - } - else { - printStatus( "NOT FOUND", YELLOW ); - } - } - - ret = ReadGameTimeTable(); - printMessage( "Core", "Reading game time table...", WHITE); - if (!ret) { - printStatus( "ERROR", LIGHT_RED ); - return GEM_ERROR; - } - printStatus( "OK", LIGHT_GREEN ); - - ret = ReadSpecialSpells(); - printMessage( "Core", "Reading special spells table...", WHITE); - if (ret) { - printStatus( "OK", LIGHT_GREEN ); - } else { - printStatus( "NOT FOUND", YELLOW ); - } - - ret = ReadAuxItemTables(); - printMessage( "Core", "Reading item tables...", WHITE); - if (!ret) { - printStatus( "ERROR", LIGHT_RED ); - return GEM_ERROR; - } - printStatus( "OK", LIGHT_GREEN ); - - ret = ReadDamageTypeTable(); - printMessage( "Core", "Reading damage type table...", WHITE); - if (!ret) { - printStatus( "ERROR", LIGHT_RED ); - } else { - printStatus( "OK", LIGHT_GREEN ); - } - - ret = ReadModalStates(); - printMessage( "Core", "Reading modal states table...", WHITE); - if (!ret) { - printStatus( "ERROR", LIGHT_RED ); - return GEM_ERROR; - } else { - printStatus( "OK", LIGHT_GREEN ); - } - - printMessage( "Core", "Reading game script tables...", WHITE); - InitializeIEScript(); - printStatus( "OK", LIGHT_GREEN ); - - printMessage( "Core", "Initializing keymap tables...", WHITE); - keymap = new KeyMap(); - ret = keymap->InitializeKeyMap("keymap.ini", "keymap"); - if (!ret) { - printStatus( "ERROR", LIGHT_RED ); - } else { - printStatus( "OK", LIGHT_GREEN ); - } - printMessage( "Core", "Core Initialization Complete!\n", WHITE ); - - return GEM_OK; -} - -bool Interface::IsAvailable(SClass_ID filetype) const -{ - return PluginMgr::Get()->IsAvailable( filetype ); -} - -WorldMap *Interface::GetWorldMap(const char *map) -{ - int index = worldmap->FindAndSetCurrentMap(map?map:game->CurrentArea); - return worldmap->GetWorldMap(index); -} - -ProjectileServer* Interface::GetProjectileServer() const -{ - return projserv; -} - -Video* Interface::GetVideoDriver() const -{ - return video.get(); -} - -Audio* Interface::GetAudioDrv(void) const { - return AudioDriver.get(); -} - -const char* Interface::TypeExt(SClass_ID type) const -{ - switch (type) { - case IE_2DA_CLASS_ID: - return "2da"; - - case IE_ACM_CLASS_ID: - return "acm"; - - case IE_ARE_CLASS_ID: - return "are"; - - case IE_BAM_CLASS_ID: - return "bam"; - - case IE_BCS_CLASS_ID: - return "bcs"; - - case IE_BS_CLASS_ID: - return "bs"; - - case IE_BIF_CLASS_ID: - return "bif"; - - case IE_BIO_CLASS_ID: - if (HasFeature(GF_BIOGRAPHY_RES)) { - return "res"; - } - return "bio"; - - case IE_BMP_CLASS_ID: - return "bmp"; - - case IE_PNG_CLASS_ID: - return "png"; - - case IE_CHR_CLASS_ID: - return "chr"; - - case IE_CHU_CLASS_ID: - return "chu"; - - case IE_CRE_CLASS_ID: - return "cre"; - - case IE_DLG_CLASS_ID: - return "dlg"; - - case IE_EFF_CLASS_ID: - return "eff"; - - case IE_GAM_CLASS_ID: - return "gam"; - - case IE_IDS_CLASS_ID: - return "ids"; - - case IE_INI_CLASS_ID: - return "ini"; - - case IE_ITM_CLASS_ID: - return "itm"; - - case IE_MOS_CLASS_ID: - return "mos"; - - case IE_MUS_CLASS_ID: - return "mus"; - - case IE_MVE_CLASS_ID: - return "mve"; - - case IE_OGG_CLASS_ID: - return "ogg"; - - case IE_PLT_CLASS_ID: - return "plt"; - - case IE_PRO_CLASS_ID: - return "pro"; - - case IE_SAV_CLASS_ID: - return "sav"; - - case IE_SPL_CLASS_ID: - return "spl"; - - case IE_SRC_CLASS_ID: - return "src"; - - case IE_STO_CLASS_ID: - return "sto"; - - case IE_TIS_CLASS_ID: - return "tis"; - - case IE_TLK_CLASS_ID: - return "tlk"; - - case IE_TOH_CLASS_ID: - return "toh"; - - case IE_TOT_CLASS_ID: - return "tot"; - - case IE_VAR_CLASS_ID: - return "var"; - - case IE_VVC_CLASS_ID: - return "vvc"; - - case IE_WAV_CLASS_ID: - return "wav"; - - case IE_WED_CLASS_ID: - return "wed"; - - case IE_WFX_CLASS_ID: - return "wfx"; - - case IE_WMP_CLASS_ID: - return "wmp"; - } - return NULL; -} - -void Interface::FreeString(char *&str) const -{ - if (str) { - strings->FreeString(str); - } - str = NULL; -} - -ieStrRef Interface::UpdateString(ieStrRef strref, const char *text) const -{ - return strings->UpdateString( strref, text ); -} - -char* Interface::GetString(ieStrRef strref, ieDword options) const -{ - ieDword flags = 0; - - if (!(options & IE_STR_STRREFOFF)) { - vars->Lookup( "Strref On", flags ); - } - return strings->GetString( strref, flags | options ); -} - -void Interface::SetFeature(int flag, int position) -{ - if (flag) { - GameFeatures[position>>5] |= 1<<(position&31); - } else { - GameFeatures[position>>5] &= ~(1<<(position&31) ); - } -} - -ieDword Interface::HasFeature(int position) const -{ - return GameFeatures[position>>5] & (1<<(position&31)); -} - -/** Search directories and load a config file */ -bool Interface::LoadConfig(void) -{ -#ifndef WIN32 - char path[_MAX_PATH]; - char name[_MAX_PATH]; - - // Find directory where user stores GemRB configurations (~/.gemrb). - // FIXME: Create it if it does not exist - // Use current dir if $HOME is not defined (or bomb out??) - - char* s = getenv( "HOME" ); - if (s) { - strcpy( UserDir, s ); - strcat( UserDir, "/."PACKAGE"/" ); - } else { - strcpy( UserDir, "./" ); - } - - // Find basename of this program. It does the same as basename (3), - // but that's probably missing on some archs - s = strrchr( argv[0], PathDelimiter ); - if (s) { - s++; - } else { - s = argv[0]; - } - - strcpy( name, s ); - //if (!name[0]) // FIXME: could this happen? - // strcpy (name, PACKAGE); // ugly hack - - // If we were called as $0 -c , load config from filename - if (argc > 2 && ! strcmp("-c", argv[1])) { - if (LoadConfig( argv[2] )) { - return true; - } else { - // Explicitly specified cfg file HAS to be present - return false; - } - } - - // FIXME: temporary hack, to be deleted?? - if (LoadConfig( "GemRB.cfg" )) { - return true; - } - - PathJoinExt( path, UserDir, name, "cfg" ); - - if (LoadConfig( path )) { - return true; - } - -#ifdef SYSCONFDIR - PathJoinExt( path, SYSCONFDIR, name, "cfg" ); - - if (LoadConfig( path )) { - return true; - } -#endif - - // Don't try with default binary name if we have tried it already - if (!strcmp( name, PACKAGE )) { - return false; - } - - PathJoinExt( path, UserDir, PACKAGE, "cfg" ); - - if (LoadConfig( path )) { - return true; - } - -#ifdef SYSCONFDIR - PathJoinExt( path, SYSCONFDIR, PACKAGE, "cfg" ); - - if (LoadConfig( path )) { - return true; - } -#endif - - return false; -#else // WIN32 - // If we were called as $0 -c , load config from filename - if (argc > 2 && ! strcmp("-c", argv[1])) { - return LoadConfig( argv[2] ); - // Explicitly specified cfg file HAS to be present - } - strcpy( UserDir, ".\\" ); - return LoadConfig( "GemRB.cfg" ); -#endif// WIN32 -} - -bool Interface::LoadConfig(const char* filename) -{ - size_t i; - - printMessage("Config","Trying to open ", WHITE); - textcolor(LIGHT_WHITE); - print("%s ", filename); - FileStream* config = FileStream::OpenFile(filename); - if (config == NULL) { - printStatus("NOT FOUND", YELLOW); - return false; - } - - //once GemRB own format is working well, this might be set to 0 - SaveAsOriginal = 1; - - int lineno = 0; - while (config->Remains()) { - char line[1024]; - char *name, *nameend, *value, *valueend; - - if (config->ReadLine(line, _MAX_PATH) == -1) { - break; - } - lineno++; - - // skip leading blanks from name - name = line; - name += strspn( line, " \t\r\n" ); - - // ignore empty or comment lines - if (*name == '\0' || *name == '#') { - continue; - } - - value = strchr( name, '=' ); - if (!value || value == name) { - print( "Invalid line %d\n", lineno ); - continue; - } - - // 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) { -#define CONFIG_INT(str, var) \ - } else if (stricmp(name, str) == 0) { \ - var ( atoi(value) ) - CONFIG_INT("Bpp", Bpp = ); - CONFIG_INT("CaseSensitive", CaseSensitive = ); - CONFIG_INT("DoubleClickDelay", evntmgr->SetDCDelay); - CONFIG_INT("DrawFPS", DrawFPS = ); - CONFIG_INT("EnableCheatKeys", EnableCheatKeys); - CONFIG_INT("EndianSwitch", DataStream::SetEndianSwitch); - CONFIG_INT("FogOfWar", FogOfWar = ); - CONFIG_INT("FullScreen", FullScreen = ); - CONFIG_INT("GUIEnhancements", GUIEnhancements = ); - CONFIG_INT("GameOnCD", GameOnCD = ); - CONFIG_INT("Height", Height = ); - CONFIG_INT("KeepCache", KeepCache = ); - CONFIG_INT("MultipleQuickSaves", GameControl::MultipleQuickSaves); - CONFIG_INT("RepeatKeyDelay", evntmgr->SetRKDelay); - CONFIG_INT("SaveAsOriginal", SaveAsOriginal = ); - CONFIG_INT("ScriptDebugMode", SetScriptDebugMode); - CONFIG_INT("SkipIntroVideos", SkipIntroVideos = ); - CONFIG_INT("TooltipDelay", TooltipDelay = ); - CONFIG_INT("Width", Width = ); - CONFIG_INT("IgnoreOriginalINI", IgnoreOriginalINI = ); - CONFIG_INT("TouchScrollAreas", TouchScrollAreas = ); -#undef CONFIG_INT -#define CONFIG_STRING(str, var) \ - } else if (stricmp(name, str) == 0) { \ - strncpy(var, value, sizeof(var)) - CONFIG_STRING("GameCharactersPath", GameCharactersPath); - CONFIG_STRING("GameDataPath", GameDataPath); - CONFIG_STRING("GameName", GameName); - CONFIG_STRING("GameOverridePath", GameOverridePath); - CONFIG_STRING("GamePortraitsPath", GamePortraitsPath); - CONFIG_STRING("GameScriptsPath", GameScriptsPath); - CONFIG_STRING("GameSoundsPath", GameSoundsPath); - CONFIG_STRING("GameType", GameType); -#undef CONFIG_STRING -#define CONFIG_STRING(str, var) \ - } else if (stricmp(name, str) == 0) { \ - var = value - CONFIG_STRING("AudioDriver", AudioDriverName); - CONFIG_STRING("VideoDriver", VideoDriverName); -#undef CONFIG_STRING -#define CONFIG_PATH(str, var) \ - } else if (stricmp(name, str) == 0) { \ - strncpy(var, value, sizeof(var)); - CONFIG_PATH("CachePath", CachePath); - CONFIG_PATH("GUIScriptsPath", GUIScriptsPath); - CONFIG_PATH("GamePath", GamePath); - CONFIG_PATH("GemRBOverridePath", GemRBOverridePath); - CONFIG_PATH("GemRBPath", GemRBPath); - CONFIG_PATH("PluginsPath", PluginsPath); - CONFIG_PATH("SavePath", SavePath); -#undef CONFIG_PATH - } else if (stricmp( name, "ModPath" ) == 0) { - for (char *path = strtok(value,SPathListSeparator); - path; - path = strtok(NULL,SPathListSeparator)) { - ModPath.push_back(path); - } - } else if (stricmp( name, "SkipPlugin" ) == 0) { - plugin_flags->SetAt( value, PLF_SKIP ); - } else if (stricmp( name, "DelayPlugin" ) == 0) { - plugin_flags->SetAt( value, PLF_DELAY ); - } else { - for(i=0;iGetResource( "gemrb", IE_INI_CLASS_ID ); - if (! inifile) { - printStatus( "ERROR", LIGHT_RED ); - return false; - } - - printMessage("Core", "Loading game type-specific GemRB setup...\n%s", WHITE, - inifile->originalfile); - - if (!IsAvailable( IE_INI_CLASS_ID )) { - printStatus( "ERROR", LIGHT_RED ); - print( "[Core]: No INI Importer Available.\n" ); - return false; - } - PluginHolder ini(IE_INI_CLASS_ID); - ini->Open(inifile); - - printStatus( "OK", LIGHT_GREEN ); - - const char *s; - - // Resrefs are already initialized in Interface::Interface() - s = ini->GetKeyAsString( "resources", "CursorBAM", NULL ); - if (s) - strnlwrcpy( CursorBam, s, 8 ); //console cursor - - s = ini->GetKeyAsString( "resources", "ScrollCursorBAM", NULL ); - if (s) - strnlwrcpy( ScrollCursorBam, s, 8 ); - - s = ini->GetKeyAsString( "resources", "ButtonFont", NULL ); - if (s) - strnlwrcpy( ButtonFont, s, 8 ); - - s = ini->GetKeyAsString( "resources", "TooltipFont", NULL ); - if (s) - strnlwrcpy( TooltipFont, s, 8 ); - - s = ini->GetKeyAsString( "resources", "MovieFont", NULL ); - if (s) - strnlwrcpy( MovieFont, s, 8 ); - - s = ini->GetKeyAsString( "resources", "TooltipBack", NULL ); - if (s) - strnlwrcpy( TooltipBackResRef, s, 8 ); - - s = ini->GetKeyAsString( "resources", "TooltipColor", NULL ); - if (s) { - if (s[0] == '#') { - unsigned long c = strtoul (s + 1, NULL, 16); - // FIXME: check errno - TooltipColor.r = (unsigned char) (c >> 24); - TooltipColor.g = (unsigned char) (c >> 16); - TooltipColor.b = (unsigned char) (c >> 8); - TooltipColor.a = (unsigned char) (c); - } - } - - //which stat determines the fist weapon (defaults to class) - Actor::SetFistStat(ini->GetKeyAsInt( "resources", "FistStat", IE_CLASS)); - - TooltipMargin = ini->GetKeyAsInt( "resources", "TooltipMargin", TooltipMargin ); - - // The format of GroundCircle can be: - // GroundCircleBAM1 = wmpickl/3 - // to denote that the bitmap should be scaled down 3x - for (int size = 0; size < MAX_CIRCLE_SIZE; size++) { - char name[30]; - sprintf( name, "GroundCircleBAM%d", size+1 ); - s = ini->GetKeyAsString( "resources", name, NULL ); - if (s) { - const char *pos = strchr( s, '/' ); - if (pos) { - GroundCircleScale[size] = atoi( pos+1 ); - strncpy( GroundCircleBam[size], s, pos - s ); - GroundCircleBam[size][pos - s] = '\0'; - } else { - strcpy( GroundCircleBam[size], s ); - } - } - } - - s = ini->GetKeyAsString( "resources", "NoteString", NULL ); - TextArea::SetNoteString(s); - - s = ini->GetKeyAsString( "resources", "INIConfig", NULL ); - if (s) - strcpy( INIConfig, s ); - - s = ini->GetKeyAsString( "resources", "Palette16", NULL ); - if (s) - strcpy( Palette16, s ); - - s = ini->GetKeyAsString( "resources", "Palette32", NULL ); - if (s) - strcpy( Palette32, s ); - - s = ini->GetKeyAsString( "resources", "Palette256", NULL ); - if (s) - strcpy( Palette256, s ); - - unsigned int i = (unsigned int) ini->GetKeyAsInt ("charset", "CharCount", 0); - if (i>99) i=99; - while(i--) { - char key[10]; - snprintf(key,9,"Letter%d", i+1); - s = ini->GetKeyAsString( "charset", key, NULL ); - if (s) { - const char *s2 = strchr(s,','); - if (s2) { - unsigned char upper = atoi(s); - unsigned char lower = atoi(s2+1); - pl_uppercase[lower] = upper; - pl_lowercase[upper] = lower; - } - } - } - - MaximumAbility = ini->GetKeyAsInt ("resources", "MaximumAbility", 25 ); - - RedrawTile = ini->GetKeyAsInt( "resources", "RedrawTile", 0 )!=0; - - for (i=0;iGetKeyAsInt( "resources", game_flags[i], 0 ), i ); - //printMessage("Option", "", GREEN); - //print("%s = %s\n", game_flags[i], HasFeature(i)?"yes":"no"); - } - - ForceStereo = ini->GetKeyAsInt( "resources", "ForceStereo", 0 ); - - return true; -} - -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; - pal->col[0].a = 0; - for (int i = 1; i < 256; i++) { - pal->col[i].r = back.r + - ( unsigned char ) ( ( ( color.r - back.r ) * ( i ) ) / 255 ); - pal->col[i].g = back.g + - ( unsigned char ) ( ( ( color.g - back.g ) * ( i ) ) / 255 ); - pal->col[i].b = back.b + - ( unsigned char ) ( ( ( color.b - back.b ) * ( i ) ) / 255 ); - pal->col[i].a = back.a + - ( unsigned char ) ( ( ( color.a - back.a ) * ( i ) ) / 255 ); - } - return pal; -} - -/** No descriptions */ -Color* Interface::GetPalette(unsigned index, int colors, Color *pal) const -{ - Image *img; - if (colors == 32) { - img = pal32; - } else if (colors <= 32) { - img = pal16; - } else if (colors == 256) { - img = pal256; - } else { - return pal; - } - if (index >= img->GetHeight()) { - index = 0; - } - for (int i = 0; i < colors; i++) { - pal[i] = img->GetPixel(i, index); - } - return pal; -} -/** Returns a preloaded Font */ -Font* Interface::GetFont(const char *ResRef) const -{ - for (unsigned int i = 0; i < fonts.size(); i++) { - if (strnicmp( fonts[i]->ResRef, ResRef, 8 ) == 0) { - return fonts[i]; - } - } - return NULL; -} - -Font* Interface::GetFont(unsigned int index) const -{ - if (index >= fonts.size()) { - return NULL; - } - return fonts[index]; -} - -Font* Interface::GetButtonFont() const -{ - return GetFont( ButtonFont ); -} - -/** Returns the Event Manager */ -EventMgr* Interface::GetEventMgr() const -{ - return evntmgr; -} - -/** Returns the Window Manager */ -WindowMgr* Interface::GetWindowMgr() const -{ - return windowmgr.get(); -} - -/** Get GUI Script Manager */ -ScriptEngine* Interface::GetGUIScriptEngine() const -{ - return guiscript.get(); -} - -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) -{ - //maximum number of monsters summoned - int cnt=10; - Actor * ab = NULL; - - //TODO: - //decrease the number of summoned creatures with the number of already summoned creatures here - //the summoned creatures have a special IE_SPECIFIC - - while(cnt--) { - ab = gamedata->GetCreature(resource); - if (!ab) { - return NULL; - } - - if (Owner && Owner->Type==ST_ACTOR) { - ab->LastSummoner = Owner->GetGlobalID(); - } - //Always use Base stats for the recently summoned creature - - int enemyally; - - if (eamod==EAM_SOURCEALLY || eamod==EAM_SOURCEENEMY) { - if (Owner && Owner->Type==ST_ACTOR) { - enemyally = ((Actor *) Owner)->GetStat(IE_EA)>EA_GOODCUTOFF; - } else { - enemyally = true; - } - } else { - if (target) { - enemyally = target->GetBase(IE_EA)>EA_GOODCUTOFF; - } else { - enemyally = true; - } - } - - switch (eamod) { - case EAM_SOURCEALLY: - case EAM_ALLY: - if (enemyally) { - ab->SetBase(IE_EA, EA_ENEMY); //is this the summoned EA? - } else { - ab->SetBase(IE_EA, EA_CONTROLLED); //is this the summoned EA? - } - break; - case EAM_SOURCEENEMY: - case EAM_ENEMY: - if (enemyally) { - ab->SetBase(IE_EA, EA_CONTROLLED); //is this the summoned EA? - } else { - ab->SetBase(IE_EA, EA_ENEMY); //is this the summoned EA? - } - break; - case EAM_NEUTRAL: - ab->SetBase(IE_EA, EA_NEUTRAL); - break; - default: - break; - } - - // mark the summon, but only if they don't have a special sex already - if (sexmod && ab->BaseStats[IE_SEX] < SEX_EXTRA) { - ab->SetBase(IE_SEX, SEX_SUMMON); - } - - Map *map; - if (target) { - map = target->GetCurrentArea(); - } else { - map = Owner->GetCurrentArea(); - } - map->AddActor(ab); - ab->SetPosition(position, true, 0); - ab->RefreshEffects(NULL); - - if (vvcres[0]) { - ScriptedAnimation* vvc = gamedata->GetScriptedAnimation(vvcres, false); - if (vvc) { - //This is the final position of the summoned creature - //not the original target point - vvc->XPos=ab->Pos.x; - vvc->YPos=ab->Pos.y; - //force vvc to play only once - vvc->PlayOnce(); - map->AddVVCell( vvc ); - - //set up the summon disable effect - Effect *newfx = EffectQueue::CreateEffect(fx_summon_disable_ref, 0, 1, FX_DURATION_ABSOLUTE); - if (newfx) { - newfx->Duration = vvc->GetSequenceDuration(AI_UPDATE_TIME)*9/10 + core->GetGame()->GameTime; - ApplyEffect(newfx, ab, ab); - } - } - } - - //remove the xp value of friendly summons - if (ab->BaseStats[IE_EA]SetBase(IE_XPVALUE, 0); - } - if (fx) { - ApplyEffect(fx, ab, Owner); - } - - //this check should happen after the fact - level -= ab->GetBase(IE_XP); - if(level<0 || ab->GetBase(IE_XP) == 0) { - break; - } - - } - return ab; -} - -void Interface::RedrawControls(const char *varname, unsigned int value) -{ - for (unsigned int i = 0; i < windows.size(); i++) { - Window *win = windows[i]; - if (win != NULL && win->Visible!=WINDOW_INVALID) { - win->RedrawControls(varname, value); - } - } -} - -void Interface::RedrawAll() -{ - for (unsigned int i = 0; i < windows.size(); i++) { - Window *win = windows[i]; - if (win != NULL && win->Visible!=WINDOW_INVALID) { - win->Invalidate(); - } - } -} - -/** Loads a WindowPack (CHUI file) in the Window Manager */ -bool Interface::LoadWindowPack(const char* name) -{ - DataStream* stream = gamedata->GetResource( name, IE_CHU_CLASS_ID ); - if (stream == NULL) { - printMessage("Interface", "Error: Cannot find %s.chu\n", LIGHT_RED, name ); - return false; - } - if (!GetWindowMgr()->Open(stream)) { - printMessage("Interface", "Error: Cannot Load %s.chu\n", LIGHT_RED, name ); - return false; - } - - strncpy( WindowPack, name, sizeof( WindowPack ) ); - WindowPack[sizeof( WindowPack ) - 1] = '\0'; - - return true; -} - -/** Loads a Window in the Window Manager */ -int Interface::LoadWindow(unsigned short WindowID) -{ - unsigned int i; - - for (i = 0; i < windows.size(); i++) { - Window *win = windows[i]; - if (win == NULL) - continue; - if (win->Visible==WINDOW_INVALID) { - continue; - } - if (win->WindowID == WindowID && - !strnicmp( WindowPack, win->WindowPack, sizeof(WindowPack) )) { - SetOnTop( i ); - win->Invalidate(); - return i; - } - } - Window* win = windowmgr->GetWindow( WindowID ); - if (win == NULL) { - return -1; - } - memcpy( win->WindowPack, WindowPack, sizeof(WindowPack) ); - - int slot = -1; - for (i = 0; i < windows.size(); i++) { - if (windows[i] == NULL) { - slot = i; - break; - } - } - if (slot == -1) { - windows.push_back( win ); - slot = ( int ) windows.size() - 1; - } else { - windows[slot] = win; - } - win->Invalidate(); - return slot; -} -// FIXME: it's a clone of LoadWindow -/** Creates a Window in the Window Manager */ -int Interface::CreateWindow(unsigned short WindowID, int XPos, int YPos, unsigned int Width, unsigned int Height, char* Background) -{ - unsigned int i; - - for (i = 0; i < windows.size(); i++) { - if (windows[i] == NULL) - continue; - if (windows[i]->WindowID == WindowID && !stricmp( WindowPack, - windows[i]->WindowPack )) { - SetOnTop( i ); - windows[i]->Invalidate(); - return i; - } - } - - Window* win = new Window( WindowID, (ieWord) XPos, (ieWord) YPos, (ieWord) Width, (ieWord) Height ); - if (Background[0]) { - ResourceHolder mos(Background); - if (mos != NULL) { - win->SetBackGround( mos->GetSprite2D(), true ); - } - } - - strcpy( win->WindowPack, WindowPack ); - - int slot = -1; - for (i = 0; i < windows.size(); i++) { - if (windows[i] == NULL) { - slot = i; - break; - } - } - if (slot == -1) { - windows.push_back( win ); - slot = ( int ) windows.size() - 1; - } else { - windows[slot] = win; - } - win->Invalidate(); - return slot; -} - -/** Sets a Window on the Top */ -void Interface::SetOnTop(int Index) -{ - std::vector::iterator t; - for(t = topwin.begin(); t != topwin.end(); ++t) { - if((*t) == Index) { - topwin.erase(t); - break; - } - } - if(topwin.size() != 0) - topwin.insert(topwin.begin(), Index); - else - topwin.push_back(Index); -} -/** Add a window to the Window List */ -void Interface::AddWindow(Window * win) -{ - int slot = -1; - for(unsigned int i = 0; i < windows.size(); i++) { - Window *w = windows[i]; - - if(w==NULL) { - slot = i; - break; - } - } - if(slot == -1) { - windows.push_back(win); - slot=(int)windows.size()-1; - } - else - windows[slot] = win; - win->Invalidate(); -} - -/** Get a Control on a Window */ -int Interface::GetControl(unsigned short WindowIndex, unsigned long ControlID) const -{ - if (WindowIndex >= windows.size()) { - return -1; - } - Window* win = windows[WindowIndex]; - if (win == NULL) { - return -1; - } - int i = 0; - while (true) { - Control* ctrl = win->GetControl( (unsigned short) i ); - if (ctrl == NULL) - return -1; - if (ctrl->ControlID == ControlID) - return i; - i++; - } -} -/** Adjust the Scrolling factor of a control (worldmap atm) */ -int Interface::AdjustScrolling(unsigned short WindowIndex, - unsigned short ControlIndex, short x, short y) -{ - if (WindowIndex >= windows.size()) { - return -1; - } - Window* win = windows[WindowIndex]; - if (win == NULL) { - return -1; - } - Control* ctrl = win->GetControl( ControlIndex ); - if (ctrl == NULL) { - return -1; - } - switch(ctrl->ControlType) { - case IE_GUI_WORLDMAP: - ((WorldMapControl *) ctrl)->AdjustScrolling(x,y); - break; - default: //doesn't work for these - return -1; - } - return 0; -} - -/** Set the Tooltip text of a Control */ -int Interface::SetTooltip(unsigned short WindowIndex, - unsigned short ControlIndex, const char* string) -{ - if (WindowIndex >= windows.size()) { - return -1; - } - Window* win = windows[WindowIndex]; - if (win == NULL) { - return -1; - } - Control* ctrl = win->GetControl( ControlIndex ); - if (ctrl == NULL) { - return -1; - } - return ctrl->SetTooltip( string ); -} - -void Interface::DisplayTooltip(int x, int y, Control *ctrl) -{ - if (tooltip_ctrl && tooltip_ctrl == ctrl && tooltip_x == x && tooltip_y == y) - return; - tooltip_x = x; - tooltip_y = y; - tooltip_currtextw = 0; - tooltip_ctrl = ctrl; -} - -int Interface::GetVisible(unsigned short WindowIndex) const -{ - if (WindowIndex >= windows.size()) { - return -1; - } - Window* win = windows[WindowIndex]; - if (win == NULL) { - return -1; - } - return win->Visible; -} -/** Set a Window Visible Flag */ -int Interface::SetVisible(unsigned short WindowIndex, int visible) -{ - if (WindowIndex >= windows.size()) { - return -1; - } - Window* win = windows[WindowIndex]; - if (win == NULL) { - return -1; - } - if (visible!=WINDOW_FRONT) { - win->Visible = (char) visible; - } - switch (visible) { - case WINDOW_GRAYED: - win->Invalidate(); - //here is a fallthrough - case WINDOW_INVISIBLE: - //hiding the viewport if the gamecontrol window was made invisible - if (win->WindowID==65535) { - video->SetViewport( 0,0,0,0 ); - } - evntmgr->DelWindow( win ); - break; - - case WINDOW_VISIBLE: - if (win->WindowID==65535) { - video->SetViewport( win->XPos, win->YPos, win->Width, win->Height); - } - //here is a fallthrough - case WINDOW_FRONT: - if (win->Visible==WINDOW_VISIBLE) { - evntmgr->AddWindow( win ); - } - win->Invalidate(); - SetOnTop( WindowIndex ); - break; - } - return 0; -} - - -/** Set the Status of a Control in a Window */ -int Interface::SetControlStatus(unsigned short WindowIndex, - unsigned short ControlIndex, unsigned long Status) -{ - //don't set the status of an already invalidated window - Window* win = GetWindow(WindowIndex); - if (win == NULL) { - return -1; - } - Control* ctrl = win->GetControl( ControlIndex ); - if (ctrl == NULL) { - return -1; - } - if (Status&IE_GUI_CONTROL_FOCUSED) { - evntmgr->SetFocused( win, ctrl); - } - if (ctrl->ControlType != ((Status >> 24) & 0xff) ) { - return -2; - } - switch (ctrl->ControlType) { - case IE_GUI_BUTTON: - //Button - { - Button* btn = ( Button* ) ctrl; - btn->SetState( ( unsigned char ) ( Status & 0x7f ) ); - } - break; - default: - ctrl->Value = Status & 0x7f; - break; - } - return 0; -} - -/** Show a Window in Modal Mode */ -int Interface::ShowModal(unsigned short WindowIndex, int Shadow) -{ - if (WindowIndex >= windows.size()) { - printMessage( "Core", "Window not found", LIGHT_RED ); - return -1; - } - Window* win = windows[WindowIndex]; - if (win == NULL) { - printMessage( "Core", "Window already freed", LIGHT_RED ); - return -1; - } - win->Visible = WINDOW_FRONT; - //don't destroy the other window handlers - //evntmgr->Clear(); - SetOnTop( WindowIndex ); - evntmgr->AddWindow( win ); - evntmgr->SetFocused( win, NULL ); - - ModalWindow = NULL; - DrawWindows(); - win->Invalidate(); - - Color gray = { - 0, 0, 0, 128 - }; - Color black = { - 0, 0, 0, 255 - }; - - Region r( 0, 0, Width, Height ); - - if (Shadow == MODAL_SHADOW_GRAY) { - video->DrawRect( r, gray ); - } else if (Shadow == MODAL_SHADOW_BLACK) { - video->DrawRect( r, black ); - } - - ModalWindow = win; - return 0; -} - -bool Interface::IsFreezed() -{ - return !update_scripts; -} - -void Interface::GameLoop(void) -{ - update_scripts = false; - GameControl *gc = GetGameControl(); - if (gc) { - update_scripts = !(gc->GetDialogueFlags() & DF_FREEZE_SCRIPTS); - } - - bool do_update = GSUpdate(update_scripts); - - //i'm not sure if this should be here - - //in multi player (if we ever get to it), only the server must call this - if (do_update) { - if ( game->selected.size() > 0 ) { - gc->ChangeMap(GetFirstSelectedPC(true), false); - } - // the game object will run the area scripts as well - game->UpdateScripts(); - } -} - -/** handles hardcoded gui behaviour */ -void Interface::HandleGUIBehaviour(void) -{ - GameControl *gc = GetGameControl(); - if (gc) { - //this variable is used all over in the following hacks - int flg = gc->GetDialogueFlags(); - - //the following part is a series of hardcoded gui behaviour - - //initiating dialog - if (flg & DF_IN_DIALOG) { - // -3 noaction - // -2 close - // -1 open - // choose option - 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" ); - - // the last node of a dialog can have a new-dialog action! don't interfere in that case - ieDword newvar = 0; vars->Lookup("DialogChoose", newvar); - if (var == (ieDword) -1 || newvar != (ieDword) -1) { - vars->SetAt("DialogChoose", (ieDword) -3); - } - } - if (flg & DF_OPENCONTINUEWINDOW) { - guiscript->RunFunction( "GUIWORLD", "OpenContinueMessageWindow" ); - gc->SetDialogueFlags(DF_OPENCONTINUEWINDOW|DF_OPENENDWINDOW, BM_NAND); - } else if (flg & DF_OPENENDWINDOW) { - guiscript->RunFunction( "GUIWORLD", "OpenEndMessageWindow" ); - gc->SetDialogueFlags(DF_OPENCONTINUEWINDOW|DF_OPENENDWINDOW, BM_NAND); - } - } - - //handling container - if (CurrentContainer && UseContainer) { - if (!(flg & DF_IN_CONTAINER) ) { - gc->SetDialogueFlags(DF_IN_CONTAINER, BM_OR); - guiscript->RunFunction( "CommonWindow", "OpenContainerWindow" ); - } - } else { - if (flg & DF_IN_CONTAINER) { - gc->SetDialogueFlags(DF_IN_CONTAINER, BM_NAND); - guiscript->RunFunction( "CommonWindow", "CloseContainerWindow" ); - } - } - //end of gui hacks - } -} - -void Interface::DrawWindows(bool allow_delete) -{ - //here comes the REAL drawing of windows - if (ModalWindow) { - ModalWindow->DrawWindow(); - return; - } - size_t i = topwin.size(); - while(i--) { - unsigned int t = topwin[i]; - - if ( t >=windows.size() ) - continue; - - //visible ==1 or 2 will be drawn - Window* win = windows[t]; - if (win != NULL) { - if (win->Visible == WINDOW_INVALID) { - if (allow_delete) { - topwin.erase(topwin.begin()+i); - evntmgr->DelWindow( win ); - delete win; - windows[t]=NULL; - } - } else if (win->Visible) { - win->DrawWindow(); - } - } - } -} - -void Interface::DrawTooltip () -{ - if (! tooltip_ctrl || !tooltip_ctrl->Tooltip) - return; - - Font* fnt = GetFont( TooltipFont ); - char *tooltip_text = tooltip_ctrl->Tooltip; - - int w1 = 0; - int w2 = 0; - int strw = fnt->CalcStringWidth( tooltip_text ) + 8; - int w = strw; - int h = fnt->maxHeight; - - if (TooltipBack) { - // animate BG tooltips - // TODO: make tooltip animation an option instead - // of following hard-coded check! - if (TooltipMargin == 5) { - // TODO: make speed an option - int tooltip_anim_speed = 15; - if (tooltip_currtextw < strw) { - tooltip_currtextw += tooltip_anim_speed; - } - if (tooltip_currtextw > strw) { - tooltip_currtextw = strw; - } - w = tooltip_currtextw; - } - - h = TooltipBack[0]->Height; - w1 = TooltipBack[1]->Width; - w2 = TooltipBack[2]->Width; - w += TooltipMargin*2; - strw += TooltipMargin*2; - //multiline in case of too much text - if (w>TooltipBack[0]->Width) - strw=w=TooltipBack[0]->Width; - else if (strw>TooltipBack[0]->Width) - strw=TooltipBack[0]->Width; - } - - int strx = tooltip_x - strw / 2; - int y = tooltip_y - h / 2; - // Ensure placement within the screen - if (strx < 0) strx = 0; - else if (strx + strw + w1 + w2 > Width) - strx = Width - strw - w1 - w2; - if (y < 0) y = 0; - else if (y + h > Height) - y = Height - h; - - int x = strx + ((strw - w) / 2); - - // FIXME: take back[0] from center, not from left end - Region r2 = Region( x, y, w, h ); - if (TooltipBack) { - video->BlitSprite( TooltipBack[0], x + TooltipMargin, y, true, &r2 ); - video->BlitSprite( TooltipBack[1], x, y, true ); - video->BlitSprite( TooltipBack[2], x + w, y, true ); - } - - if (TooltipBack) { - r2.x+=TooltipMargin; - strx+=TooltipMargin; - } - Region textr = Region( strx, y, strw, h ); - fnt->Print( r2, textr, (ieByte *) tooltip_text, NULL, - IE_FONT_ALIGN_CENTER | IE_FONT_ALIGN_MIDDLE, true ); -} - -//interface for higher level functions, if the window was -//marked for deletion it is not returned -Window* Interface::GetWindow(unsigned short WindowIndex) const -{ - if (WindowIndex < windows.size()) { - Window *win = windows[WindowIndex]; - if (win && (win->Visible!=WINDOW_INVALID) ) { - return win; - } - } - return NULL; -} - -// this function will determine if wnd is a valid window pointer -// by checking if its WindowID is the same as the reference -bool Interface::IsValidWindow(unsigned short WindowID, Window *wnd) const -{ - size_t WindowIndex = windows.size(); - while (WindowIndex--) { - if (windows[WindowIndex] == wnd) { - return wnd->WindowID == WindowID; - } - } - return false; -} - -//this function won't delete the window, just mark it for deletion -//it will be deleted in the next DrawWindows cycle -//regardless, the window deleted is inaccessible for gui scripts and -//other high level functions from now -int Interface::DelWindow(unsigned short WindowIndex) -{ - if (WindowIndex >= windows.size()) { - return -1; - } - Window* win = windows[WindowIndex]; - if ((win == NULL) || (win->Visible==WINDOW_INVALID) ) { - printMessage( "Core", "Window deleted again", LIGHT_RED ); - return -1; - } - if (win == ModalWindow) { - ModalWindow = NULL; - RedrawAll(); //marking windows for redraw - } - evntmgr->DelWindow( win ); - win->release(); - //re-capturing new (old) modal window if any - size_t tw = topwin.size(); - for(size_t i=0;iVisible==WINDOW_FRONT) { - ModalWindow = tmp; - break; - } - } - return 0; -} - -void Interface::DelAllWindows() -{ - vars->SetAt("MessageWindow", (ieDword) ~0); - vars->SetAt("OptionsWindow", (ieDword) ~0); - vars->SetAt("PortraitWindow", (ieDword) ~0); - vars->SetAt("ActionsWindow", (ieDword) ~0); - vars->SetAt("TopWindow", (ieDword) ~0); - vars->SetAt("OtherWindow", (ieDword) ~0); - vars->SetAt("FloatWindow", (ieDword) ~0); - for(unsigned int WindowIndex=0; WindowIndexClear(); - ModalWindow = NULL; -} - -/** Popup the Console */ -void Interface::PopupConsole() -{ - ConsolePopped = !ConsolePopped; - RedrawAll(); - console->Changed = true; -} - -/** Draws the Console */ -void Interface::DrawConsole() -{ - console->Draw( 0, 0 ); -} - -/** Get the Sound Manager */ -SaveGameIterator* Interface::GetSaveGameIterator() const -{ - return sgiterator; -} -/** Sends a termination signal to the Video Driver */ -bool Interface::Quit(void) -{ - return video->Quit(); -} -/** Returns the variables dictionary */ -Variables* Interface::GetDictionary() const -{ - return vars; -} -/** Returns the token dictionary */ -Variables* Interface::GetTokenDictionary() const -{ - return tokens; -} -/** Get the Music Manager */ -MusicMgr* Interface::GetMusicMgr() const -{ - return music.get(); -} -/** Loads an IDS Table, returns -1 on error or the Symbol Table Index on success */ -int Interface::LoadSymbol(const char* ResRef) -{ - int ind = GetSymbolIndex( ResRef ); - if (ind != -1) { - return ind; - } - DataStream* str = gamedata->GetResource( ResRef, IE_IDS_CLASS_ID ); - if (!str) { - return -1; - } - PluginHolder sm(IE_IDS_CLASS_ID); - if (!sm) { - delete str; - return -1; - } - if (!sm->Open(str)) { - return -1; - } - Symbol s; - strncpy( s.ResRef, ResRef, 8 ); - s.sm = sm; - ind = -1; - for (size_t i = 0; i < symbols.size(); i++) { - if (!symbols[i].sm) { - ind = ( int ) i; - break; - } - } - if (ind != -1) { - symbols[ind] = s; - return ind; - } - symbols.push_back( s ); - return ( int ) symbols.size() - 1; -} -/** Gets the index of a loaded Symbol Table, returns -1 on error */ -int Interface::GetSymbolIndex(const char* ResRef) const -{ - for (size_t i = 0; i < symbols.size(); i++) { - if (!symbols[i].sm) - continue; - if (strnicmp( symbols[i].ResRef, ResRef, 8 ) == 0) - return ( int ) i; - } - return -1; -} -/** Gets a Loaded Symbol Table by its index, returns NULL on error */ -Holder Interface::GetSymbol(unsigned int index) const -{ - if (index >= symbols.size()) { - return Holder(); - } - if (!symbols[index].sm) { - return Holder(); - } - return symbols[index].sm; -} -/** Frees a Loaded Symbol Table, returns false on error, true on success */ -bool Interface::DelSymbol(unsigned int index) -{ - if (index >= symbols.size()) { - return false; - } - if (!symbols[index].sm) { - return false; - } - symbols[index].sm.release(); - return true; -} -/** Plays a Movie */ -int Interface::PlayMovie(const char* ResRef) -{ - ResourceHolder mp(ResRef); - if (!mp) { - return -1; - } - - ieDword subtitles = 0; - Font *SubtitleFont = NULL; - Palette *palette = NULL; - ieDword *frames = NULL; - ieDword *strrefs = NULL; - int cnt = 0; - int offset = 0; - - //one of these two should exist (they both mean the same thing) - vars->Lookup("Display Movie Subtitles", subtitles); - if (subtitles) { - //HoW flag - cnt=-3; - offset = 3; - } else { - //ToB flag - vars->Lookup("Display Subtitles", subtitles); - } - AutoTable sttable; - if (subtitles && sttable.load(ResRef)) { - cnt += sttable->GetRowCount(); - if (cnt>0) { - frames = (ieDword *) malloc(cnt * sizeof(ieDword) ); - strrefs = (ieDword *) malloc(cnt * sizeof(ieDword) ); - } else { - cnt = 0; - } - if (frames && strrefs) { - for (int i=0;iQueryField(i+offset, 0) ); - strrefs[i] = atoi (sttable->QueryField(i+offset, 1) ); - } - } - int r = atoi(sttable->QueryField("red", "frame")); - int g = atoi(sttable->QueryField("green", "frame")); - int b = atoi(sttable->QueryField("blue", "frame")); - SubtitleFont = GetFont (MovieFont); //will change - if (r || g || b) { - if (SubtitleFont) { - Color fore = {(unsigned char) r,(unsigned char) g,(unsigned char) b, 0x00}; - Color back = {0x00, 0x00, 0x00, 0x00}; - palette = CreatePalette( fore, back ); - } - } - } - - //shutting down music and ambients before movie - if (music) - music->HardEnd(); - AmbientMgr *ambim = AudioDriver->GetAmbientMgr(); - if (ambim) ambim->deactivate(); - video->SetMovieFont(SubtitleFont, palette ); - mp->CallBackAtFrames(cnt, frames, strrefs); - mp->Play(); - gamedata->FreePalette( palette ); - if (frames) - free(frames); - if (strrefs) - free(strrefs); - //restarting music - if (music) - music->Start(); - if (ambim) ambim->activate(); - //this will fix redraw all windows as they looked like - //before the movie - RedrawAll(); - - //Setting the movie name to 1 - vars->SetAt( ResRef, 1 ); - return 0; -} - -int Interface::Roll(int dice, int size, int add) const -{ - if (dice < 1) { - return add; - } - if (size < 1) { - return add; - } - if (dice > 100) { - return add + dice * size / 2; - } - for (int i = 0; i < dice; i++) { - add += rand() % size + 1; - } - return add; -} - -static char bmp_suffix[6]="M.BMP"; -static char png_suffix[6]="M.PNG"; - -int Interface::GetPortraits(TextArea* ta, bool smallorlarge) -{ - int count = 0; - char Path[_MAX_PATH]; - - if (smallorlarge) { - bmp_suffix[0]='S'; - png_suffix[0]='S'; - } else { - bmp_suffix[0]='M'; - png_suffix[0]='M'; - } - PathJoin( Path, GamePath, GamePortraitsPath, NULL ); - DirectoryIterator dir(Path); - if (!dir) { - return -1; - } - print( "Looking in %s\n", Path ); - do { - char *name = dir.GetName(); - if (name[0] == '.') - continue; - if (dir.IsDirectory()) - continue; - strupr(name); - char *pos = strstr(name,bmp_suffix); - if (!pos && IsAvailable(IE_PNG_CLASS_ID) ) { - pos = strstr(name,png_suffix); - } - if (!pos) continue; - pos[1]=0; - count++; - ta->AppendText( name, -1 ); - } while (++dir); - return count; -} - -int Interface::GetCharSounds(TextArea* ta) -{ - bool hasfolders; - int count = 0; - char Path[_MAX_PATH]; - - PathJoin( Path, GamePath, GameSoundsPath, NULL ); - hasfolders = ( HasFeature( GF_SOUNDFOLDERS ) != 0 ); - DirectoryIterator dir(Path); - if (!dir) { - return -1; - } - print( "Looking in %s\n", Path ); - do { - char *name = dir.GetName(); - if (name[0] == '.') - continue; - if (hasfolders == !dir.IsDirectory()) - continue; - if (!hasfolders) { - strupr(name); - char *pos = strstr(name,"A.WAV"); - if (!pos) continue; - *pos=0; - } - count++; - ta->AppendText( name, -1 ); - } while (++dir); - return count; -} - -int Interface::GetCharacters(TextArea* ta) -{ - int count = 0; - char Path[_MAX_PATH]; - - PathJoin( Path, GamePath, GameCharactersPath, NULL ); - DirectoryIterator dir(Path); - if (!dir) { - return -1; - } - print( "Looking in %s\n", Path ); - do { - char *name = dir.GetName(); - if (name[0] == '.') - continue; - if (dir.IsDirectory()) - continue; - strupr(name); - char *pos = strstr(name,".CHR"); - if (!pos) continue; - *pos=0; - count++; - ta->AppendText( name, -1 ); - } while (++dir); - return count; -} - -bool Interface::LoadINI(const char* filename) -{ - FileStream* config = FileStream::OpenFile(filename); - if (config == NULL) { - return false; - } - char name[65], value[_MAX_PATH + 3]; - while (config->Remains()) { - char line[_MAX_PATH]; - - if (config->ReadLine(line, _MAX_PATH) == -1) - break; - - if ((line[0] == '#') || - ( line[0] == '[' ) || - ( line[0] == '\r' ) || - ( line[0] == '\n' ) || - ( line[0] == ';' )) { - continue; - } - - name[0] = 0; - value[0] = 0; - - //the * element is not counted - if (sscanf( line, "%[^=]=%[^\r\n]", name, value )!=2) - continue; - if (( value[0] >= '0' ) && ( value[0] <= '9' )) { - vars->SetAt( name, atoi( value ) ); - } - } - delete config; - return true; -} - -/** Enables/Disables the Cut Scene Mode */ -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 == (bool)(gc->GetScreenFlags()&SF_CUTSCENE)) - return; - - gc->SetCutSceneMode( active ); - } - if (game) { - if (active) { - game->ControlStatus |= CS_HIDEGUI; - } else { - game->ControlStatus &= ~CS_HIDEGUI; - } - SetEventFlag(EF_CONTROL); - } - video->SetMouseEnabled(!active); -} - -/** returns true if in dialogue or cutscene */ -bool Interface::InCutSceneMode() const -{ - 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) -{ - SetCutSceneMode(false); - if (timer) { - //clear cutscenes - //clear fade/screenshake effects - timer->Init(); - timer->SetFadeFromColor(0); - } - - DelAllWindows(); //delete all windows, including GameControl - - //shutting down ingame music - //(do it before deleting the game) - if (music) { - music->HardEnd(); - } - // stop any ambients which are still enqueued - if (AudioDriver) { - AmbientMgr *ambim = AudioDriver->GetAmbientMgr(); - if (ambim) ambim->deactivate(); - } - //delete game, worldmap - if (game) { - delete game; - game=NULL; - } - if (worldmap) { - delete worldmap; - worldmap=NULL; - } - if (BackToMain) { - strcpy(NextScript, "Start"); - QuitFlag |= QF_CHANGESCRIPT; - } - GSUpdate(true); -} - -void Interface::SetupLoadGame(Holder sg, int ver_override) -{ - LoadGameIndex = sg; - VersionOverride = ver_override; - QuitFlag |= QF_LOADGAME; -} - -void Interface::LoadGame(SaveGame *sg, int ver_override) -{ - // This function has rather painful error handling, - // as it should swap all the objects or none at all - // and the loading can fail for various reasons - - // Yes, it uses goto. Other ways seemed too awkward for me. - - gamedata->SaveAllStores(); - strings->CloseAux(); - tokens->RemoveAll(NULL); //clearing the token dictionary - - if(calendar) delete calendar; - calendar = new Calendar; - - DataStream* gam_str = NULL; - DataStream* sav_str = NULL; - DataStream* wmp_str1 = NULL; - DataStream* wmp_str2 = NULL; - - Game* new_game = NULL; - WorldMapArray* new_worldmap = NULL; - - LoadProgress(10); - if (!KeepCache) DelTree((const char *) CachePath, true); - LoadProgress(15); - - if (sg == NULL) { - //Load the Default Game - gam_str = gamedata->GetResource( GameNameResRef, IE_GAM_CLASS_ID ); - sav_str = NULL; - wmp_str1 = gamedata->GetResource( WorldMapName[0], IE_WMP_CLASS_ID ); - if (WorldMapName[1][0]) { - wmp_str2 = gamedata->GetResource( WorldMapName[1], IE_WMP_CLASS_ID ); - } - } else { - gam_str = sg->GetGame(); - sav_str = sg->GetSave(); - wmp_str1 = sg->GetWmap(0); - if (WorldMapName[1][0]) { - wmp_str2 = sg->GetWmap(1); - if (!wmp_str2) { - //upgrade an IWD game to HOW - wmp_str2 = gamedata->GetResource( WorldMapName[1], IE_WMP_CLASS_ID ); - } - } - } - - // These are here because of the goto - PluginHolder gam_mgr(IE_GAM_CLASS_ID); - PluginHolder wmp_mgr(IE_WMP_CLASS_ID); - - if (!gam_str || !(wmp_str1 || wmp_str2) ) - goto cleanup; - - // Load GAM file - if (!gam_mgr) - goto cleanup; - - if (!gam_mgr->Open(gam_str)) - goto cleanup; - - new_game = gam_mgr->LoadGame(new Game(), ver_override); - if (!new_game) - goto cleanup; - - gam_str = NULL; - - // Load WMP (WorldMap) file - if (!wmp_mgr) - goto cleanup; - - if (!wmp_mgr->Open(wmp_str1, wmp_str2)) - goto cleanup; - - new_worldmap = wmp_mgr->GetWorldMapArray( ); - - wmp_str1 = NULL; - wmp_str2 = NULL; - - LoadProgress(20); - // Unpack SAV (archive) file to Cache dir - if (sav_str) { - PluginHolder ai(IE_SAV_CLASS_ID); - if (ai) { - if (ai->DecompressSaveGame(sav_str) != GEM_OK) { - goto cleanup; - } - } - delete sav_str; - sav_str = NULL; - } - - // Let's assume that now is everything loaded OK and swap the objects - - delete game; - delete worldmap; - - game = new_game; - worldmap = new_worldmap; - - strings->OpenAux(); - LoadProgress(70); - return; -cleanup: - // Something went wrong, so try to clean after itself - - delete new_game; - delete new_worldmap; - - delete gam_str; - delete wmp_str1; - delete wmp_str2; - delete sav_str; -} - -/* swapping out old resources */ -void Interface::UpdateMasterScript() -{ - if (game) { - game->SetScript( GlobalScript, 0 ); - } - - PluginHolder wmp_mgr(IE_WMP_CLASS_ID); - if (! wmp_mgr) - return; - - if (worldmap) { - DataStream *wmp_str1 = gamedata->GetResource( WorldMapName[0], IE_WMP_CLASS_ID ); - DataStream *wmp_str2 = gamedata->GetResource( WorldMapName[1], IE_WMP_CLASS_ID ); - - if (!wmp_mgr->Open(wmp_str1, wmp_str2)) { - delete wmp_str1; - delete wmp_str2; - } - - delete worldmap; - worldmap = wmp_mgr->GetWorldMapArray(); - } -} - -bool Interface::HideGCWindow() -{ - Window *window = GetWindow( 0 ); - // in the beginning, there's no window at all - if (! window) - return false; - - Control* gc = window->GetControl(0); - if (gc->ControlType!=IE_GUI_GAMECONTROL) { - return false; - } - SetVisible(0, WINDOW_INVISIBLE); - return true; -} - -void Interface::UnhideGCWindow() -{ - Window *window = GetWindow( 0 ); - if (!window) - return; - Control* gc = window->GetControl(0); - if (gc->ControlType!=IE_GUI_GAMECONTROL) - return; - SetVisible(0, WINDOW_VISIBLE); -} - -GameControl *Interface::GetGameControl() const -{ - Window *window = GetWindow( 0 ); - // in the beginning, there's no window at all - if (! window) - return NULL; - - Control* gc = window->GetControl(0); - if (gc == NULL) { - return NULL; - } - if (gc->ControlType!=IE_GUI_GAMECONTROL) { - return NULL; - } - return (GameControl *) gc; -} - -bool Interface::InitItemTypes() -{ - if (slotmatrix) { - free(slotmatrix); - } - AutoTable it("itemtype"); - ItemTypes = 0; - if (it) { - ItemTypes = it->GetRowCount(); //number of itemtypes - if (ItemTypes<0) { - ItemTypes = 0; - } - int InvSlotTypes = it->GetColumnCount(); - if (InvSlotTypes > 32) { //bit count limit - InvSlotTypes = 32; - } - //make sure unsigned int is 32 bits - slotmatrix = (ieDword *) malloc(ItemTypes * sizeof(ieDword) ); - for (int i=0;iQueryField(i,j),NULL,0) ) { - value |= k; - } - k <<= 1; - } - //we let any items in the inventory - slotmatrix[i] = (ieDword) value | SLOT_INVENTORY; - } - } - - //slottype describes the inventory structure - Inventory::Init(HasFeature(GF_MAGICBIT)); - AutoTable st("slottype"); - if (slottypes) { - free(slottypes); - slottypes = NULL; - } - SlotTypes = 0; - if (st) { - SlotTypes = st->GetRowCount(); - //make sure unsigned int is 32 bits - slottypes = (SlotType *) malloc(SlotTypes * sizeof(SlotType) ); - memset(slottypes, -1, SlotTypes * sizeof(SlotType) ); - for (unsigned int row = 0; row < SlotTypes; row++) { - bool alias; - unsigned int i = (ieDword) strtol(st->GetRowName(row),NULL,0 ); - if (i>=SlotTypes) continue; - if (slottypes[i].sloteffects!=0xffffffffu) { - slottypes[row].slot = i; - i=row; - alias = true; - } else { - slottypes[row].slot = i; - alias = false; - } - slottypes[i].slottype = (ieDword) strtol(st->QueryField(row,0),NULL,0 ); - slottypes[i].slotid = (ieDword) strtol(st->QueryField(row,1),NULL,0 ); - strnlwrcpy( slottypes[i].slotresref, st->QueryField(row,2), 8 ); - slottypes[i].slottip = (ieDword) strtol(st->QueryField(row,3),NULL,0 ); - slottypes[i].slotflags = (ieDword) strtol(st->QueryField(row,5),NULL,0 ); - //don't fill sloteffects for aliased slots (pst) - if (alias) { - continue; - } - slottypes[i].sloteffects = (ieDword) strtol(st->QueryField(row,4),NULL,0 ); - //setting special slots - if (slottypes[i].slottype&SLOT_ITEM) { - if (slottypes[i].slottype&SLOT_INVENTORY) { - Inventory::SetInventorySlot(i); - } else { - Inventory::SetQuickSlot(i); - } - } - switch (slottypes[i].sloteffects) { - //fist slot, not saved, default weapon - case SLOT_EFFECT_FIST: Inventory::SetFistSlot(i); break; - //magic weapon slot, overrides all weapons - case SLOT_EFFECT_MAGIC: Inventory::SetMagicSlot(i); break; - //weapon slot, Equipping marker is relative to it - case SLOT_EFFECT_MELEE: Inventory::SetWeaponSlot(i); break; - //ranged slot - case SLOT_EFFECT_MISSILE: Inventory::SetRangedSlot(i); break; - //right hand - case SLOT_EFFECT_LEFT: Inventory::SetShieldSlot(i); break; - //head (for averting critical hit) - case SLOT_EFFECT_HEAD: Inventory::SetHeadSlot(i); break; - default:; - } - } - } - return (it && st); -} - -ieDword Interface::FindSlot(unsigned int idx) const -{ - ieDword i; - - for (i=0;i=SlotTypes) { - return 0; - } - return slottypes[idx].slot; -} - -ieDword Interface::QuerySlotType(unsigned int idx) const -{ - if (idx>=SlotTypes) { - return 0; - } - return slottypes[idx].slottype; -} - -ieDword Interface::QuerySlotID(unsigned int idx) const -{ - if (idx>=SlotTypes) { - return 0; - } - return slottypes[idx].slotid; -} - -ieDword Interface::QuerySlottip(unsigned int idx) const -{ - if (idx>=SlotTypes) { - return 0; - } - return slottypes[idx].slottip; -} - -ieDword Interface::QuerySlotEffects(unsigned int idx) const -{ - if (idx>=SlotTypes) { - return 0; - } - return slottypes[idx].sloteffects; -} - -ieDword Interface::QuerySlotFlags(unsigned int idx) const -{ - if (idx>=SlotTypes) { - return 0; - } - return slottypes[idx].slotflags; -} - -const char *Interface::QuerySlotResRef(unsigned int idx) const -{ - if (idx>=SlotTypes) { - return ""; - } - return slottypes[idx].slotresref; -} - -// checks the itemtype vs. slottype, and also checks the usability flags -// vs. Actor's stats (alignment, class, race, kit etc.) -int Interface::CanUseItemType(int slottype, Item *item, Actor *actor, bool feedback, bool equipped) const -{ - //inventory is a special case, we allow any items to enter it - if ( slottype==-1 ) { - return SLOT_INVENTORY; - } - //if we look for ALL slot types, then SLOT_SHIELD shouldn't interfere - //with twohandedness - //As long as this is an Item, use the ITEM constant - //switch for IE_INV_ITEM_* if it is a CREItem - if (item->Flags&IE_ITEM_TWO_HANDED) { - //if the item is twohanded and there are more slots, drop the shield slot - if (slottype&~SLOT_SHIELD) { - slottype&=~SLOT_SHIELD; - } - if (slottype&SLOT_SHIELD) { - //cannot equip twohanded in offhand - if (feedback) displaymsg->DisplayConstantString(STR_NOT_IN_OFFHAND, 0xf0f0f0); - return 0; - } - } - - if ( (unsigned int) item->ItemType>=(unsigned int) ItemTypes) { - //invalid itemtype - if (feedback) displaymsg->DisplayConstantString(STR_WRONGITEMTYPE, 0xf0f0f0); - return 0; - } - - //if actor is supplied, check its usability fields - if (actor) { - //constant strings - int idx = actor->Unusable(item); - if (idx) { - if (feedback) displaymsg->DisplayConstantString(idx, 0xf0f0f0); - return 0; - } - //custom strings - ieStrRef str = actor->Disabled(item->Name, item->ItemType); - if (str && !equipped) { - if (feedback) displaymsg->DisplayString(str, 0xf0f0f0, 0); - return 0; - } - } - - //if any bit is true, the answer counts as true - int ret = (slotmatrix[item->ItemType]&slottype); - - if (!ret) { - if (feedback) displaymsg->DisplayConstantString(STR_WRONGITEMTYPE, 0xf0f0f0); - return 0; - } - - //this warning comes only when feedback is enabled - if (feedback) { - //this was, but that disabled equipping of amber earrings in PST - //if (slotmatrix[item->ItemType]&(SLOT_QUIVER|SLOT_WEAPON|SLOT_ITEM)) { - if (ret&(SLOT_QUIVER|SLOT_WEAPON|SLOT_ITEM)) { - //don't ruin the return variable, it contains the usable slot bits - int flg = 0; - if (ret&SLOT_QUIVER) { - if (item->GetWeaponHeader(true)) flg = 1; - } - - if (ret&SLOT_WEAPON) { - //melee - if (item->GetWeaponHeader(false)) flg = 1; - //ranged - if (item->GetWeaponHeader(true)) flg = 1; - } - - if (ret&SLOT_ITEM) { - if (item->GetEquipmentHeaderNumber(0)!=0xffff) flg = 1; - } - - if (!flg) { - displaymsg->DisplayConstantString(STR_UNUSABLEITEM, 0xf0f0f0); - return 0; - } - } - } - - return ret; -} - -Label *Interface::GetMessageLabel() const -{ - ieDword WinIndex = (ieDword) -1; - ieDword TAIndex = (ieDword) -1; - - vars->Lookup( "OtherWindow", WinIndex ); - if (( WinIndex != (ieDword) -1 ) && - ( vars->Lookup( "MessageLabel", TAIndex ) )) { - Window* win = GetWindow( (unsigned short) WinIndex ); - if (win) { - Control *ctrl = win->GetControl( (unsigned short) TAIndex ); - if (ctrl && ctrl->ControlType==IE_GUI_LABEL) - return (Label *) ctrl; - } - } - return NULL; -} - -TextArea *Interface::GetMessageTextArea() const -{ - ieDword WinIndex = (ieDword) -1; - ieDword TAIndex = (ieDword) -1; - - vars->Lookup( "MessageWindow", WinIndex ); - if (( WinIndex != (ieDword) -1 ) && - ( vars->Lookup( "MessageTextArea", TAIndex ) )) { - Window* win = GetWindow( (unsigned short) WinIndex ); - if (win) { - Control *ctrl = win->GetControl( (unsigned short) TAIndex ); - if (ctrl && ctrl->ControlType==IE_GUI_TEXTAREA) - return (TextArea *) ctrl; - } - } - return NULL; -} - -static const char *saved_extensions[]={".are",".sto",0}; -static const char *saved_extensions_last[]={".tot",".toh",0}; - -//returns the priority of the file to be saved -//2 - save -//1 - save last -//0 - don't save -int Interface::SavedExtension(const char *filename) -{ - const char *str=strchr(filename,'.'); - if (!str) return 0; - int i=0; - while(saved_extensions[i]) { - if (!stricmp(saved_extensions[i], str) ) return 2; - i++; - } - i=0; - while(saved_extensions_last[i]) { - if (!stricmp(saved_extensions_last[i], str) ) return 1; - i++; - } - return 0; -} - -static const char *protected_extensions[]={".exe",".dll",".so",0}; - -//returns true if file should be saved -bool Interface::ProtectedExtension(const char *filename) -{ - const char *str=strchr(filename,'.'); - if (!str) return false; - int i=0; - while(protected_extensions[i]) { - if (!stricmp(protected_extensions[i], str) ) return true; - i++; - } - return false; -} - -void Interface::RemoveFromCache(const ieResRef resref, SClass_ID ClassID) -{ - char filename[_MAX_PATH]; - - PathJoinExt(filename, CachePath, resref, TypeExt(ClassID)); - unlink ( filename); -} - -//this function checks if the path is eligible as a cache -//if it contains a directory, or suspicious file extensions -//we bail out, because the cache will be purged regularly. -bool Interface::StupidityDetector(const char* Pt) -{ - char Path[_MAX_PATH]; - strcpy( Path, Pt ); - DirectoryIterator dir(Path); - if (!dir) { - print("\n**cannot open**\n"); - return true; - } - do { - const char *name = dir.GetName(); - if (dir.IsDirectory()) { - if (name[0] == '.') { - if (name[1] == '\0') - continue; - if (name[1] == '.' && name[2] == '\0') - continue; - } - print("\n**contains another dir**\n"); - return true; //a directory in there??? - } - if (ProtectedExtension(name) ) { - print("\n**contains alien files**\n"); - return true; //an executable file in there??? - } - } while (++dir); - //ok, we got a good conscience - return false; -} - -void Interface::DelTree(const char* Pt, bool onlysave) -{ - char Path[_MAX_PATH]; - - if (!Pt[0]) return; //Don't delete the root filesystem :) - strcpy( Path, Pt ); - DirectoryIterator dir(Path); - if (!dir) { - return; - } - do { - char *name = dir.GetName(); - if (dir.IsDirectory()) - continue; - if (name[0] == '.') - continue; - if (!onlysave || SavedExtension(name) ) { - char dtmp[_MAX_PATH]; - dir.GetFullPath(dtmp); - unlink( dtmp ); - } - } while (++dir); -} - -void Interface::LoadProgress(int percent) -{ - vars->SetAt("Progress", percent); - RedrawControls("Progress", percent); - RedrawAll(); - DrawWindows(); - video->SwapBuffers(); -} - -void Interface::ReleaseDraggedItem() -{ - DraggedItem=NULL; //shouldn't free this - video->SetDragCursor (NULL); -} - -void Interface::DragItem(CREItem *item, const ieResRef Picture) -{ - //We should drop the dragged item and pick this up, - //we shouldn't have a valid DraggedItem at this point. - //Anyway, if there is still a dragged item, it will be destroyed. - if (DraggedItem) { - printMessage("Core","Forgot to call ReleaseDraggedItem when leaving inventory (item destroyed)!\n",YELLOW); - delete DraggedItem; - } - DraggedItem = item; - if (video) { - Sprite2D* DraggedCursor = NULL; - if (item) { - DraggedCursor = gamedata->GetBAMSprite( Picture, 0, 0 ); - } - video->SetDragCursor (DraggedCursor); - } -} - -void Interface::SetDraggedPortrait(int dp, int idx) -{ - if (idx<0) idx=14; - DraggedPortrait = dp; - if (dp) { - //hmm this might work? - Cursors[idx]->acquire(); - video->SetDragCursor(Cursors[idx]); - } else { - video->SetDragCursor(NULL); - } -} - -bool Interface::ReadItemTable(const ieResRef TableName, const char * Prefix) -{ - ieResRef ItemName; - int i,j; - - AutoTable tab(TableName); - if (!tab) { - return false; - } - i=tab->GetRowCount(); - for(j=0;jGetRowName(j), 8); - } - //Variable elements are free'd, so we have to use malloc - //well, not anymore, we can use ReleaseFunction - int l=tab->GetColumnCount(j); - if (l<1) continue; - int cl = atoi(tab->GetColumnName(0)); - ItemList *itemlist = new ItemList(l, cl); - for(int k=0;kResRefs[k],tab->QueryField(j,k), 8); - } - RtRows->SetAt(ItemName, (void*)itemlist); - } - return true; -} - -bool Interface::ReadRandomItems() -{ - ieResRef RtResRef; - int i; - - ieDword difflev=0; //rt norm or rt fury - vars->Lookup("Nightmare Mode", difflev); - if (RtRows) { - RtRows->RemoveAll(ReleaseItemList); - } - else { - RtRows=new Variables(10, 17); //block size, hash table size - if (!RtRows) { - return false; - } - RtRows->SetType( GEM_VARIABLES_POINTER ); - } - AutoTable tab("randitem"); - if (!tab) { - return false; - } - if (difflev>=tab->GetColumnCount()) { - difflev = tab->GetColumnCount()-1; - } - - //the gold item - strnlwrcpy( GoldResRef, tab->QueryField((unsigned int) 0,(unsigned int) 0), 8); - if ( GoldResRef[0]=='*' ) { - return false; - } - strnlwrcpy( RtResRef, tab->QueryField( 1, difflev ), 8); - i=atoi( RtResRef ); - if (i<1) { - ReadItemTable( RtResRef, 0 ); //reading the table itself - return true; - } - if (i>5) { - i=5; - } - while(i--) { - strnlwrcpy( RtResRef, tab->QueryField(2+i,difflev), 8); - ReadItemTable( RtResRef,tab->GetRowName(2+i) ); - } - return true; -} - -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] ); - str->ReadWord( &itm->Usages[1] ); - str->ReadWord( &itm->Usages[2] ); - str->ReadDword( &itm->Flags ); - if (ResolveRandomItem(itm) ) { - return itm; - } - return NULL; -} - -#define MAX_LOOP 10 - -//This function generates random items based on the randitem.2da file -//there could be a loop, but we don't want to freeze, so there is a limit -bool Interface::ResolveRandomItem(CREItem *itm) -{ - if (!RtRows) return true; - for(int loop=0;loopLookup( itm->ItemResRef, lookup ) ) { - if (!gamedata->Exists(itm->ItemResRef, IE_ITM_CLASS_ID)) { - printMessage("Interface", "Nonexistent random item (bad table entry) detected: %s\n", LIGHT_RED, itm->ItemResRef); - return false; - } - return true; - } - ItemList *itemlist = (ItemList*)lookup; - if (itemlist->WeightOdds) { - //instead of 1d19 we calculate with 2d10 (which also has 19 possible values) - i=Roll(2,(itemlist->Count+1)/2,-2); - } else { - i=Roll(1,itemlist->Count,-1); - } - strnlwrcpy( NewItem, itemlist->ResRefs[i], 8); - char *p=(char *) strchr(NewItem,'*'); - if (p) { - *p=0; //doing this so endptr is ok - k=strtol(p+1,NULL,10); - } else { - k=1; - } - j=strtol(NewItem,&endptr,10); - if (j<1) { - j=1; - } - if (*endptr) { - strnlwrcpy(itm->ItemResRef, NewItem, 8); - } else { - strnlwrcpy(itm->ItemResRef, GoldResRef, 8); - } - if ( !memcmp( itm->ItemResRef,"no_drop",8 ) ) { - itm->ItemResRef[0]=0; - } - if (!itm->ItemResRef[0]) { - return false; - } - itm->Usages[0]=(ieWord) Roll(j,k,0); - } - printMessage("Interface", "Loop detected while generating random item:%s\n", LIGHT_RED, - itm->ItemResRef); - return false; -} - -//now that we store spell name in spl, i guess, we shouldn't pass 'ieResRef name' -//these functions are needed because Win32 doesn't allow freeing memory from -//another dll. So we allocate all commonly used memories from core -ITMExtHeader *Interface::GetITMExt(int count) -{ - return new ITMExtHeader[count]; -} - -SPLExtHeader *Interface::GetSPLExt(int count) -{ - return new SPLExtHeader[count]; -} - -Effect *Interface::GetEffect(ieDword opcode) -{ - if (opcode==0xffffffff) { - return NULL; - } - Effect *fx = new Effect(); - if (!fx) { - return NULL; - } - memset(fx,0,sizeof(Effect)); - fx->Opcode=opcode; - return fx; -} - -Effect *Interface::GetFeatures(int count) -{ - return new Effect[count]; -} - -/* -void Interface::FreeITMExt(ITMExtHeader *p, Effect *e) -{ - delete [] p; - delete [] e; -} - -void Interface::FreeSPLExt(SPLExtHeader *p, Effect *e) -{ - delete [] p; - delete [] e; -} -*/ - -WorldMapArray *Interface::NewWorldMapArray(int count) -{ - return new WorldMapArray(count); -} - -Container *Interface::GetCurrentContainer() -{ - return CurrentContainer; -} - -int Interface::CloseCurrentContainer() -{ - UseContainer = false; - if ( !CurrentContainer) { - return -1; - } - //remove empty ground piles on closeup - CurrentContainer->GetCurrentArea()->TMap->CleanupContainer(CurrentContainer); - CurrentContainer = NULL; - return 0; -} - -void Interface::SetCurrentContainer(Actor *actor, Container *arg, bool flag) -{ - //abort action if the first selected PC isn't the original actor - if (actor!=GetFirstSelectedPC(false)) { - CurrentContainer = NULL; - return; - } - CurrentContainer = arg; - UseContainer = flag; -} - -Store *Interface::GetCurrentStore() -{ - return CurrentStore; -} - -void Interface::CloseCurrentStore() -{ - gamedata->SaveStore(CurrentStore); - CurrentStore = NULL; -} - -Store *Interface::SetCurrentStore(const ieResRef resname, ieDword owner) -{ - if (CurrentStore) { - if (!strnicmp(CurrentStore->Name, resname, 8)) { - return CurrentStore; - } - - //not simply delete the old store, but save it - CloseCurrentStore(); - } - - CurrentStore = gamedata->GetStore(resname); - if (CurrentStore == NULL) { - return NULL; - } - if (owner) { - CurrentStore->SetOwnerID(owner); - } - return CurrentStore; -} - -void Interface::SetMouseScrollSpeed(int speed) { - mousescrollspd = (speed+1)*2; -} - -int Interface::GetMouseScrollSpeed() { - return mousescrollspd; -} - -ieStrRef Interface::GetRumour(const ieResRef dlgref) -{ - PluginHolder dm(IE_DLG_CLASS_ID); - dm->Open(gamedata->GetResource(dlgref, IE_DLG_CLASS_ID)); - Dialog *dlg = dm->GetDialog(); - - if (!dlg) { - printMessage("Interface", "Cannot load dialog: %s\n", LIGHT_RED, dlgref); - return (ieStrRef) -1; - } - Scriptable *pc=game->GetPC( game->GetSelectedPCSingle(), false ); - - ieStrRef ret = (ieStrRef) -1; - int i = dlg->FindRandomState( pc ); - if (i>=0 ) { - ret = dlg->GetState( i )->StrRef; - } - delete dlg; - return ret; -} - -//plays stock sound listed in defsound.2da -void Interface::PlaySound(int index) -{ - if (index<=DSCount) { - AudioDriver->Play(DefSound[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()) { - if (actor->InPartyInParty; - } - } - } - - if (forced && !ret) { - return game->FindPC((unsigned int) 0); - } - return ret; -} - -Actor *Interface::GetFirstSelectedActor() -{ - if (game->selected.size()) { - return game->selected[0]; - } - return NULL; -} - -//this is used only for the console -Sprite2D *Interface::GetCursorSprite() -{ - Sprite2D *spr = gamedata->GetBAMSprite(CursorBam, 0, 0); - if (spr) - { - if(HasFeature(GF_OVERRIDE_CURSORPOS)) - { - spr->XPos=1; - spr->YPos=spr->Height-1; - } - } - return spr; -} - -Sprite2D *Interface::GetScrollCursorSprite(int frameNum, int spriteNum) -{ - return gamedata->GetBAMSprite(ScrollCursorBam, frameNum, spriteNum); -} - -/* we should return -1 if it isn't gold, otherwise return the gold value */ -int Interface::CanMoveItem(const CREItem *item) const -{ - //This is an inventory slot, switch to IE_ITEM_* if you use Item - if (!HasFeature(GF_NO_DROP_CAN_MOVE) ) { - if (item->Flags & IE_INV_ITEM_UNDROPPABLE) - return 0; - } - //not gold, we allow only one single coin ResRef, this is good - //for all of the original games - if (strnicmp(item->ItemResRef, GoldResRef, 8 ) ) - return -1; - //gold, returns the gold value (stack size) - return item->Usages[0]; -} - -// dealing with applying effects -void Interface::ApplySpell(const ieResRef resname, Actor *actor, Scriptable *caster, int level) -{ - Spell *spell = gamedata->GetSpell(resname); - if (!spell) { - return; - } - - int header = spell->GetHeaderIndexFromLevel(level); - EffectQueue *fxqueue = spell->GetEffectBlock(caster, actor->Pos, header, level); - - ApplyEffectQueue(fxqueue, actor, caster, actor->Pos); - delete fxqueue; -} - -void Interface::ApplySpellPoint(const ieResRef resname, Map* area, const Point &pos, Scriptable *caster, int level) -{ - Spell *spell = gamedata->GetSpell(resname); - if (!spell) { - return; - } - int header = spell->GetHeaderIndexFromLevel(level); - Projectile *pro = spell->GetProjectile(caster, header, pos); - pro->SetCaster(caster->GetGlobalID(), level); - area->AddProjectile(pro, caster->Pos, pos); -} - -//-1 means the effect was reflected back to the caster -//0 means the effect was resisted and should be removed -//1 means the effect was applied -int Interface::ApplyEffect(Effect *effect, Actor *actor, Scriptable *caster) -{ - if (!effect) { - return 0; - } - - EffectQueue *fxqueue = new EffectQueue(); - //AddEffect now copies the fx data, please delete your effect reference - //if you created it. (Don't delete cached references) - fxqueue->AddEffect( effect ); - int res = ApplyEffectQueue(fxqueue, actor, caster); - delete fxqueue; - return res; -} - -int Interface::ApplyEffectQueue(EffectQueue *fxqueue, Actor *actor, Scriptable *caster) -{ - Point p; - p.empty(); //the effect should have all its coordinates already set - return ApplyEffectQueue(fxqueue, actor, caster, p); -} - -int Interface::ApplyEffectQueue(EffectQueue *fxqueue, Actor *actor, Scriptable *caster, Point p) -{ - int res = fxqueue->CheckImmunity ( actor ); - if (res) { - if (res == -1 ) { - //bounced back at a nonliving caster - if (caster->Type!=ST_ACTOR) { - return 0; - } - actor = (Actor *) caster; - } - fxqueue->SetOwner( caster ); - - if (fxqueue->AddAllEffects( actor, p)==FX_NOT_APPLIED) { - res=0; - } - } - return res; -} - -Effect *Interface::GetEffect(const ieResRef resname, int level, const Point &p) -{ - //Don't free this reference, it is cached! - Effect *effect = gamedata->GetEffect(resname); - if (!effect) { - return NULL; - } - if (!level) { - level = 1; - } - effect->Power = level; - effect->PosX=p.x; - effect->PosY=p.y; - return effect; -} - -// dealing with saved games -int Interface::SwapoutArea(Map *map) -{ - PluginHolder mm(IE_ARE_CLASS_ID); - if (mm == NULL) { - return -1; - } - int size = mm->GetStoredFileSize (map); - if (size > 0) { - //created streams are always autofree (close file on destruct) - //this one will be destructed when we return from here - FileStream str; - - str.Create( map->GetScriptName(), IE_ARE_CLASS_ID ); - int ret = mm->PutArea (&str, map); - if (ret <0) { - printMessage("Core", "Area removed: %s\n", YELLOW, - map->GetScriptName()); - RemoveFromCache(map->GetScriptName(), IE_ARE_CLASS_ID); - } - } else { - printMessage("Core", "Area removed: %s\n", YELLOW, - map->GetScriptName()); - RemoveFromCache(map->GetScriptName(), IE_ARE_CLASS_ID); - } - //make sure the stream isn't connected to sm, or it will be double freed - return 0; -} - -int Interface::WriteCharacter(const char *name, Actor *actor) -{ - char Path[_MAX_PATH]; - - PathJoin( Path, GamePath, GameCharactersPath, NULL ); - if (!actor) { - return -1; - } - PluginHolder gm(IE_CRE_CLASS_ID); - if (gm == NULL) { - return -1; - } - - //str is freed - { - FileStream str; - - if (!str.Create( Path, name, IE_CHR_CLASS_ID )) - return -1; - - int ret = gm->PutActor(&str, actor, true); - if (ret <0) { - printMessage("Core", "Character cannot be saved: %s\n", YELLOW, name); - return -1; - } - } - - //write the BIO string - if (!HasFeature(GF_NO_BIOGRAPHY)) { - FileStream str; - - str.Create( Path, name, IE_BIO_CLASS_ID ); - //never write the string reference into this string - char *tmp = GetString(actor->GetVerbalConstant(VB_BIO),IE_STR_STRREFOFF); - str.Write (tmp, strlen(tmp)); - free(tmp); - } - return 0; -} - -int Interface::WriteGame(const char *folder) -{ - PluginHolder gm(IE_GAM_CLASS_ID); - if (gm == NULL) { - return -1; - } - - int size = gm->GetStoredFileSize (game); - if (size > 0) { - //created streams are always autofree (close file on destruct) - //this one will be destructed when we return from here - FileStream str; - - str.Create( folder, GameNameResRef, IE_GAM_CLASS_ID ); - int ret = gm->PutGame (&str, game); - if (ret <0) { - printMessage("Core", "Game cannot be saved: %s\n", YELLOW, folder); - return -1; - } - } else { - printMessage("Core", "Internal error, game cannot be saved: %s\n", YELLOW, folder); - return -1; - } - return 0; -} - -int Interface::WriteWorldMap(const char *folder) -{ - PluginHolder wmm(IE_WMP_CLASS_ID); - if (wmm == NULL) { - return -1; - } - - if (WorldMapName[1][0]) { - worldmap->SetSingle(false); - } - - int size1 = wmm->GetStoredFileSize (worldmap, 0); - int size2 = 1; //just a dummy value - - //if size is 0 for the first worldmap, then there is a problem - if (!worldmap->IsSingle() && (size1>0) ) { - size2=wmm->GetStoredFileSize (worldmap, 1); - } - - int ret = 0; - if ((size1 < 0) || (size2<0) ) { - ret=-1; - } else { - //created streams are always autofree (close file on destruct) - //this one will be destructed when we return from here - FileStream str1; - FileStream str2; - - str1.Create( folder, WorldMapName[0], IE_WMP_CLASS_ID ); - if (!worldmap->IsSingle()) { - str2.Create( folder, WorldMapName[1], IE_WMP_CLASS_ID ); - } - ret = wmm->PutWorldMap (&str1, &str2, worldmap); - } - if (ret <0) { - printMessage("Core", "Internal error, worldmap cannot be saved: %s\n", YELLOW, folder); - return -1; - } - return 0; -} - -int Interface::CompressSave(const char *folder) -{ - FileStream str; - - str.Create( folder, GameNameResRef, IE_SAV_CLASS_ID ); - DirectoryIterator dir(CachePath); - if (!dir) { - return -1; - } - PluginHolder ai(IE_SAV_CLASS_ID); - ai->CreateArchive( &str); - - //.tot and .toh should be saved last, because they are updated when an .are is saved - int priority=2; - while(priority) { - do { - const char *name = dir.GetName(); - if (dir.IsDirectory()) - continue; - if (name[0] == '.') - continue; - if (SavedExtension(name)==priority) { - char dtmp[_MAX_PATH]; - dir.GetFullPath(dtmp); - FileStream fs; - fs.Open(dtmp); - ai->AddToSaveGame(&str, &fs); - } - } while (++dir); - //reopen list for the second round - priority--; - if (priority>0) { - dir.Rewind(); - } - } - return 0; -} - -int Interface::GetMaximumAbility() const { return MaximumAbility; } - -int Interface::GetStrengthBonus(int column, int value, int ex) const -{ - //to hit, damage, open doors, weight allowance - if (column<0 || column>3) - return -9999; - - if (value<0) - value = 0; - else if (value>25) - value = 25; - - if (ex<0) - ex=0; - else if (ex>100) - ex=100; - - return strmod[column*(MaximumAbility+1)+value]+strmodex[column*101+ex]; -} - -//The maze columns are used only in the maze spell, no need to restrict them further -int Interface::GetIntelligenceBonus(int column, int value) const -{ - //learn spell, max spell level, max spell number on level, maze duration dice, maze duration dice size - if (column<0 || column>4) return -9999; - - return intmod[column*(MaximumAbility+1)+value]; -} - -int Interface::GetDexterityBonus(int column, int value) const -{ - //no dexmod in iwd2 and only one type of modifier - if (HasFeature(GF_3ED_RULES)) { - return (value-10)/2; - } - - //reaction, missile, ac - if (column<0 || column>2) - return -9999; - - return dexmod[column*(MaximumAbility+1)+value]; -} - -int Interface::GetConstitutionBonus(int column, int value) const -{ - //no conmod in iwd2 - if (HasFeature(GF_3ED_RULES)) { - return (value-10)/2; - } - - //normal, warrior, minimum, regen hp, regen fatigue - if (column<0 || column>4) - return -9999; - - return conmod[column*(MaximumAbility+1)+value]; -} - -int Interface::GetCharismaBonus(int column, int /*value*/) const -{ - // store price reduction - if (column<0 || column>(MaximumAbility-1)) - return -9999; - - return chrmod[column]; -} - -int Interface::GetLoreBonus(int column, int value) const -{ - //no lorebon in iwd2 - lore is a skill - if (HasFeature(GF_3ED_RULES)) return 0; - - if (column<0 || column>0) - return -9999; - - return lorebon[value]; -} - -int Interface::GetWisdomBonus(int column, int value) const -{ - //no wismod in iwd2 - if (HasFeature(GF_3ED_RULES)) { - return (value-10)/2; - } - - if (!HasFeature(GF_WISDOM_BONUS)) return 0; - - // xp bonus - if (column<0 || column>0) - return -9999; - - return wisbon[value]; -} - -int Interface::GetReputationMod(int column) const -{ - int reputation = game->Reputation / 10 - 1; - - if (column<0 || column>8) { - return -9999; - } - if (reputation > 19) { - reputation = 19; - } - if (reputation < 0) { - reputation = 0; - } - - return reputationmod[reputation][column]; -} - -// -3, -2 if request is illegal or in cutscene -// -1 if pause is already active -// 0 if pause was not allowed -// 1 if autopause happened -int Interface::Autopause(ieDword flag) -{ - GameControl *gc = GetGameControl(); - if (!gc) { - return -3; - } - if (InCutSceneMode()) { - return -2; - } - if (gc->GetDialogueFlags()&DF_FREEZE_SCRIPTS) { - return -1; - } - ieDword autopause_flags = 0; - - vars->Lookup("Auto Pause State", autopause_flags); - if (autopause_flags & (1<DisplayConstantString(STR_AP_UNUSABLE+flag, 0xff0000); - gc->SetDialogueFlags(DF_FREEZE_SCRIPTS, BM_OR); - return 1; - } - return 0; -} - -void Interface::RegisterOpcodes(int count, const EffectDesc *opcodes) -{ - EffectQueue_RegisterOpcodes(count, opcodes); -} - -void Interface::SetInfoTextColor(const Color &color) -{ - if (InfoTextPalette) { - gamedata->FreePalette(InfoTextPalette); - } - InfoTextPalette = CreatePalette(color, black); -} - -//todo row? -void Interface::GetResRefFrom2DA(const ieResRef resref, ieResRef resource1, ieResRef resource2, ieResRef resource3) -{ - if (!resource1) { - return; - } - resource1[0]=0; - if (resource2) { - resource2[0]=0; - } - if (resource3) { - resource3[0]=0; - } - AutoTable tab(resref); - if (tab) { - unsigned int cols = tab->GetColumnCount(); - unsigned int row = (unsigned int) Roll(1,tab->GetRowCount(),-1); - strnuprcpy(resource1, tab->QueryField(row,0), 8); - if (resource2 && cols>1) - strnuprcpy(resource2, tab->QueryField(row,1), 8); - if (resource3 && cols>2) - strnuprcpy(resource3, tab->QueryField(row,2), 8); - } -} - -ieDword *Interface::GetListFrom2DAInternal(const ieResRef resref) -{ - ieDword *ret; - - AutoTable tab(resref); - if (tab) { - ieDword cnt = tab->GetRowCount(); - ret = (ieDword *) malloc((1+cnt)*sizeof(ieDword)); - ret[0]=cnt; - while(cnt) { - ret[cnt]=strtol(tab->QueryField(cnt-1, 0),NULL, 0); - cnt--; - } - return ret; - } - ret = (ieDword *) malloc(sizeof(ieDword)); - ret[0]=0; - return ret; -} - -ieDword* Interface::GetListFrom2DA(const ieResRef tablename) -{ - ieDword *list; - - if (!lists->Lookup(tablename, (void *&) list)) { - list = GetListFrom2DAInternal(tablename); - lists->SetAt(tablename, list); - } - - return list; -} - -//returns a numeric value associated with a stat name (symbol) from stats.ids -ieDword Interface::TranslateStat(const char *stat_name) -{ - long tmp; - - if (valid_number(stat_name, tmp)) { - return (ieDword) tmp; - } - - int symbol = LoadSymbol( "stats" ); - Holder sym = GetSymbol( symbol ); - ieDword stat = (ieDword) sym->GetValue( stat_name ); - if (stat==(ieDword) ~0) { - printMessage("Core", "Cannot translate symbol: %s\n", YELLOW, stat_name); - } - return stat; -} - -void Interface::WaitForDisc(int disc_number, const char* path) -{ - GetDictionary()->SetAt( "WaitForDisc", (ieDword) disc_number ); - - GetGUIScriptEngine()->RunFunction( "GUICommonWindows", "OpenWaitForDiscWindow" ); - do { - DrawWindows(); - for (size_t i=0;iRunFunction( "GUICommonWindows", "OpenWaitForDiscWindow" ); - return; - } - } - - } while (video->SwapBuffers() == GEM_OK); -} - -// remove the extraneus EOL newline and carriage return -void Interface::StripLine(char * string, size_t size) { - if (size >= 2 && string[size-2] == '\n') { - string[size-2] = '\0'; - } - if (size >= 3 && string[size-3] == '\r') { - string[size-3] = '\0'; // remove the carriage return too - } -} - -void Interface::SetTickHook(EventHandler hook) -{ - TickHook = hook; -} - -void Interface::SetNextScript(const char *script) -{ - strncpy( NextScript, script, sizeof(NextScript) ); - QuitFlag |= QF_CHANGESCRIPT; -} - -void Interface::SanityCheck(const char *ver) { - if (strcmp(ver, VERSION_GEMRB)) { - error("Core", "version check failed: core version %s doesn't match caller's version %s\n", VERSION_GEMRB, ver); - } -} diff --git a/project/jni/application/gemrb/gemrb/core/Interface.h b/project/jni/application/gemrb/gemrb/core/Interface.h deleted file mode 100644 index f8d86189f..000000000 --- a/project/jni/application/gemrb/gemrb/core/Interface.h +++ /dev/null @@ -1,807 +0,0 @@ -/* GemRB - Infinity Engine Emulator - * Copyright (C) 2003 The GemRB Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - */ - -/** - * @file Interface.h - * Declaration of Interface class, central interconnect for various GemRB parts - */ - -#ifndef INTERFACE_H -#define INTERFACE_H - -#include "SClassID.h" -#include "exports.h" - -#include "Cache.h" -#include "Callback.h" -#include "Holder.h" - -#include -#include -#include - -#ifdef _MSC_VER // No SFINAE -#include "Audio.h" -#include "DataFileMgr.h" -#include "MusicMgr.h" -#include "SaveGame.h" -#include "ScriptEngine.h" -#include "StringMgr.h" -#include "SymbolMgr.h" -#include "Video.h" -#include "WindowMgr.h" -#endif - -class Actor; -class Audio; -class CREItem; -class Calendar; -class Console; -class Container; -class Control; -class DataFileMgr; -struct Effect; -class EffectQueue; -struct EffectDesc; -class EventMgr; -class Factory; -class Font; -class Game; -class GameControl; -class GlobalTimer; -class ITMExtHeader; -class Image; -class Item; -class KeyMap; -class Label; -class Map; -class MusicMgr; -class Palette; -class ProjectileServer; -class Resource; -class SPLExtHeader; -class SaveGame; -class SaveGameIterator; -class ScriptEngine; -class ScriptedAnimation; -class Spell; -class Sprite2D; -class Store; -class StringMgr; -class SymbolMgr; -class TableMgr; -class TextArea; -class Variables; -class Video; -class Window; -class WindowMgr; -class WorldMap; -class WorldMapArray; - -struct Symbol { - Holder sm; - char ResRef[8]; -}; - -struct SlotType { - ieDword slot; - ieDword slottype; - ieDword slottip; - ieDword slotid; - ieDword sloteffects; - ieDword slotflags; - ieResRef slotresref; -}; - -struct DamageInfoStruct { - unsigned int strref; - unsigned int resist_stat; - unsigned int value; - int iwd_mod_type; - // maybe also add the ac bonus and/or the DL_ constants -}; - -struct ModalStatesStruct { - ieResRef spell; - char action[16]; - unsigned int entering_str; - unsigned int leaving_str; - unsigned int failed_str; - bool aoe_spell; -}; - -struct TimeStruct { - unsigned int round_sec; - unsigned int turn_sec; - unsigned int round_size; // in ticks - unsigned int rounds_per_turn; -}; - -struct SpellDescType { - ieResRef resref; - ieStrRef value; -}; -#define SP_IDENTIFY 1 //any spell that cannot be cast from the menu -#define SP_SILENCE 2 //any spell that can be cast in silence - -struct SurgeSpell { - ieResRef spell; - ieStrRef message; -}; - -class ItemList { -public: - ieResRef *ResRefs; - unsigned int Count; - //if count is odd and the column titles start with 2, the random roll should be 2d((c+1)/2)-1 - bool WeightOdds; - - ItemList(unsigned int size, int label) { - ResRefs = (ieResRef *) calloc(size, sizeof(ieResRef) ); - Count = size; - if ((size&1) && (label==2)) { - WeightOdds=true; - } else { - WeightOdds=false; - } - } - ~ItemList() { - if (ResRefs) { - free(ResRefs); - } - } -}; - -// Colors of modal window shadow -// !!! Keep these synchronized with GUIDefines.py !!! -#define MODAL_SHADOW_NONE 0 -#define MODAL_SHADOW_GRAY 1 -#define MODAL_SHADOW_BLACK 2 - -#define WINDOW_INVALID -1 -#define WINDOW_INVISIBLE 0 -#define WINDOW_VISIBLE 1 -#define WINDOW_GRAYED 2 -#define WINDOW_FRONT 3 - -//quitflags -#define QF_NORMAL 0 -#define QF_QUITGAME 1 -#define QF_EXITGAME 2 -#define QF_CHANGESCRIPT 4 -#define QF_LOADGAME 8 -#define QF_ENTERGAME 16 - -//events that are called out of drawwindow -//they wait until the condition is right -#define EF_CONTROL 1 //updates the game window statuses -#define EF_SHOWMAP 2 //starts worldmap -#define EF_PORTRAIT 4 //updates portraits -#define EF_ACTION 8 //updates the actions bar -#define EF_UPDATEANIM 16 //updates avatar animation -#define EF_SEQUENCER 32 //starts sequencer/contingency creation -#define EF_IDENTIFY 64 //starts identify screen -#define EF_SELECTION 128 //selection changed -#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 -#define AP_ATTACKED 1 -#define AP_HIT 2 -#define AP_WOUNDED 3 -#define AP_DEAD 4 -#define AP_NOTARGET 5 -#define AP_ENDROUND 6 -#define AP_ENEMY 7 -#define AP_TRAP 8 -#define AP_SPELLCAST 9 - -/** ea relations (derivated from 2 actor's EA value) */ -#define EAR_FRIEND 0 -#define EAR_NEUTRAL 1 -#define EAR_HOSTILE 2 - -/** Max size of actor's ground circle (PST) */ -#define MAX_CIRCLE_SIZE 3 - -/** Summoning */ -#define EAM_SOURCEALLY 0 -#define EAM_SOURCEENEMY 1 -#define EAM_ENEMY 2 -#define EAM_ALLY 3 -#define EAM_NEUTRAL 4 -#define EAM_DEFAULT 5 -// -#define STAT_CON_HP_NORMAL 0 -#define STAT_CON_HP_WARRIOR 1 -#define STAT_CON_HP_MIN 2 -#define STAT_CON_HP_REGEN 3 -#define STAT_CON_FATIGUE 4 - -#define STAT_DEX_REACTION 0 -#define STAT_DEX_MISSILE 1 -#define STAT_DEX_AC 2 - -#define STAT_INT_LEARN 0 -#define STAT_INT_MAXLEVEL 1 -#define STAT_INT_MAXNUMBER 2 - -//sloteffects (querysloteffect returns it) -#define SLOT_EFFECT_NONE 0 -#define SLOT_EFFECT_ITEM 1 //normal equipped item -#define SLOT_EFFECT_FIST 2 //fist slot -#define SLOT_EFFECT_MAGIC 3 //magic weapon slot -#define SLOT_EFFECT_MELEE 4 //normal weapon slot -#define SLOT_EFFECT_MISSILE 5 //quiver slots -#define SLOT_EFFECT_LEFT 6 //shield (left hand) slot -#define SLOT_EFFECT_HEAD 7 //head slot - -//fog of war bits -#define FOG_DRAWFOG 1 -#define FOG_DRAWSEARCHMAP 2 -#define FOG_DITHERSPRITES 4 - -enum PluginFlagsType { - PLF_NORMAL, - PLF_SKIP, - PLF_DELAY -}; - -/** - * @class Interface - * Central interconnect for all GemRB parts, driving functions and utility functions possibly belonging to a better place - */ - -class GEM_EXPORT Interface -{ -private: - Holder