/* * 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 cHouse.cpp * Implements functionality for house objects. * * This class is referenced whenever a house object is created, used, or assessed. * Inherits from the cObject class. */ #include "object.h" #include "masterserver.h" #include "worldmanager.h" /*************** * constructors **************/ /** * Handles the creation of houses. * * Called whenever a house object should be initialized. * * Generally, house objects reside where the house models are located in the world. * By default, the houses are inaccessable (restricted client-side) by characters unless the proper house object is created. */ cHouse::cHouse( char *szName, char *szDescription, WORD type, DWORD dwGUID, cLocation *pcLoc ) { SetLocation( pcLoc ); m_dwGUID = dwGUID; m_strName.assign( szName ); m_strDescription.assign( szDescription ); m_dwModel = type; m_fStatic = TRUE; } /********** * methods *********/ /** * Handles the message sent for the creation of house objects in the world. * * This function is called whenever a house object should be created in the world for a client. * * @return cMessage - Returns a Create Object (0x0000F745) server message. */ cMessage cHouse::CreatePacket() { cMessage cmReturn; float flpScale; // Scale used in Packet being Sent float flmScale = 0.1f;// Model Data Scale /* wModelID 0x4720 apartment 0x4727 apartment 0x5130 cottage 0x512E cottage 0x512F cottage 0x36A0 cottage 0x37A8 cottage 0x2920 villa 0x218B mansion wIconID 0x2181 apartment 0x2181 cottage 0x218E villa 0x218B mansion */ cmReturn << 0xF745L << m_dwGUID << BYTE( 0x11 ) << BYTE( 0 ) << BYTE( 0 ) << BYTE( 0 ); DWORD dwFlags1 = 0x00028081;// Flags 1 defines whats next cmReturn << dwFlags1; cmReturn << 0x00000034; // Unknown // Flags1 Mask 0x00028081 { // Flags1 & 0x00020000 -- Unknown DWORD cmReturn << 0x00000065; // Flags1 & 0x00008000 -- Location cmReturn.pasteData( (UCHAR*)&m_Location, sizeof(m_Location) ); //Next comes the location // Flags1 & 0x00000001 //DWORD dwModel = 0x02000001; // the model. DWORD dwModel = 0x02000000L + m_dwModel; cmReturn << dwModel; // dwModel; // Flags1 & 0x00000080 -- unknown_green flpScale = 0.1f; // FLOAT flpScale cmReturn << flpScale; } //Next comes some unknown flags...these flags contain information such //as whether or not the object is solid (collision detection), the radar color //PK information, and more. I will crack these some time // SeaGreens WORD wUnkFlag2 = 0x0000; WORD wUnkFlag3 = 0x0000; WORD wUnkFlag4 = 0x0000; WORD wUnkFlag6 = 0x0000; WORD wUnkFlag7 = 0x0000; WORD wUnkFlag8 = 0x0000; WORD wUnkFlag10 = 0x0000; cmReturn << WORD(0x0001) // m_wPositionSequence // movement 0x0001 (can also be 0x0000) << wUnkFlag2 // animations << wUnkFlag3 // bubble modes << wUnkFlag4 // num jumps << m_wNumPortals << wUnkFlag6 // anim count << wUnkFlag7 // overrides << wUnkFlag8 << WORD(0x0D7F) // m_wNumLogins // 0x0D4B << wUnkFlag10; char szCommand[200]; RETCODE retcode; // Flags2 -- Defines what data comes next DWORD dwFlags2; if (m_dwOwnerID) { dwFlags2 = 0x0E200010; // mask for owned dwelling } else { dwFlags2 = 0x0C200010; // mask for unowned dwelling (excludes owner) } cmReturn << dwFlags2; cmReturn << Name( ); // Object's Name cmReturn << m_wModel << m_wIcon; DWORD dwObjectFlags1 = 0x00000080; // 0x0080 Miscellaneous Object DWORD dwObjectFlags2 = 0x00000094; // 0x0004 - Cannot be picked up, 0x0080 Unknown - Cannot be selected 0x0010 Unknown - Can be selected. // appears to contradict it self; sets Cannot be Selected and Can be Selected. Housing Item, may set house open/closed cmReturn << dwObjectFlags1 << dwObjectFlags2; // Flags2 & 0x00000010 -- DWORD unknown10 cmReturn << 0x00000001; // Flags2 & 0x08000000 -- WORD unknown8000000 cmReturn << WORD(0x0098); // Flags2 & 0x00200000 -- WORD burden cmReturn << WORD(0x000A); // total burden of this object if (dwFlags2 == 0x0E200010) // if masked for owned dwelling { // Flags2 & 0x02000000 // ObjectID owner cmReturn << m_dwOwnerID;// the owner of the object } WORD wGuestCount = 0; char GuestIDBuff[9]; DWORD GuestID = NULL; WORD StorageOpen; sprintf( szCommand, "SELECT COUNT(ID) FROM houses_guest_lists WHERE HouseID=%d;",m_wModel ); 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_ULONG, &wGuestCount, sizeof( wGuestCount ), NULL ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 ) retcode = SQLFetch( cDatabase::m_hStmt ); if( retcode == SQL_NO_DATA ) wGuestCount = 0; retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL ) retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL ) // Flags2 & 0x04000000 // Dwelling access control list cmReturn << 0x10000002 // DWORD flags -- believed to be flags that control the size and content of this structure << IsOpen // DWORD open: 0 = private dwelling, 1 = open to public << 0x00000000 // ObjectID allegiance -- allegiance monarch (if allegiance access granted) << wGuestCount // WORD guestCount -- number of guests on list << WORD(0x0300);// WORD guestLimit -- Maximum number of guests on guest list (cottage is 32) sprintf( szCommand, "SELECT GuestGUID,StorageAccess FROM houses_guest_lists WHERE HouseID=%d;",m_wModel ); 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, GuestIDBuff, sizeof( GuestIDBuff ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1) retcode = SQLBindCol( cDatabase::m_hStmt, 2, SQL_C_USHORT, &StorageOpen, sizeof( WORD ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL) for ( int i = 0; SQLFetch( cDatabase::m_hStmt ) == SQL_SUCCESS; ++i ) { sscanf(GuestIDBuff,"%08x",&GuestID); cmReturn << DWORD(GuestID) << StorageOpen; //0x0000 = access to dwelling; 0x0001 = access also to storage; } retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL) retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND ); return cmReturn; } /** * Handles the actions of house objects. * * This function is called whenever a house object is used or should perform an action. */ void cHouse::Action(cClient* who) { cMessage cmActionComplete; cmActionComplete << 0xF7B0L << who->m_pcAvatar->GetGUID( ) << ++who->m_dwF7B0Sequence << 0x01C7L << 0L; who->AddPacket(WORLD_SERVER,cmActionComplete,4); } /** * Handles the assessment of house objects. * * This function is called whenever a house object is assessed by a client. * House objects are intended to be imperceptible to the client. * * Returns a Game Event (0x0000F7B0) server message of type Identify Object (0x000000C9). */ void cHouse::Assess(cClient *pcAssesser) { cMessage cmAssess; cmAssess << 0xF7B0L << pcAssesser->m_pcAvatar->GetGUID() << ++pcAssesser->m_dwF7B0Sequence << 0xC9L; cmAssess << m_dwGUID << 0x00000080L << 1L; cmAssess << 0xEL; cmAssess << 30L << 50L << 50L; cmAssess << 60L << 40L << 50L << 60L << 100L << 100L << 70L << 150L << 70L << 150L << 1L; cmAssess << 0xFFFFFFFFL << 0xFFFFFFFFL; cmAssess << 50L << 100L << 0L; cmAssess << "Male" << "Isparian" << "NPC" << "" << "" << "" << 1L << 2L << 1L << 3L << 2L << 3L << 0L; 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); }