/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 TITANIC_TT_NPC_SCRIPT_H #define TITANIC_TT_NPC_SCRIPT_H #include "titanic/support/simple_file.h" #include "titanic/true_talk/tt_script_base.h" #include "titanic/true_talk/script_support.h" namespace Titanic { #define DIALS_ARRAY_COUNT 10 class CGameManager; class CPetControl; class TTroomScript; struct TTnpcData { private: int _array[136]; public: TTnpcData(); int &operator[](int idx) { return _array[idx]; } int *getSlot(int idx) { return &_array[16 + idx * 4]; } void resetFlags(); }; class TTnpcScriptBase : public TTscriptBase { protected: int _field54; int _val2; public: int _charId; public: TTnpcScriptBase(int charId, const char *charClass, int v2, const char *charName, int v3, int val2, int v4, int v5, int v6, int v7); /** * Chooses and adds a conversation response based on a specified tag Id. */ virtual int chooseResponse(const TTroomScript *roomScript, const TTsentence *sentence, uint tag) = 0; /** * Does NPC specific processing of the parsed sentence */ virtual int process(const TTroomScript *roomScript, const TTsentence *sentence) = 0; virtual int proc8() const = 0; /** * Called when the script/id changes */ virtual ScriptChangedResult scriptChanged(uint id) = 0; /** * Called when the script/id changes */ virtual ScriptChangedResult scriptChanged(const TTroomScript *roomScript, uint id) = 0; virtual int proc11() const = 0; virtual int proc12() const = 0; int charId() const { return _charId; } }; class TTnpcScript : public TTnpcScriptBase { private: int translateByArray(int id); protected: static TTsentenceEntries *_defaultEntries; protected: Common::Array _responses; int _valuesPerResponse; Common::Array _ranges; TTscriptMappings _mappings; TTsentenceEntries _entries; TTtagMappings _tagMappings; TTwordEntries _words; TThandleQuoteEntries _quotes; int _entryCount; int _field68; int _field6C; int _rangeResetCtr; int _currentDialNum; int _dialDelta; int _field7C; const char *_itemStringP; int _dialValues[DIALS_ARRAY_COUNT]; TTnpcData _data; bool _field2CC; protected: /** * Loads response data for the NPC from the given resource */ void loadResponses(const char *name, int valuesPerResponse = 1); /** * Load ranges data for the NPC from the given resource */ void loadRanges(const char *name); /** * Reset script flags */ void resetFlags(); /** * Setup dials */ void setupDials(int dial1, int dial2, int dial3); static int getRoom54(int roomId); /** * Perform test on various state values */ int getValue(int testNum) const; /** * Gets a random number between 1 and a given max */ uint getRandomNumber(int max) const; /** * Gets a random number of 0 or 1 */ uint getRandomBit() const { return getRandomNumber(2) - 1; } /** * Returns a dialogue Id by script tag value Id */ uint getDialogueId(uint tagId); /** * Returns a pointer to the PET control */ static CPetControl *getPetControl(CGameManager *gameManager); /** * Adds a new item to the list of number ranges */ void addRange(uint id, const Common::Array &values, bool isRandom, bool isSequential); /** * Finds an entry in the list of prevoiusly registered number ranges */ TTscriptRange *findRange(uint id); /** * Scans through a list of sentence entries for a matching standardized response */ int processEntries(const TTsentenceEntries *entries, uint entryCount, const TTroomScript *roomScript, const TTsentence *sentence); /** * Scans through a list of sentence entries for a matching standardized response */ int processEntries(const TTroomScript *roomScript, const TTsentence *sentence) { return processEntries(&_entries, _entryCount, roomScript, sentence); } bool defaultProcess(const TTroomScript *roomScript, const TTsentence *sentence); void checkItems(const TTroomScript *roomScript, const TTsentence *sentence); /** * Adds a random conversation response */ bool addRandomResponse(bool flag); /** * Updates the current dial with the given delta */ void updateCurrentDial(bool changeDial); bool fn10(bool flag); static bool sentence2C(const TTsentence *sentence); /** * Gets the True Talk state value */ bool getStateValue() const; /** * Gets the assigned room's room, floor, and elevator number */ void getAssignedRoom(int *roomNum, int *floorNum, int *elevatorNum) const; /** * Uses a porition of the state _array to set up a new response */ void setResponseFromArray(int index, int id); public: static void init(); static void deinit(); public: TTnpcScript(int charId, const char *charClass, int v2, const char *charName, int v3, int val2, int v4, int v5, int v6, int v7); virtual void addResponse(int id); /** * Chooses and adds a conversation response based on a specified tag Id. * This default implementation does a lookup into a list of known tags, * and chooses a random dialogue Id from the available ones for that tag */ virtual int chooseResponse(const TTroomScript *roomScript, const TTsentence *sentence, uint tag); /** * Does NPC specific processing of the parsed sentence */ virtual int process(const TTroomScript *roomScript, const TTsentence *sentence); virtual int proc8() const; /** * Called when the script/id changes */ virtual ScriptChangedResult scriptChanged(uint id) { return SCR_2; } /** * Called when the script/id changes */ virtual ScriptChangedResult scriptChanged(const TTroomScript *roomScript, uint id) { return SCR_2; } virtual int proc11() const; virtual int proc12() const; /** * Translate a passed Id to a dialogue Id if necessary, * and adds it to the response */ virtual void selectResponse(int id); /** * Handles scanning the word list for a given Id, and if * found adds it to the sentence concept list */ virtual bool handleWord(uint id) const; virtual int handleQuote(const TTroomScript *roomScript, const TTsentence *sentence, uint val, uint tagId, uint remainder); /** * Given an Id for a previously registered set of random number values, * picks one of the array values and returns it.. depending on flags, * either a random value, or each value in turn */ virtual uint getRangeValue(uint id); /** * Resets the prior used index for the specified range */ virtual void resetRange(int id); /** * Handles updating NPC state based on specified dialogue Ids and dial positions */ virtual int updateState(uint oldId, uint newId, int index); /** * Handles getting a pre-response */ virtual int preResponse(uint id); /** * Returns a bitset of the dials being off or not */ virtual uint getDialsBitset() const { return 0; } virtual const TTscriptMapping *getMapping(int index); virtual int doSentenceEntry(int val1, const int *srcIdP, const TTroomScript *roomScript, const TTsentence *sentence); /** * Handles any post-response NPC processing */ virtual void postResponse(int v1, const TTsentenceEntry *entry, const TTroomScript *roomScript, const TTsentence *sentence) {} virtual void save(SimpleFile *file); virtual void load(SimpleFile *file); virtual void saveBody(SimpleFile *file); virtual void loadBody(SimpleFile *file); virtual int proc31() const; /** * Sets a given dial to be pointing in a specified region (0 to 2) */ virtual void setDialRegion(int dialNum, int region); /** * Sets the value for an NPC's dial */ virtual void setDial(int dialNum, int value); /** * Returns a dial's region number */ virtual int getDialRegion(int dialNum) const; /** * Gets the value for a dial * @param dialNum Dial number * @param randomizeFlag If set, introduces a slight random variance so that * the displayed dial will oscillate randomly around it's real level */ virtual int getDialLevel(uint dialNum, bool randomizeFlag = true); /** * Handles a randomzied response */ virtual bool randomResponse(uint index); virtual uint translateId(uint id) const; void preLoad(); /** * Called with the script and id changes */ ScriptChangedResult notifyScript(TTroomScript *roomScript, int id) { return scriptChanged(roomScript, id); } }; } // End of namespace Titanic #endif /* TITANIC_TT_NPC_SCRIPT_H */