/* * psserverchar.h * * Copyright (C) 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 PS_SERVER_CHAR_MANAGER_H #define PS_SERVER_CHAR_MANAGER_H #include "msgmanager.h" #include "bulkobjects/pscharacter.h" #include "bulkobjects/psitem.h" #include "iutil/vfs.h" #include #include class MsgEntry; class ClientConnectionSet; class psServer; class Client; struct psItemCategory; class psMerchantInfo; class psItem; class psActionLocation; enum ReservedNames{NAME_RESERVED_FOR_YOU, NAME_RESERVED, NAME_AVAILABLE}; /// This manages the collective change to state that needs to be made when a transaction is successful. class psTransaction { protected: psCharacter *from; enum Slot_Containers eToSlot; int toSlot; int toContainer; bool toSet; void ToWorld(psItem *item); void ToBulk(psItem *item); void ToEquipment(psItem *item); void ToContainer(psItem *item); psTransaction() : toSet(false) { }; public: virtual void Execute(void) = 0; void To(Slot_Containers slot, int _toSlot = 0, int toContainer = 0); }; class transMoney : public psTransaction { psMoney amount; bool fromExchange; public: transMoney(const psMoney& amount, psCharacter *from, bool exchange); void Execute(void); }; class transItem : public psTransaction { enum Slot_Containers eFromSlot; int fromSlot; int fromContainer; int quantity; bool Validate(psItem *item, int& remainder); public: transItem(Slot_Containers slot, int fromSlot, int quantity, psCharacter *from, int fromContainer = 0); void Execute(void); bool IsInUse(); // This retrieves the item to be moved by the transaction, note the stack count may be wrong psItem *GetItem(); }; /** Handles Drag and Drop Messages from the client. * This basically figures out what item is being dragged and places it in a * holding slot. It then looks for the destination slot and sees if it can be placed * there. If not it will Replace the holding item back to where it came from. */ class SlotManager : public MessageManager { public: virtual ~SlotManager(); bool Initialize(); virtual void HandleMessage( MsgEntry *me, Client *client ); static psItem* FindItem( Client* client, int containerID, int slotID, int parentID = 0 ); /** Used in the slot management. This is called when a player tries to place an * item into an equipment slot. If it was successful then holdingItem should be * set to NULL. Otherwise the holdingItem will automatically be replaced in it's * orginal slot. * * @param mesg The incoming message from the client for the movement. */ static int PlaceItemInEquipment( psCharacter& character, int toSlot, psItem* item, bool test ); /** Find a container based on id. * This uses the gem idea of the gemItem object to find the psItem. */ static psItem* FindContainer( Client* client, int containerID, int parentContainerID ); /** Sends an error message to the client based on the return code. * This will send a popup floating text error message. * @param result One of the enums from psitem.h * @param fromClient The client the error message should be sent to. */ static void SendContainerError( int result, Client* fromClient, int containerID, int slotID, int parentContainerID ); /** This creates a money item. * * @param slot One of the four money slots. * @param stackCount The amount to put in the item. * @return A new psItem object. */ static psItem* MakeMoneyItem( int slot, int stackCount ); static void UnequipHolding( int fromSlot, psItem* item, psCharacter* from); private: /** Finds the particular item the client dragged/dropped. * @param fromClient The client the message came from. * @param mesg The slot movement message that has the drag/drop details. * * @return A psTransaction object that the player is manipulating. */ psTransaction* StartTransaction( Client* fromClient, psSlotMovementMsg& mesg ); /** Places the item that is being dragged into it's destination slot. * * @param mesg The slot movement message that has the drag/drop details. */ void PlaceHoldingItem( Client* fromClient, psSlotMovementMsg& mesg, psTransaction *tRemove); void PlaceItemInExchange( Client* fromClient, psSlotMovementMsg & mesg, psTransaction *tRemove); /** Consume an item. This will consume the item and fire off any events * that this item has. */ static int Consume( psItem* item, psCharacter& charData, bool test ); }; /// Manages character details over the net. /** * This is used instead of cel persistance because the persistance * is an all or nothing sort of thing. By using this we can make * more efficient use of the net traffic */ class psServerCharManager : public MessageManager { public: psServerCharManager(); virtual ~psServerCharManager(); bool Initialize( ClientConnectionSet* ccs); virtual void HandleMessage( MsgEntry *me, Client *client ); // Handles any incomming messages about the character gui. virtual bool HandleInventoryMessage( MsgEntry* me ); /// Sends the client an inventory virtual bool SendInventory( int clientNum, bool sendUpdatesOnly = true ); /// Update all views with items virtual bool UpdateItemViews( int clientNum ); bool SendItemContents( Client *client, psItem *item, int parentContainer = 0, int containerID = CONTAINER_INVENTORY_BULK); bool SendActionContents( Client *client, psActionLocation *action, csRef topNode, psItem *item, int parentContainer = 0, int containerID = CONTAINER_INVENTORY_BULK); void SendOutPlaySoundMessage( int clientnum, const char* itemsound, const char* action ); /** Sends out equipment messages to all the people around client. * * This is used when a player changes their visible equipment and needs * to be reflected on other nearby clients. Visible changes can be either * new weapons/shields ( new mesh ) or texture changes for clothes ( new material ). * * @param fromClient The client that has changed equipment. * @param slotName To what slot has changed. * @param item The item that is the piece of visible equipment. * @param type The equiping type. One of: * psEquipmentMessage::DEEQUIP * psEquipmentMessage::EQUIP * */ void SendOutEquipmentMessages( Client* fromClient, int slotID, psItem* item, int equiped ); void SendOutEquipmentMessages( unsigned int fromClient, int slotID, psItem* item, int equiped ); void SendOutEquipmentMessages( gemActor* actor, int slotID, psItem* item, int equiped ); /** Check to see if a name is on the reserve list for database migration. @param playerName The name to check to see if is on a the reserve list. @param acctID The acct that is trying to create this character. @return
  • NAME_RESERVED_FOR_YOU - if you can take this name.
  • NAME_RESERVED - you are not allowed this name.
  • NAME_AVAILABLE - name is free for use.
