/* * This file is part of UAS2. * * UAS2 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. * * UAS2 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 UASv1; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file cStorage.cpp * Implements functionality for housing storage. * * This class is referenced whenever a housing storage object is created, used, or assessed. * Inherits from the cObject class. */ #include "Client.h" #include "MasterServer.h" #include "Object.h" #include "WorldManager.h" /*************** * constructors **************/ /** * Handles the creation of housing storage chests. * * Called whenever a housing storage chest object should be initialized. */ cStorage::cStorage( WORD type, DWORD dwGUID, DWORD dwHouseID, char *szName, char *szDescription, cLocation *pcLoc ) { SetLocation( pcLoc ); m_dwGUID = dwGUID; m_strName.assign( szName ); m_strDescription.assign( szDescription ); m_dwModel = type; m_fStatic = TRUE; m_dwDoorState = 0x0CL; m_dwHouseID = dwHouseID; m_dwOwnerID = 0x00000000; // TODO: Link with housing } /********** * methods *********/ /** * Handles the message sent for the creation of housing storage chests in the world. * * This function is called whenever a housing storage chest object should be created in the world for a client. * * @return cMessage - Returns a Create Object (0x0000F745) server message. */ cMessage cStorage::CreatePacket() { cMessage cmCreate; char szCommand[200]; RETCODE retcode; char OwnerIDBuff[9]; DWORD OwnerID = NULL; sprintf( szCommand, "SELECT OwnerID FROM houses WHERE wModel = %d;",m_dwHouseID); retcode = SQLPrepare( cDatabase::m_hStmt, (unsigned char *)szCommand, SQL_NTS ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL) retcode = SQLExecute( cDatabase::m_hStmt ); retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_CHAR, OwnerIDBuff, sizeof( OwnerIDBuff ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1) // Return SQL_SUCCESS if there is a house that corresponds to the hook's HouseID if (SQLFetch( cDatabase::m_hStmt ) == SQL_SUCCESS) { sscanf(OwnerIDBuff,"%08x",&OwnerID); } retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL) retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND ); // float flpScale; // Scale used in Packet being Sent float flmScale = 0; // Model Data Scale DWORD dwFlags1 = 0x00019803; cmCreate << 0xF745L << m_dwGUID << BYTE( 0x11 ) << BYTE( 0 ) << BYTE( 0 ) << BYTE( 0 ); cmCreate << dwFlags1; cmCreate << WORD(0x0418); // Type of portal cmCreate << WORD(0x0000); // Unknown //Flags1 Mask: 0x00019803 { //Flags1 & 0x00010000 -- DWORD byteCount DWORD dwUnkCount = 0x0000000C; BYTE unknownByte[0x0C] = { 0x00,0x00,0x3D,0x00,0x02,0x00,0x00,0x00, 0x0C, // model appearance: owned = 0x0B; unowned = 0x0A, 0x0C? 0x00,0x00,0x00}; cmCreate << dwUnkCount; for ( int i = 0; i < dwUnkCount; ++i ) { cmCreate << unknownByte[i]; } DWORD dwUnknownDword = 0x0L; cmCreate << dwUnknownDword; //Flags1 & 0x00008000 -- Location cmCreate.pasteData( (UCHAR*)&m_Location, sizeof(m_Location) ); // Next comes the location //Flags1 & 0x0000002 -- DWORD ResourceID Animations DWORD dwAnimC = 0x09000000L + m_wAnimConfig; cmCreate << dwAnimC; //Flags1 & 0x0000800 -- DWORD ResourceID Sounds DWORD dwSoundSet = 0x20000000L + m_wSoundSet; cmCreate << dwSoundSet; //Flags1 & 0x00001000 -- DWORD ResourceID cmCreate << 0x3400002B; // unknown ResourceID //Flags1 & 0x00000001 -- DWORD ResourceID dwModel = 0x02000001; // the model. DWORD dwModel = 0x02000000L + m_dwModel; cmCreate << dwModel; } // SeaGreens WORD wNuminteracts = 0x0004; WORD wNumbubbles = 0x0000; WORD wNumJumps = 0x0000; WORD wUnkFlag6 = 0x0000; WORD wNumOverrides = 0x0040; WORD wUnkFlag8 = 0x0000; WORD wUnkFlag10 = 0x0000; cmCreate << m_wPositionSequence // movement 0x0001 << wNuminteracts // animations << wNumbubbles // bubble modes << wNumJumps // num jumps << m_wNumPortals << wUnkFlag6 // anim count << wNumOverrides // overrides << wUnkFlag8 << WORD(0x7A51) // m_wNumLogins // 0x0D4B << wUnkFlag10; DWORD dwFlags2 = 0x0220003E; // Flags2 -- Defines what data comes next cmCreate << dwFlags2; cmCreate << Name( ); // Object's Name cmCreate << WORD(m_wModel) << WORD(m_wIcon); DWORD dwObjectFlags1 = 0x00000200; // 0x0200 Containers DWORD dwObjectFlags2 = 0x00000015; // 0x0010 is not an npc; 0x0004 cannot be picked up; 0x0001 can be opened (false if locked) cmCreate << dwObjectFlags1 << dwObjectFlags2; //Flags2 Mask: 0x0220003E { // Flags2 & 0x00000002 -- BYTE itemSlots cmCreate << BYTE(0x1A); // number of item slots // Flags2 & 0x00000004 -- BYTE packSlots cmCreate << BYTE(0x01); // number of pack slots (a pack slot is a slot that may hold a pack or a foci) // Flags2 & 0x00000008 -- DWORD value cmCreate << 0x000000C8; // object value // Flags2 & 0x00000010 -- DWORD unknown10 cmCreate << 0x00000030; // Flags2 & 0x00000020 -- float approachDistance float flApproach = 1.0f; // 0x3F800000 cmCreate << flApproach; // distance a player will walk to use the object // Flags2 & 0x00200000 -- WORD burden cmCreate << WORD(0xBBAF); // total burden of this object // Flags2 & 0x02000000 -- ObjectID owner cmCreate << OwnerID; // the owner of this object } return cmCreate; } /** * Handles the actions of housing storage chest objects. * * This function is called whenever a housing storage chest is used or should perform an action. */ void cStorage::Action(cClient* who) { cMessage cmUseChest; WORD m_wStance; if(m_wState == 0) //CLOSED { m_dwDoorState = 0x0CL; m_wStance = 0x3D; // Starting Stance m_wState = 1; } else //OPEN { m_dwDoorState = 0x0BL; m_wStance = 0x3D; m_wState = 0; } //Play Animation cmUseChest << 0xF74CL // Packet type << m_dwGUID // Door's GUID << m_wNumLogins // number of logins << ++m_wPositionSequence // sequence number << ++m_wNumAnims // Number Animations this login session << WORD(0x00) // Activity << WORD(0x00) << WORD(0x3D) // Starting Stance << DWORD(0x00000002) // Supposed to be Animation Mask << m_dwDoorState; // Door state Closed = 0x0C Open = 0x0B cWorldManager::SendToAllInFocus( who->m_pcAvatar->m_Location, cmUseChest, 3 ); if(m_wState == 0) { //Display the item slots in the chest (0x0196) cMessage cmSetPackContents; cmSetPackContents << 0xF7B0L << who->m_pcAvatar->GetGUID( ) << ++who->m_dwF7B0Sequence << 0x0196L << m_dwGUID; who->AddPacket(WORLD_SERVER,cmSetPackContents,4); cMessage cmActionComplete; cmActionComplete << 0xF7B0L << who->m_pcAvatar->GetGUID( ) << ++who->m_dwF7B0Sequence << 0x01C7L << 0L; who->AddPacket(WORLD_SERVER,cmActionComplete,4); } if(m_wState == 1) { //Close Container cMessage cmCloseContainer; cmCloseContainer << 0xF7B0L << who->m_pcAvatar->GetGUID( ) << ++who->m_dwF7B0Sequence << 0x0052L << m_dwGUID; who->AddPacket(WORLD_SERVER,cmCloseContainer,4); cMessage cmActionComplete; cmActionComplete << 0xF7B0L << who->m_pcAvatar->GetGUID( ) << ++who->m_dwF7B0Sequence << 0x01C7L << 0L; who->AddPacket(WORLD_SERVER,cmActionComplete,4); } } /** * Handles the assessment of housing storage chest objects. * * This function is called whenever a housing storage chest is assessed by a client. * * Returns a Game Event (0x0000F7B0) server message of type Identify Object (0x000000C9). */ void cStorage::Assess(cClient *pcAssesser) { // cObject *pcObject = cWorldManager::FindObject( m_dwGUID ); cMessage cmAssess; DWORD flags = 0x0000000B; m_strDescription.assign("Use this item to open it and see its content"); cmAssess << 0xF7B0L << pcAssesser->m_pcAvatar->GetGUID() << ++pcAssesser->m_dwF7B0Sequence << 0xC9L << m_dwGUID << flags << 0x01L // Success = 0x01; Failure = 0x00 // Flags & 0x00000001 << WORD(0x0002) // Total number of DWORDS << WORD(0x0010) // Unknown << 0x13L // Value << 0xC8L // DWORD value << 0x05L // Burden << 0x0001BBAFL // DWORD value // Flags & 0x00000002 << WORD(0x0001) // Total number of DWORDS << WORD(0x0008) // Unknown << 0x02L // Value << 0x00L // DWORD value // Flags & 0x00000008 << WORD(0x0002) // Total number of DWORDS << WORD(0x0008) // Unknown << 0x10L; // DWORD Full Description cmAssess << "Owned by Cubem0j0" << 0x0EL // DWORD Usage Instructions << this->m_strDescription.c_str(); pcAssesser->AddPacket(WORLD_SERVER,cmAssess,4); cMessage cmActionComplete; cmActionComplete << 0xF7B0L << pcAssesser->m_pcAvatar->GetGUID( ) << ++pcAssesser->m_dwF7B0Sequence << 0x01C7L << 0L; pcAssesser->AddPacket(WORLD_SERVER,cmActionComplete,4); }