123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440 |
- /*
- * 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 Corpse.cpp
- * Implements functionality for corpses.
- *
- * This class is referenced whenever a corpse is created, used, or assessed.
- *
- * Author: Cubem0j0
- */
-
- #include "Client.h"
- #include "MasterServer.h"
- #include "Object.h"
- #include "WorldManager.h"
- #include "TreasureGen.h"
-
- /***************
- * constructors
- **************/
-
- /**
- * Handles the creation of corpses.
- *
- * Called whenever a corpses object should be initialized.
- */
- cCorpse::cCorpse( WORD type, DWORD dwGUID, cLocation& Loc, char *szName, char *szDesc)
- {
- //SetLocation( pcLoc );
- m_dwGUID = dwGUID;//cWorldManager::NewGUID_Object( );
- m_strName.assign( szName );
- m_strDescription.assign( szDesc );
- m_dwModel = type;
- m_dwType = 0;
- m_fStatic = false;
- m_dwDoorState = 0x0CL;
- CopyMemory( &m_Location, &Loc, sizeof( cLocation ) );
- //Set the objects state
- this->SetState(0);
- }
-
- /**********
- * methods
- *********/
-
- /**
- * Handles the message sent for the creation of a corpse in the world.
- *
- * This function is called whenever a corpse should be created in the world for a client.
- * @return cMessage - Returns a server message to the client.
- */
- cMessage cCorpse::CreatePacket( )
- {
- cMessage cmCreate;
- unsigned char bUnknown[] = {
- 0x00, 0x00, 0x3D, 0x00, 0x02, 0xF0, 0xB5, 0x02, 0x11, 0x00, 0x00, 0x00,
- };
-
- cModels *pcMonster = cModels::FindModel(this->m_MonsterModelID);
-
- #ifdef _DEBUG
- cMasterServer::ServerMessage( ColorYellow,NULL,"m_dwModel = %d",this->m_MonsterModelID);
- #endif
-
- if(pcMonster)
- {
- cmCreate << 0xF745L << m_dwGUID << BYTE(0x11); //0x11 is a constant
- cmCreate << pcMonster->m_bPaletteChange
- << pcMonster->m_bTextureChange
- << pcMonster->m_bModelChange;
-
- // The Model Vectors
- if ( pcMonster->m_bPaletteChange != 0)
- {
- for (int i = 0; i < pcMonster->m_bPaletteChange; i++)
- {
- cmCreate.pasteData((UCHAR*)&pcMonster->m_vectorPal[i],sizeof(pcMonster->m_vectorPal[i]));
- }
- }
-
- if (pcMonster->m_bPaletteChange != 0)
- {
- cmCreate << WORD( pcMonster->m_wUnknown1 );
- }
-
- if ( pcMonster->m_bTextureChange != 0)
- {
- for (int i = 0; i < pcMonster->m_bTextureChange; i++)
- {
- cmCreate.pasteData((UCHAR*)&pcMonster->m_vectorTex[i],sizeof(pcMonster->m_vectorTex[i]));
- }
- }
-
- if ( pcMonster->m_bModelChange != 0)
- {
- for (int i = 0; i < pcMonster->m_bModelChange; i++)
- {
- cmCreate.pasteData((UCHAR*)&pcMonster->m_vectorMod[i],sizeof(pcMonster->m_vectorMod[i]));
- }
- }
- }
-
- cmCreate.pasteAlign(4);
- DWORD dwFlags = 0x00019883L;
-
- cmCreate << dwFlags;
- cmCreate << WORD( 0x0414 );
- cmCreate << WORD( 0x000C );
-
- // MASK 0x00010000 unknown Bytes - Starting Animation
- cmCreate << 0x0CL;
- cmCreate.pasteData(bUnknown,sizeof(bUnknown));
- cmCreate << 0x0L;
- // MASK 0x00008000 -- Location
- if ( !m_fIsOwned )
- cmCreate.CannedData( (BYTE *)&m_Location, sizeof( cLocation ) );
- // MASK 0x00000002 -- Animation Set
- DWORD dwAnimC = 0x09000000L + m_wAnimConfig;
- cmCreate << dwAnimC;
- // MASK 0x00000800 -- Sound Set
- DWORD dwSoundSet = 0x20000000L + m_wSoundSet;
- cmCreate << dwSoundSet;
- // MASK 0x00001000 -- Particle Effects (unknown_blue)
- cmCreate << 0x3400006EL;//0x00000000L;
- // MASK 0x00000001 -- ModelNumber
- DWORD dwModel = 0x02000000L + m_dwModel;
- cmCreate << dwModel;
-
- cmCreate << float(m_flScale);
-
- // SeaGreens
- WORD wNuminteracts = 0x0;
- WORD wNumbubbles = 0x0;
- WORD wNumJumps = 0x0;
- WORD wNumOverrides = 0x0;
- WORD wUnkFlag8 = 0x0;
- WORD wUnkFlag10 = 0x0;
-
- cmCreate << m_wPositionSequence
- << m_wNumAnims //wNuminteracts
- << wNumbubbles
- << wNumJumps
- << m_wNumPortals
- << m_wNumAnims
- << wNumOverrides
- << wUnkFlag8
- << m_wNumLogins
- << wUnkFlag10;
-
- DWORD dwFlags2 = 0x00200036;
-
- cmCreate << dwFlags2 << m_strName.c_str( ) << WORD(m_wModel) << WORD(m_wIcon);//WORD( 0x019C ) << WORD( 0x1317 );;//WORD( 0x0116 ) << WORD( 0x1317 );
-
- /* Category of object:
- 0x00000001 Melee Weapon
- 0x00000002 Armor
- 0x00000004 Clothing
- 0x00000008 Jewelry
- 0x00000010 Creature (Player/NPC/Monster)
- 0x00000020 Food
- 0x00000040 Pyreals
- 0x00000080 Miscellaneous
- 0x00000100 Missile Weapons/Ammunition
- 0x00000200 Containers
- 0x00000400 Wrapped Fletching Supplies, House Decorations
- 0x00000800 Gems, Pack dolls, Decorative Statues
- 0x00001000 Spell Components
- 0x00002000 Books, Parchment, Scrolls, Signs, Statues
- 0x00004000 Keys, Lockpicks
- 0x00008000 Casting Item (wand, orb, staff)
- 0x00010000 Portal
- 0x00020000 Lockable
- 0x00040000 Trade Notes
- 0x00080000 Mana Stones, Mana Charges
- 0x00100000 Services
- 0x00200000 unknown (no longer plants)
- 0x00400000 Cooking Ingredients and Supplies, Plants, Dye Pots
- 0x00800000 Loose Fletching Supplies
- 0x01000000 unknown
- 0x02000000 unknown
- 0x04000000 Alchemy Ingredients and Supplies, Oils, Dye Vials
- 0x08000000 unknown
- 0x10000000 Lifestone
- 0x20000000 Ust
- 0x40000000 Salvage
- 0x80000000 unknown
- */
-
- DWORD dwObjectFlags1 = 0x0200L;
- cmCreate << dwObjectFlags1;
-
- /* Behavior of object:
- 0x00000001 can be opened (false if locked)
- 0x00000002 can be inscribed
- 0x00000004 cannot be picked up
- 0x00000008 is a player
- 0x00000010 is not an npc
- 0x00000020 unknown
- 0x00000040 unknown
- 0x00000080 cannot be selected
- 0x00000100 can be read
- 0x00000200 is a merchant
- 0x00000400 is a pk altar
- 0x00000800 is an npk altar
- 0x00001000 is a door
- 0x00002000 is a corpse
- 0x00004000 can be attuned to (lifestone)
- 0x00008000 adds to health, stamina or mana
- 0x00010000 is a healing kit
- 0x00020000 is a lockpick
- 0x00040000 is a portal
- 0x00800000 is a foci
- 0x04000000 has an extra flags DWORD
- */
- DWORD dwObjectFlags2 = 0x2015L;
- cmCreate << dwObjectFlags2;
-
-
- /* Masked against dwFlags2 in reverse order:
- 0x00000002 - Item Slots
- 0x00000004 - Pack Slots
- 0x00000008 - Value
- 0x00000010 - Unknown1
- 0x00000020 - Approach Distance
- 0x00200000 - Burden
- */
- cmCreate << BYTE (0x78); //78 is item slots. (120)
- cmCreate << BYTE (0x00); //00 is pack slots
- //cmCreate << DWORD (0x000009C4); //Value
- cmCreate << DWORD (0x00000030); //Unknown
- cmCreate << float(3.0); //Approach Distance.
- cmCreate << WORD (0x0000); //Burden
-
- return cmCreate;
- }
-
- /**
- * Handles the actions of corpse objects.
- *
- * This function is called whenever a corpse is used.
- */
- void cCorpse::Action(cClient* who)
- {
-
- //Logic for open/close
- switch (GetState())
- {
- case 0:
- {
- /*
- char szCommand[100];
- RETCODE retcode;
-
- int ItemType;
- DWORD dwItemModelID;
- int test;
- test = 70;
-
- sprintf( szCommand, "SELECT * FROM monsters_loot where dwModelID = %d;", this->GetType());
- #ifdef _DEBUG
- cMasterServer::ServerMessage( ColorYellow,NULL,"This GUID: %d, This Monster Model: %d",this->GetGUID(),this->GetMonsterModelID());
- #endif
- retcode = SQLPrepare( cDatabase::m_hStmt, (unsigned char *)szCommand, SQL_NTS ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
- retcode = SQLExecute( cDatabase::m_hStmt );
- int iCol = 3;
-
- retcode = SQLBindCol( cDatabase::m_hStmt, iCol++, SQL_C_LONG, &ItemType, sizeof( INT ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
- retcode = SQLBindCol( cDatabase::m_hStmt, iCol++, SQL_C_LONG, &dwItemModelID, sizeof( DWORD ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
- who->m_pcAvatar->m_CorpseTarget = this->GetGUID();
-
- cMessage cmSetPackContents;
- cmSetPackContents << 0xF7B0L << who->m_pcAvatar->GetGUID( ) << ++who->m_dwF7B0Sequence << 0x0196L << m_dwGUID;
- for ( int i = 0; SQLFetch( cDatabase::m_hStmt ) == SQL_SUCCESS; i++ )
- {
- //Cubem0j0: We find the model number so we can get some vars.
- cItemModels *pcModel = cItemModels::FindModel(dwItemModelID);
-
- switch(ItemType)
- {
- case 1:
- {
- cWeapon* aWeapon = new cWeapon(cWorldManager::NewGUID_Object(),this->GetGUID(),dwItemModelID,1.0,TRUE,pcModel->m_wIcon,pcModel->m_strName,pcModel->m_strDescription,pcModel->m_wBurden,pcModel->m_dwValue,pcModel->m_bWieldType);
- who->AddPacket( WORLD_SERVER, aWeapon->CreatePacketContainer(this->GetGUID(),pcModel->m_dwModelID),3);
- this->AddInventory(aWeapon);
- cmSetPackContents << 0x01L << aWeapon->GetGUID() << 0x0L;
- #ifdef _DEBUG
- cMasterServer::ServerMessage( ColorYellow,NULL,"Case 1");
- #endif
- break;
- }
-
- case 2:
- {
- cFood* aFood = new cFood(cWorldManager::NewGUID_Object(),this->GetGUID(),dwItemModelID,pcModel->m_wIcon,pcModel->m_strName,pcModel->m_strDescription,pcModel->m_wBurden,pcModel->m_dwValue);
- who->AddPacket( WORLD_SERVER, aFood->CreatePacketContainer(this->GetGUID(),pcModel->m_dwModelID),3);
- this->AddInventory(aFood);
- cmSetPackContents << aFood->GetGUID() << 0x0L;
- break;
- }
-
- case 3:
- {
- cArmor* aArmor = new cArmor(cWorldManager::NewGUID_Object(),this->GetGUID(),dwItemModelID,1.0,TRUE,pcModel->m_wIcon,pcModel->m_strName,pcModel->m_strDescription,pcModel->m_dwValue,pcModel->m_wBurden);
- who->AddPacket( WORLD_SERVER, aArmor->CreatePacketContainer(this->GetGUID(),pcModel->m_dwModelID),3);
- this->AddInventory(aArmor);
- cmSetPackContents << aArmor->GetGUID() << 0x0L;
- break;
- }
-
- case 8:
- {
- cWands* aWand = new cWands(cWorldManager::NewGUID_Object(),this->GetGUID(),dwItemModelID,1.0,TRUE,pcModel->m_wIcon,pcModel->m_strName,pcModel->m_strDescription,pcModel->m_dwValue,pcModel->m_wBurden);
- who->AddPacket( WORLD_SERVER, aWand->CreatePacketContainer(this->GetGUID(),pcModel->m_dwModelID),3);
- this->AddInventory(aWand);
- cmSetPackContents << aWand->GetGUID() << 0x0L;
- break;
- }
-
- case 13:
- {
- cSpellComps* aReg = new cSpellComps(cWorldManager::NewGUID_Object(),this->GetGUID(),dwItemModelID,1.0,TRUE,pcModel->m_wIcon,pcModel->m_strName,pcModel->m_strDescription,pcModel->m_dwValue,pcModel->m_wBurden);
- who->AddPacket( WORLD_SERVER, aReg->CreatePacketContainer(this->GetGUID(),pcModel->m_dwModelID),3);
- this->AddInventory(aReg);
- //cmSetPackContents << 0x01L << aReg->GetGUID() << 0x0L;
- break;
- }
-
- }
- who->AddPacket(WORLD_SERVER,cmSetPackContents,4);
- }
- */
- //I just explicitly use a model ID here, I will change this to a function later.
- cItemModels *pcModel = cItemModels::FindModel(147);
-
- //Use the Item Container classes to create the item in a corpse/chest.
- cLockpicks* Lockpicks = new cLockpicks(cWorldManager::NewGUID_Object(),this->GetGUID(),pcModel->m_dwModelNumber,1.0,TRUE,pcModel->m_wIcon,pcModel->m_strName,pcModel->m_strDescription,pcModel->m_wUses,pcModel->m_wUseLimit);
-
- //Need a way for the cObject class to find the Item Model ID
- Lockpicks->m_dwItemModelID = pcModel->m_dwModelID;
-
- //Send the create packet
- who->AddPacket(WORLD_SERVER,Lockpicks->CreatePacketContainer(this->GetGUID(),Lockpicks->GetItemModelID()),3);
-
- #ifdef _DEBUG
- cMasterServer::ServerMessage( ColorYellow,NULL,"ItemModelID is: %d",Lockpicks->GetItemModelID());
- #endif
-
- //Add the item to the corpse inventory.
- this->AddInventory(Lockpicks);
-
- //SQL Done
- // 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 )
-
- //Set the GUID of the corpse on the avatar (this is used in find the item in the corpses inventory)
- who->m_pcAvatar->m_CorpseTarget = this->GetGUID();
-
- if(this->FindInventory(Lockpicks->GetGUID()))
- {
- #ifdef _DEBUG
- cMasterServer::ServerMessage( ColorYellow,NULL,"Item Found");
- #endif
- }
-
- //Display the item slots in the chest (0x0196)
- cMessage cmSetPackContents;
- cmSetPackContents << 0xF7B0L << who->m_pcAvatar->GetGUID( ) << ++who->m_dwF7B0Sequence << 0x0196L << m_dwGUID
- << 0x01L << Lockpicks->GetGUID() << 0x0L;
- 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);
-
- this->SetState(1);
- break;
- }
- case 1:
- {
- #ifdef _DEBUG
- cMasterServer::ServerMessage(ColorYellow,NULL,"m_wState is %d",m_wState);
- #endif
-
- //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);
- this->SetState(0);
- break;
- }
- }
- }
-
- /**
- * Handles the assessment of corpse objects.
- *
- * This function is called whenever a corpse is assessed by a client.
- * Returns a server message to the client.
- */
- void cCorpse::Assess(cClient *pcAssesser)
- {
- cMessage cmAssess;
- DWORD flags = 0x00000009;
- cmAssess << 0xF7B0L << pcAssesser->m_pcAvatar->GetGUID() << ++pcAssesser->m_dwF7B0Sequence << 0xC9L << m_dwGUID
- << flags
- << 0x01L //Success = 0x01, Failure = 0x00
- << WORD(0x0002)
- << WORD(0x0010)
- << 0x13L //Value
- << 0x00L //Corpse always zero.
- << 0x05L //Burden
- << 0xCCL //for now, static amount it eventuall should add up all the item bu's
-
- << WORD(0x0001) //Count (as above) total number of DWORDS
- << WORD(0x0008) //Unknown
- << 0x10L
- << this->m_strDescription.c_str(); //This is the "Killed by" message when ID'd.
- pcAssesser->AddPacket(WORLD_SERVER,cmAssess,4);
-
- }
|