/* * 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 cHooks.cpp * Implements functionality for housing hooks. * * This class is referenced whenever a housing hook 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 hooks. * * Called whenever a housing hook object should be initialized. */ cHooks::cHooks( 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_dwHouseID = dwHouseID; } /********** * methods *********/ /** * Handles the message sent for the creation of housing hooks in the world. * * This function is called whenever a housing hook should be created for a client. * * @return cMessage - Returns a Create Object (0x0000F745) server message. */ cMessage cHooks::CreatePacket() { cMessage cmCreate; char szCommand[200]; RETCODE retcode; char OwnerIDBuff[9]; DWORD OwnerID = 0x0L; sprintf( szCommand, "SELECT OwnerID FROM houses_covenants WHERE HouseID = %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 = 0x00009081; // Flags1 /* dwModel 0x0A8D Floor Hook 0x0A8E Wall Hook 0x0A8C Ceiling Hook 0x0A8D Yard Hook 0x0A8D Roof Hook wModelID 0x2DB1 Floor Hook 0x25D6 Wall Hook 0x2DB2 Ceiling Hook 0x3187 Yard Hook 0x3186 Roof Hook wIconID 0x20C0 */ WORD tBurden = 0; if (IsUsed == 1) { // cItemModels *h_model = cItemModels::FindModel(m_hook_item->GetItemModelID()); // h_model->m_wBurden //Burden (WORD, no padding) // tBurden += h_model->m_wBurden; } /* //Loop through inventory and find all items. for (int i = 0; i < this->m_hook_lstInventory.size(); i++) { //Find each item by it's GUID cObject *v_item = this->FindInventory(this->v_guids[i]); //Associate model with item cItemModels *v_model = cItemModels::FindModel(v_item->GetItemModelID()); // v_item->GetGUID() //Item GUID // v_model->m_dwFlags2 //10254018 // v_model->m_strName.c_str() //Item Name // v_model->m_wModel //Model // v_model->m_wIcon //Icon // v_model->m_wBurden //Burden (WORD, no padding) // v_model->m_wHooks; //Hook Type (WORD, no padding) } */ cmCreate << 0xF745L << m_dwGUID << BYTE( 0x11 ) << BYTE( 0 ) << BYTE( 0 ) << BYTE( 0 ); cmCreate << dwFlags1; cmCreate << WORD(0x0014); // Type of portal cmCreate << WORD(0x0000); // Unknown //Flags1 Mask: 0x00009081 { //Flags1 & 0x00008000 -- Location cmCreate.pasteData( (UCHAR*)&m_Location, sizeof(m_Location) ); //Next comes the location //Flags1 & 0x00001000 -- DWORD ResourceID cmCreate << 0x3400002B; // unknown ResourceID //Flags1 & 0x00000001 -- DWORD dwModel = 0x02000001; // the model. DWORD dwModel = 0x02000000L + m_dwModel; cmCreate << dwModel; //Flags1 & 0x00000080 -- unknown_green if (flmScale > 0) { flpScale = flmScale;// FLOAT flpScale } else { flpScale = 0.5; } cmCreate << flpScale; } // SeaGreens WORD wUnkFlag2 = 0x0000; WORD wUnkFlag3 = 0x0002; WORD wUnkFlag4 = 0x0000; WORD wUnkFlag6 = 0x0000; WORD wUnkFlag7 = 0x0000; WORD wUnkFlag8 = 0x0000; WORD wUnkFlag10 = 0x0000; cmCreate << m_wPositionSequence // movement 0x0001 << wUnkFlag2 // animations << wUnkFlag3 // bubble modes << wUnkFlag4 // num jumps << m_wNumPortals << wUnkFlag6 // anim count << wUnkFlag7 // overrides << wUnkFlag8 << WORD(0x7A51) // m_wNumLogins // 0x0D4B << wUnkFlag10; DWORD dwFlags2 = 0x3220003A; // 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 & 0x00000002 -- BYTE itemSlots cmCreate << BYTE(0x01); // number of item slots // Flags2 & 0x00000008 -- BYTE value cmCreate << BYTE(0x0A); // object value // Flags2 & 0x00000010 -- DWORD unknown10 cmCreate << 0x30000000L; // Unknown cmCreate << BYTE( 0 ) << BYTE( 0 ) << BYTE( 0 ); // Flags2 & 0x00000020 -- float approachDistance float flApproach = 10.0f; // 0x41200000 cmCreate << flApproach; // distance a player will walk to use the object // Flags2 & 0x00200000 -- WORD burden tBurden += WORD(0x0005); cmCreate << tBurden; // total burden of this object // Flags2 & 0x02000000 -- ObjectID owner cmCreate << OwnerID; // the owner of this object // Flags2 & 0x20000000 -- hookType Unknown cmCreate << WORD(0xFFFF); // always -1 // Flags2 & 0x10000000 -- hookable On /* 0x0001 floor hook 0x0002 wall hook 0x0004 ceiling hook 0x0008 yard hook 0x0010 roof hook */ cmCreate << WORD(0xFFFF); // the types of hooks this object may be placed on (-1 for hooks) return cmCreate; } /** * Handles the actions of housing hook objects. * * This function is called whenever a housing hook is used or should perform an action. */ void cHooks::Action(cClient* who) { cMessage cmUseHook; 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; } cmUseHook << 0xF74CL // Packet type << who->m_pcAvatar->GetGUID() // Character's GUID << m_wNumLogins // number of logins << ++m_wPositionSequence // sequence number << ++m_wNumAnims // Number Animations this login session << WORD(0x00) // Activity << WORD(0x08) << WORD(0x3D) // Starting Stance << m_dwGUID; // Hook's GUID cmUseHook << 0x4342BD54 // DWORD unknown_value << 0x19C5EE0F // bitfield? << 0x3F800000 // unknown -- unknown DWORD << 0x00000000; // float heading -- Appears to be the heading to which the object is turning cWorldManager::SendToAllInFocus( who->m_pcAvatar->m_Location, cmUseHook, 3 ); if(m_wState == 0) { //Display the item slot in the hook (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 hook objects. * * This function is called whenever a housing hook is assessed by a client. * * Returns a Game Event (0x0000F7B0) server message of type Identify Object (0x000000C9). */ void cHooks::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 dwUnkCount = 0x0002; cmAssess << dwUnkCount // Total number of DWORDS << WORD(0x0010) // Unknown << 0x13L // Value << 0x0AL // DWORD value << 0x05L // Burden << 0x05L // 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 << "This hook is 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); }