void ChatHandler::SpawnCreature(GameClient *pClient, char* pName, uint32 display_id, uint32 npcFlags, uint32 faction_id, uint32 level) { wowWData data; // Create the requested monster Character *chr = pClient->getCurrentChar(); float x = chr->getPositionX(); float y = chr->getPositionY(); float z = chr->getPositionZ(); float o = chr->getOrientation(); Unit* pUnit = new Unit(); UpdateMask unitMask; WorldServer::getSingletonPtr()->mObjectMgr.SetCreateUnitBits(unitMask); pUnit->Create(world.m_hiCreatureGuid++, (uint8*)pName, x, y, z, o); pUnit->setMapId(chr->getMapId()); pUnit->setZone(chr->getZone()); data.clear(); pUnit->setUpdateValue(OBJECT_FIELD_ENTRY, world.addCreatureName((uint8*)pUnit->getCreatureName())); pUnit->setUpdateFloatValue(OBJECT_FIELD_SCALE_X, 1.0f); pUnit->setUpdateValue(UNIT_FIELD_DISPLAYID, display_id); pUnit->setUpdateValue(UNIT_NPC_FLAGS , npcFlags); pUnit->setUpdateValue(UNIT_FIELD_FACTIONTEMPLATE , faction_id); pUnit->setUpdateValue(UNIT_FIELD_HEALTH, 100 + 30*level); pUnit->setUpdateValue(UNIT_FIELD_MAXHEALTH, 100 + 30*level); pUnit->setUpdateValue(UNIT_FIELD_LEVEL , level); pUnit->setUpdateFloatValue(UNIT_FIELD_COMBATREACH , 1.5f); pUnit->setUpdateFloatValue(UNIT_FIELD_MAXDAMAGE , 5.0f); pUnit->setUpdateFloatValue(UNIT_FIELD_MINDAMAGE , 8.0f); pUnit->setUpdateValue(UNIT_FIELD_BASEATTACKTIME, 1900); pUnit->setUpdateValue(UNIT_FIELD_BASEATTACKTIME+1, 2000); pUnit->setUpdateFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 2.0f); pUnit->CreateObject(&unitMask, &data, 0); // add to the world list of creatures WPAssert( pUnit->getGUID() != 0 ); world.mCreatures[pUnit->getGUID()] = pUnit; // send create message to everyone world.SendGlobalMessage(&data); DatabaseInterface *dbi = Database::getSingleton( ).createDatabaseInterface( ); dbi->saveCreature(pUnit); Database::getSingleton( ).removeDatabaseInterface(dbi); }
void WorldSession::_HandleUpdateObjectOpcode(WorldPacket& recvPacket) { uint8 utype; //uint8 hasTransport; uint32 usize, ublocks, readblocks=0; uint64 uguid; recvPacket >> ublocks; // >> hasTransport; //logdev("UpdateObject: blocks = %u, hasTransport = %u", ublocks, hasTransport); logdev("UpdateObject: blocks = %u", ublocks); while((recvPacket.rpos() < recvPacket.size())&& (readblocks < ublocks)) { recvPacket >> utype; switch(utype) { case UPDATETYPE_VALUES: { uguid = recvPacket.GetPackedGuid(); _ValuesUpdate(uguid,recvPacket); } break; case UPDATETYPE_MOVEMENT: { recvPacket >> uguid; // the guid is NOT packed here! uint8 tyid; Object *obj = objmgr.GetObj(uguid, true); // here we update also depleted objects, its just safer if(obj) tyid = obj->GetTypeId(); else // sometimes objects get deleted BEFORE a last update packet arrives, this must be handled also { tyid = GetTypeIdByGuid(uguid); logerror("Got UpdateObject_Movement for unknown object "I64FMT". Using typeid %u",uguid,(uint32)tyid); } if(obj) this->_MovementUpdate(tyid,uguid,recvPacket); } break; case UPDATETYPE_CREATE_OBJECT2: // will be sent when our very own character is created case UPDATETYPE_CREATE_OBJECT: // will be sent on any other object creation { uguid = recvPacket.GetPackedGuid(); uint8 objtypeid; recvPacket >> objtypeid; logdebug("Create Object type %u with guid "I64FMT,objtypeid,uguid); // dont create objects if already present in memory. // recreate every object except ourself! if(objmgr.GetObj(uguid)) { if(uguid != GetGuid()) { logdev("- already exists, deleting old, creating new object"); objmgr.Remove(uguid, false); // do not call script here, since the object does not really get deleted } else { logdev("- already exists, but not deleted (has our current GUID)"); } } // only if the obj didnt exist or was just deleted above, create it.... if(!objmgr.GetObj(uguid)) { switch(objtypeid) { case TYPEID_OBJECT: // no data to read { logerror("Recieved wrong UPDATETYPE_CREATE_OBJECT to create Object base type!"); logerror("%s",toHexDump((uint8*)recvPacket.contents(),recvPacket.size(),true).c_str()); } case TYPEID_ITEM: { Item *item = new Item(); item->Create(uguid); objmgr.Add(item); break; } case TYPEID_CONTAINER: { Bag *bag = new Bag(); bag->Create(uguid); objmgr.Add(bag); break; } case TYPEID_UNIT: { Unit *unit = new Unit(); unit->Create(uguid); objmgr.Add(unit); break; } case TYPEID_PLAYER: { if(GetGuid() == uguid) // objmgr.Add() would cause quite some trouble if we added ourself again break; Player *player = new Player(); player->Create(uguid); objmgr.Add(player); break; } case TYPEID_GAMEOBJECT: { GameObject *go = new GameObject(); go->Create(uguid); objmgr.Add(go); break; } case TYPEID_CORPSE: { Corpse *corpse = new Corpse(); corpse->Create(uguid); objmgr.Add(corpse); break; } case TYPEID_DYNAMICOBJECT: { DynamicObject *dobj = new DynamicObject(); dobj->Create(uguid); objmgr.Add(dobj); break; } } } else { logdebug("Obj "I64FMT" not created, already exists",uguid); } // ...regardless if it was freshly created or already present, update its values and stuff now... this->_MovementUpdate(objtypeid, uguid, recvPacket); this->_ValuesUpdate(uguid, recvPacket); // ...and ask the server for eventually missing data. _QueryObjectInfo(uguid); // call script "_OnObjectCreate" if(GetInstance()->GetScripts()->ScriptExists("_onobjectcreate")) { CmdSet Set; Set.defaultarg = toString(uguid); Set.arg[0] = toString(objtypeid); GetInstance()->GetScripts()->RunScript("_onobjectcreate", &Set); } // if our own character got finally created, we have successfully entered the world, // and should have gotten all info about our char already. } break; case UPDATETYPE_OUT_OF_RANGE_OBJECTS: { recvPacket >> usize; for(uint16 i=0; i<usize; i++) { uguid = recvPacket.GetPackedGuid(); // not 100% sure if this is correct logdebug("GUID "I64FMT" out of range",uguid); // call script just before object removal if(GetInstance()->GetScripts()->ScriptExists("_onobjectdelete")) { Object *del_obj = objmgr.GetObj(uguid); CmdSet Set; Set.defaultarg = toString(uguid); Set.arg[0] = del_obj ? toString(del_obj->GetTypeId()) : ""; Set.arg[1] = "true"; // out of range = true GetInstance()->GetScripts()->RunScript("_onobjectdelete", &Set); } objmgr.Remove(uguid, false); } } break; default: { logerror("UPDATE_OBJECT: Got unk updatetype 0x%X",utype); logerror("UPDATE_OBJECT: Read %u / %u bytes, skipped rest",recvPacket.rpos(),recvPacket.size()); logerror("%s",toHexDump((uint8*)recvPacket.contents(),recvPacket.size(),true).c_str()); char buf[100]; sprintf(buf,"Got unk updatetype=0x%X, read %u / %u bytes",utype,recvPacket.rpos(),recvPacket.size()); if(GetInstance()->GetConf()->dumpPackets) { char buf[100]; sprintf(buf,"Got unk updatetype=0x%X, read %u / %u bytes",utype,recvPacket.rpos(),recvPacket.size()); DumpPacket(recvPacket, recvPacket.rpos(),buf); } return; } } // switch readblocks++; } // while } // func
void ChatHandler::GenCreature(GameClient *pClient, uint32 StartId, uint32 EndId ,uint32 StepId ) { char* pName= "Def Name "; uint32 CurrentId=1; uint16 ModuloId=0; uint32 npcFlags=0; uint32 faction_id=0; uint32 level=10; wowWData data; // Create the requested monster Character *chr = pClient->getCurrentChar(); float x = chr->getPositionX(); float y = chr->getPositionY(); float z = chr->getPositionZ(); float o = chr->getOrientation(); for (CurrentId=StartId;CurrentId<=EndId;CurrentId++) { x+= (float) 5.0f; ModuloId++; if ( ModuloId>=StepId) { x-= (float) 5.0f *(float) ModuloId; ModuloId=0; y+= (float) 10.0f; } sprintf(pName,"Id:%i",CurrentId); Unit* pUnit = new Unit(); UpdateMask unitMask; WorldServer::getSingletonPtr()->mObjectMgr.SetCreateUnitBits(unitMask); pUnit->Create(world.m_hiCreatureGuid++, (uint8*)pName, x, y, z, o); pUnit->setMapId(chr->getMapId()); pUnit->setZone(chr->getZone()); data.clear(); pUnit->setUpdateValue(OBJECT_FIELD_ENTRY, world.addCreatureName((uint8*)pUnit->getCreatureName())); pUnit->setUpdateFloatValue(OBJECT_FIELD_SCALE_X, 1.0f); pUnit->setUpdateValue(UNIT_FIELD_DISPLAYID, CurrentId); pUnit->setUpdateValue(UNIT_NPC_FLAGS , npcFlags); pUnit->setUpdateValue(UNIT_FIELD_FACTIONTEMPLATE , faction_id); pUnit->setUpdateValue(UNIT_FIELD_HEALTH, 100 + 30*level); pUnit->setUpdateValue(UNIT_FIELD_MAXHEALTH, 100 + 30*level); pUnit->setUpdateValue(UNIT_FIELD_LEVEL , level); pUnit->setUpdateFloatValue(UNIT_FIELD_COMBATREACH , 1.5f); pUnit->setUpdateFloatValue(UNIT_FIELD_MAXDAMAGE , 5.0f); pUnit->setUpdateFloatValue(UNIT_FIELD_MINDAMAGE , 8.0f); pUnit->setUpdateValue(UNIT_FIELD_BASEATTACKTIME, 1900); pUnit->setUpdateValue(UNIT_FIELD_BASEATTACKTIME+1, 2000); pUnit->setUpdateFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 2.0f); pUnit->CreateObject(&unitMask, &data, 0); // add to the world list of creatures WPAssert( pUnit->getGUID() != 0 ); world.mCreatures[pUnit->getGUID()] = pUnit; // send create message to everyone world.SendGlobalMessage(&data); DatabaseInterface *dbi = Database::getSingleton( ).createDatabaseInterface( ); char sql[512]; sprintf(sql, "insert into skin set id_skin='%i',name='%s',type='0',race='0', gender='0'", CurrentId,pName); dbi->doQuery(sql); //dbi->saveCreature(pUnit); Database::getSingleton( ).removeDatabaseInterface(dbi); } }