*/ int IsReserved( const char* playerName, int acctID ); /** Check to see a name is unique in the characters table. @param playerName The name to check to see if it is unique. @return true if the name is unique. */ bool IsUnique( const char* playerName ); /** Check to see a lastname is unique in the characters table. @param lastname The lastname to check to see if it is unique. @return true if the name is unique. */ bool IsLastNameUnique( const char* lastname ); void ViewItem(Client* client, int containerID, int slotID, int parentContainerID); void BeginTrading(Client * client, gemObject * target, const csString & type); /// Returns true if the name is ok static bool FilterName( const char* name ); bool IsBanned(const char* name); ///Checked if the character exists still or if it hasn't connected in two months. int HasConnected( csString name ); protected: void SendPlayerMoney( Client *client); bool SendItemDescription( Client *client, psItem *item); bool SendBookText( Client *client, psItem *item); bool SendMerchantItems( Client *client, psCharacter * merchant, psItemCategory * category); bool SendPlayerItems( Client *client, psItemCategory * category); void HandleBookWrite(MsgEntry* me, Client* client); void HandleUploadMessage( MsgEntry * me, Client *client ); void HandleCharInfo( MsgEntry* me, Client *client ); void HandleMerchantMessage( MsgEntry* me, Client *client ); void HandleCraftInfo( MsgEntry * me, Client *client ); /** Fills up the message with the details about the items in the container. * @param item The item that is the container * @param client The client the message is for. Used to figure out ownership flags. * @param outgoing The message that needs to be populated. */ void FillContainerMsg( psItem* item, Client* client, psViewItemDescription& outgoing ); /// Return true if all trade params are ok bool VerifyTrade( Client * client, psCharacter * character, psCharacter ** merchant, psMerchantInfo ** info, const char * trade,const char * itemName, unsigned int merchantID); // verifies that item dropped in mind slot is a valid goal bool VerifyGoal(Client* client, psCharacter* character, psItem* goal); ClientConnectionSet* clients; /** Assign a script to a character. Takes whatever script is stored in the migration table and adds it to the character to be run on character login. @param chardata The character data class to append the script to. */ void AssignScript( psCharacter* chardata ); SlotManager *slotManager; void ViewItem( MsgEntry* me ); }; #endif