/* * workmanager.h * * Copyright (C) 2001-2002 Atomic Blue (info@planeshift.it, http://www.atomicblue.org) * * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation (version 2 of the License) * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #ifndef __WORKMANAGER_H__ #define __WORKMANAGER_H__ #include "msgmanager.h" // Parent class #include "net/messages.h" // Message definitions #include "net/msghandler.h" // Network access #include #include "gem.h" class psWorkGameEvent; class psWorkManager; class psItem; class Client; // Define the work event types #define MANUFACTURE 0 // Digging, collecting, farming #define PRODUCTION 1 // Crafting #define LOCKPICKING 2 // Picking of locks #define CLEANUP 3 // Cleaning up of public containers #define REPAIR 4 // Repairing items takes time too #define GARBAGE_PATTERNID 1 // Define for hard coded pattern IDs #define CLEANUP_DELAY 600 // Seconds to wait before performing cleanup event //#define CLEANUP_DELAY 10 // for testing only /** Holds the possible return values for a test to see if an item is transformable. This is binary since each transform atempt could have multiple reasons for failure */ enum TradePatternMatch { TRANSFORM_MATCH = 0x0000, ///< There was a transform that matched correctly TRANSFORM_UNKNOWN_PATTERN = 0x0001, ///< There was no pattern found TRANSFORM_UNKNOWN_ITEM = 0x0002, ///< Item is not used with any available transform. TRANSFORM_MISSING_ITEM = 0x0004, ///< No item found to use with work item. TRANSFORM_UNKNOWN_WORKITEM = 0x0008, ///< No work item container choosen. TRANSFORM_MISSING_EQUIPMENT = 0x0010, ///< Transform found but not correct equipment TRANSFORM_BAD_TRAINING = 0x0020, ///< Did not meet required skills. TRANSFORM_BAD_SKILLS = 0x0040, ///< Did not meet required skills. TRANSFORM_OVER_SKILLED = 0x0080, ///< Over skilled for this task. TRANSFORM_FAILED_CONSTRAINTS = 0x0100, ///< Failed one or more contstraints on the transform TRANSFORM_BAD_QUANTITY = 0x0200, ///< Item was ok for transform but quantity was not. TRANSFORM_BAD_COMBINATION = 0x0400, ///< Combination items or ammounts not correct. TRANSFORM_TOO_MANY_ITEMS = 0x0800, ///< Tried to transform too many items. TRANSFORM_BAD_USE = 0x1000, ///< Use of item or ammounts not correct. TRANSFORM_NO_STAMINA = 0x2000, ///< Too tired to do trade skill work. TRANSFORM_spare = 0x4000, ///< Spare transform result type TRANSFORM_GARBAGE = 0x8000 ///< There was a any item garbage transform that matched correctly }; /** Holds the possible transformation types. */ enum TradeTransfomType { TRANSFORMTYPE_UNKNOWN=0, ///< A unknown tranformation TRANSFORMTYPE_AUTO_CONTAINER, ///< Transforming an item by putting it into auto-transform container TRANSFORMTYPE_SLOT, ///< Transforming an item in an equiped slot TRANSFORMTYPE_CONTAINER, ///< Transforming an item that is in a container TRANSFORMTYPE_SLOT_CONTAINER ///< Transforming an item that is in a container in an equiped slot }; //----------------------------------------------------------------------------- /** This class keeps natural resource concentrations across the world. */ struct NaturalResource { int sector; ///< The id of the sector this resource is in. csVector3 loc; ///< Centre point of resource location. float radius; ///< Radius around the centre where resource can be found. float visible_radius; float probability; ///< Probability of finding resource on attempt. psSkillInfo *skill; ///< Skill used to harvest resource. int skill_level; ///< Skill level required to be able to harvest resource. unsigned int item_cat_id; float item_quality; csString anim; ///< Name of animation to play while harvesting int anim_duration_seconds; ///< Length of time the animation should play. int reward; csString reward_nickname; }; //----------------------------------------------------------------------------- struct constraint { bool (*constraintFunction)(psWorkManager* that, char* param); char* name; char* message; }; //----------------------------------------------------------------------------- /** This class handles all calculations around work, using statistics * and information from the pspccharacterinfo Prop Classes for both * the worker and the target. */ class psWorkManager : public MessageManager { protected: csPDelArray resources; /// list of all natural resources in game. MathScriptEngine *script_engine; /// Scripting engine handles all RPG calculations. MathScript *calc_repair_time; /// This is the calculation for how long a repair takes. MathScript *calc_repair_result; /// This is the calculation for how many points of quality are added in a repair. MathScriptVar *var_time_Worker; /// Variable representing worker in time calculation MathScriptVar *var_time_Object; /// Variable representing the repaired object in time calculation MathScriptVar *var_time_Result; /// Variable representing the answer in time calculation MathScriptVar *var_result_Worker; /// Variable representing worker in result calculation MathScriptVar *var_result_Object; /// Variable representing the repaired object in result calculation MathScriptVar *var_result_Result; /// Variable representing the answer in result calculation public: psWorkManager(); virtual ~psWorkManager(); virtual void HandleMessage(MsgEntry *me, Client *client); //----------------------------------------------------------------------------- // Entry points //----------------------------------------------------------------------------- /** Handles using an item for working. This is called when an item * is tagetted and the use command issued. * * @param client The client that placed the item inside */ void HandleUse(Client *client); /** Start Combine work * This gets called when the player tries to combine items in a container using /combine command. * * @param client The client that placed the item inside */ void HandleCombine(Client *client); /** Start a work event for this client. This is called when an item is placed * in a container. If the container is an auto-transform container it can transform items * automatically ( ie placing items in automatically triggers the transformation process to start ). * * @param client The client that placed the item inside * @param container The work item container that can transform an item. * @param autoItem The item that was placed inside and to be transformed. * @param count The stack count of the item placed in. */ void StartAutoWork(Client *client, psItem* container, psItem *autoItem, int count); /** Stop work event. * This is called when a client removes an item from a container. * * @param client The client that removed the item. * @param item The item that was being transformed. */ void StopWork(Client *client, psItem *item); //----------------------------------------------------------------------------- /** Stop auto work event. * This is called when a client removes an item from any container * before it has had a chance to transform the item. * * @param client The client that removed the item. * @param autoItem The item that was being transformed. */ void StopAutoWork(Client *client, psItem *autoItem); /** @name Work Event Handlers * These are the functions fired when a psWorkGameEvent is Triggered. */ //@{ /** Handles a transformation/combination event. Basically the manufacturing events. * * @param event The work event that was in the queue to fire. */ void HandleWorkEvent(psWorkGameEvent* workEvent); /** Handles a cleanup event. Basically removing discarded items from public containers. * * @param event The work event that was in the queue to fire. */ void HandleCleanupEvent(psWorkGameEvent* workEvent); /** Handles a resource/harvesting event. Basically the production events. * * @param event The work event that was in the queue to fire. */ void HandleProductionEvent(psWorkGameEvent* workEvent); /** Handles a repair event, which occurs after a few seconds of repairing an item. * * @param event The work event that was in the queue to fire. */ void HandleRepairEvent(psWorkGameEvent* workEvent); void LockpickComplete(psWorkGameEvent* workEvent); //@} /** @name Constraint Functions * */ //@{ static bool constraintTime(psWorkManager* that, char* param); static bool constraintFriends(psWorkManager* that,char* param); static bool constraintLocation(psWorkManager* that,char* param); static bool constraintMode(psWorkManager* that,char* param); //@} csWeakRef worker; ///< Current worker that the work manager is dealing with. // int workerCID; ///< Current worker ID uint32_t clientNum; ///< Current client the work manager is dealing with. psItem* workItem; ///< The current work item that is in use ( example, ore furnace ) psItem* autoItem; ///< The current item that is being transformed by auto-transformation container psCharacter *owner; ///< The character data of the current character being used. uint32 patternId; ///< Current pattern ID uint32 groupPatternId; ///< Current group pattern ID float patternKFactor; ///< Pattern factor that's part of quality calculation float currentQuality; ///< Current result item quality psTradeTransformations* trans; ///< Current work transformation psTradeProcesses* process; ///< Current work process const char* preworkModeString; ///< Mode string prior to work // Lockpicking void StartLockpick(Client* client,psItem* item); /** Sets up the internal structure of the work manager to handle a particular client. * This sets many variables of the workmanager to work with a single user at a time. * * @param client The client that is the current one to use. * * @return False if there is a problem loading stuff. */ bool LoadLocalVars(Client* client); /** Send clear client view message to remove items from autocontainers. * * @param slotID The slot number to clear. * @param containerID The container ID that has item that needs to be cleared. * * @return False if there is a problem sending message. */ bool SendClearUpdate( unsigned int slotID, unsigned int containerID ); protected: /** Handles stopping the use of the item for working. This is called when an item * is tagetted and the /use command issued and it's already in use. * * @param client The client that issues the /use command */ void StopUseWork(Client *client); /** Checks to see if the item can be used for working. * * @param client The client that issues the /use command */ void StartUseWork(Client *client); /** Handles stopping the combining in the work container. This is called when an item * is tagetted and the /combine command issued and it's already in use. * * @param client The client that issues the /combine command */ void StopCombineWork(Client *client); /** Checks to see if the work container item can be used for combining. * * @param client The client that issues the /combine command */ void StartCombineWork(Client *client); /** Handles stopping the cleanup event for a particular item. This is called when an item * is removed from a container. * * @param client The client that removes the item * @param cleanItem The item that is removed */ void StopCleanupWork(Client* client, psItem* cleanItem); /** Sends an error message to the client based on the trade pattern error. * @see TradePatternMatch for the list of error conditions. * @param clientNum the client to send the message to. * @param result The error code from the transformable test. */ void SendTransformError( uint32 clientNum, int result, uint32 curItemId = 0, int CurItemQty = 0 ); /** Returns with the result ID and quantity of the combination * if work item container has the correct items in the correct amounts * Note: This assumes that the combination items array is sorted by * resultId and then itemId * * @return resultID The item ID of the resulting item. * @return resultQty The stack quantity of the resulting item. * * @return False if combination is not possible. */ bool IsContainerCombinable(uint32 &resultId, int &resultQty); /** Returns with the result ID and quantity of the combination * if player has the correct items in the correct amounts in hand * Note: This assumes that the combination items array is sorted by * resultId and then itemId * * @return resultID The item ID of the resulting item. * @return resultQty The stack quantity of the resulting item. * * @return False if combination is not possible. */ bool IsHandCombinable(uint32 &resultId, int &resultQty); /** Returns with the result ID and quantity of the combination * if the item list matches every item in a valid combination * * @param itemArray The array of items that need to be checked. * @return resultID The item ID of the resulting item. * @return resultQty The stack quantity of the resulting item. * * @return False if combination is not possible. */ bool ValidateCombination(csArray itemArray, uint32 &resultId, int &resultQty); /** Check to see if there is a possible trasnform available. * @param singlePatternID The current single pattern to use * @param groupPatternID The current group pattern to use * @param targetID the id of the item trying to transform. * @param targetQty The stack count of the item to transform. * * @return A integer that indicates pattern match status. */ int AnyTransform(uint32 singlePatternId, uint32 groupPatternId, uint32 targetId, int targetQty); /** Check to see if there is a possible trasnform available. * @param patternId The current pattern to use * @param targetId the id of the item trying to transform. * @param targetQty The stack count of the item to transform. * * @return A integer that indicates pattern match status. */ int IsTransformable(uint32 patternId, uint32 targetId, int targetQty); bool TransformContainedItem(psItem* oldItem, uint32 newId, int newQty, float itemQuality); psItem* CombineContainedItem(uint32 newId, int newQty, float itemQuality, psItem* containerItem); bool TransformSlotItem(int slot, uint32 newId, int newQty, float itemQuality); // bool TransformHandItem(uint32 newId, int newQty, float itemQuality); bool SendItemUpdate( unsigned int slotID, psItem *newItem ); void StartTransformationEvent(int transType, int transSlot, int resultQty, float resultQuality, psItem* autoItem); void StartCleanupEvent(int transType, Client* client, psItem* item, gemActor* worker); bool ValidateTarget(Client* client); bool ValidateWork(); bool ValidateMind(); bool ValidateStamina(Client* client); bool IsOnHand(uint32 equipId); bool IsInContainer(uint32 equipId); psItem* CreateTradeItem(uint32 newId, int newQty, float itemQuality, psItem* parent, int slot); bool ValidateTraining(psTradeTransformations* transCandidate, psTradeProcesses* processCandidate); bool ValidateSkills(psTradeTransformations* transCandidate, psTradeProcesses* processCandidate); bool ValidateNotOverSkilled(psTradeTransformations* transCandidate, psTradeProcesses* processCandidate); bool ValidateConstraints(psTradeTransformations* transCandidate, psTradeProcesses* processCandidate); int CalculateEventDuration(int pointQty); bool CheckStamina(psCharacter * owner) const; void Initialize(); bool ApplySkills(float factor, psItem* transItem); void HandleRepair(Client *client); /// Handle production events from clients void HandleProduction(Client *client,const char *type,const char *reward); public: /// Handle production events from super clients void HandleProduction(gemActor *actor,const char *type,const char *reward); protected: bool SameProductionPosition(gemActor *actor, const csVector3& startPos); NaturalResource *FindNearestResource(const char *reward,iSector *sector, csVector3& pos); }; //----------------------------------------------------------------------------- // work event class class psWorkGameEvent : public psGameEvent, public iDeleteObjectCallback { public: psWorkGameEvent(psWorkManager* mgr, gemActor* worker, int delayticks, int cat, csVector3& pos, NaturalResource *natres=NULL, Client *c=NULL, psItem* object=NULL, float repairAmount=0.0F); virtual ~psWorkGameEvent(); void Interrupt(); virtual void Trigger(); // Abstract event processing function virtual void DeleteObjectCallback(iDeleteNotificationObject * object); // Set the active trade transformation for the event. void SetTransformation(psTradeTransformations *t) { transformation = t; } // Return the active transformation, if any for this event. psTradeTransformations *GetTransformation() { return transformation; } // result quantity is only used when transaction result is zero int GetResultQuantity() { return resultQuantity; } void SetResultQuantity(int newQuantity) { resultQuantity = newQuantity; } // result quality is calculated immediately before the event float GetResultQuality() { return resultQuality; } void SetResultQuality(float newQuality) { resultQuality = newQuality; } // pattern Kfactor is based on the current pattern float GetKFactor() { return KFactor; } void SetKFactor(float newFactor) { KFactor = newFactor; } // slot to perform the transformation int GetTransformationSlot() { return transSlot; } void SetTransformationSlot(int curSlot) { transSlot = curSlot; } psItem* GetTranformationItem() { return item; } void SetTransformationItem(psItem* i) { item = i; } psItem* GetWorkItem() { return workItem; } void SetWorkItem(psItem* w) { workItem = w; } // transformation type int GetTransformationType() { return transType; } void SetTransformationType(int t) { transType = t; } psWorkManager* workmanager; csWeakRef worker; NaturalResource* nr; Client* client; int category; csVector3 position; psItem* object; psTradeTransformations* transformation; float repairAmount; uint32_t effectID; // The id of the psEffect tied to event. csArray multi; private: int resultQuantity; float resultQuality; float KFactor; int transSlot; psItem* item; psItem* workItem; int transType; }; #endif