void WorldSession::SendPetitionQueryOpcode(uint64 petitionguid) { uint64 ownerguid = 0; uint32 type; std::string name = "NO_NAME_FOR_GUID"; uint8 signs = 0; QueryResult_AutoPtr result = CharacterDatabase.PQuery( "SELECT ownerguid, name, " " (SELECT COUNT(playerguid) FROM petition_sign WHERE petition_sign.petitionguid = '%u') AS signs, " " type " "FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid), GUID_LOPART(petitionguid)); if (result) { Field* fields = result->Fetch(); ownerguid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER); name = fields[1].GetCppString(); signs = fields[2].GetUInt8(); type = fields[3].GetUInt32(); } else { sLog->outDebug("CMSG_PETITION_QUERY failed for petition (GUID: %u)", GUID_LOPART(petitionguid)); return; } WorldPacket data(SMSG_PETITION_QUERY_RESPONSE, (4+8+name.size()+1+1+4*13)); data << GUID_LOPART(petitionguid); // guild/team guid (in Trinity always same as GUID_LOPART(petition guid) data << ownerguid; // charter owner guid data << name; // name (guild/arena team) data << uint8(0); // 1 if (type == 9) { data << uint32(9); data << uint32(9); data << uint32(0); // bypass client - side limitation, a different value is needed here for each petition } else { data << type-1; data << type-1; data << type; // bypass client - side limitation, a different value is needed here for each petition } data << uint32(0); // 5 data << uint32(0); // 6 data << uint32(0); // 7 data << uint32(0); // 8 data << uint16(0); // 9 2 bytes field data << uint32(0); // 10 data << uint32(0); // 11 data << uint32(0); // 13 count of next strings? data << uint32(0); // 14 if (type == 9) data << uint32(0); // 15 0 - guild, 1 - arena team else data << uint32(1); SendPacket(&data); }
void WorldSession::SendPetitionQueryOpcode(uint64 petitionguid) { uint64 ownerguid = 0; uint32 type; std::string name = "NO_NAME_FOR_GUID"; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION); stmt->setUInt32(0, GUID_LOPART(petitionguid)); PreparedQueryResult result = CharacterDatabase.Query(stmt); if (result) { Field* fields = result->Fetch(); ownerguid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER); name = fields[1].GetString(); type = fields[2].GetUInt8(); } else { TC_LOG_DEBUG("network", "CMSG_PETITION_QUERY failed for petition (GUID: %u)", GUID_LOPART(petitionguid)); return; } WorldPacket data(SMSG_PETITION_QUERY_RESPONSE, (4+8+name.size()+1+1+4*12+2+10)); data << uint32(GUID_LOPART(petitionguid)); // guild/team guid (in Trinity always same as GUID_LOPART(petition guid) data << uint64(ownerguid); // charter owner guid data << name; // name (guild/arena team) data << uint8(0); // some string if (type == GUILD_CHARTER_TYPE) { uint32 needed = sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS); data << uint32(needed); data << uint32(needed); data << uint32(0); // bypass client - side limitation, a different value is needed here for each petition } else { data << uint32(type-1); data << uint32(type-1); data << uint32(type); // bypass client - side limitation, a different value is needed here for each petition } data << uint32(0); // 5 data << uint32(0); // 6 data << uint32(0); // 7 data << uint32(0); // 8 data << uint16(0); // 9 2 bytes field data << uint32(0); // 10 data << uint32(0); // 11 data << uint32(0); // 13 count of next strings? for (int i = 0; i < 10; ++i) data << uint8(0); // some string data << uint32(0); // 14 data << uint32(type != GUILD_CHARTER_TYPE); // 15 0 - guild, 1 - arena team SendPacket(&data); }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); uint64 guid; recvData >> guid; Player* player = HashMapHolder<Player>::Find(guid); if (!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.appendPackGUID(guid); data << (uint32) GROUP_UPDATE_FLAG_STATUS; data << (uint16) MEMBER_STATUS_OFFLINE; SendPacket(&data); return; } Pet* pet = player->GetPet(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); // Needs checked for 406a data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.append(player->GetPackGUID()); /* * uint32 mask1 = 0x00040BFF; // common mask, real flags used 0x000040BFF * if (pet) * mask1 = 0x7FFFFFFF; // for hunters and other classes with pets */ uint32 mask1 = GROUP_UPDATE_FULL; if (!pet) mask1 &= ~GROUP_UPDATE_PET; Powers powerType = player->getPowerType(); data << uint32(mask1); // group update mask data << uint16(MEMBER_STATUS_ONLINE); // member's online status, GROUP_UPDATE_FLAG_STATUS data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP data << uint8 (powerType); // GROUP_UPDATE_FLAG_POWER_TYPE data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL data << uint16(player->GetZoneId()); // GROUP_UPDATE_FLAG_ZONE data << uint16(player->GetPositionX()); // GROUP_UPDATE_FLAG_POSITION data << uint16(player->GetPositionY()); // GROUP_UPDATE_FLAG_POSITION data << uint16(player->GetPositionZ()); // GROUP_UPDATE_FLAG_POSITION // GROUP_UPDATE_FLAG_AURAS // if true client clears auras that are not covered by auramask // TODO: looks like now client requires all active auras to be in the beginning of the auramask // e.g. if you have holes in the aura mask the values after are ignored. data << uint8(1); uint64 auramask = 0; size_t maskPos = data.wpos(); data << uint64(auramask); // placeholder data << uint32(MAX_AURAS); // if true client clears auras that are not covered by auramask for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication const* aurApp = player->GetVisibleAura(i)) { auramask |= (uint64(1) << i); data << uint32(aurApp->GetBase()->GetId()); data << uint16(aurApp->GetFlags()); if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT) { for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) { if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) data << int32(eff->GetAmount()); else data << int32(0); } } } } data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS if (pet) { Powers petpowertype = pet->getPowerType(); data << uint64(pet->GetGUID()); // GROUP_UPDATE_FLAG_PET_GUID data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(pet->GetDisplayId()); // GROUP_UPDATE_FLAG_PET_MODEL_ID data << uint32(pet->GetHealth()); // GROUP_UPDATE_FLAG_PET_CUR_HP data << uint32(pet->GetMaxHealth()); // GROUP_UPDATE_FLAG_PET_MAX_HP data << uint8 (petpowertype); // GROUP_UPDATE_FLAG_PET_POWER_TYPE data << uint16(pet->GetPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_CUR_POWER data << uint16(pet->GetMaxPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_MAX_POWER // GROUP_UPDATE_FLAG_PET_AURAS // if true client clears auras that are not covered by auramask // TODO: looks like now client requires all active auras to be in the beginning of the auramask // e.g. if you have holes in the aura mask the values after are ignored. data << uint8(1); uint64 petauramask = 0; size_t petMaskPos = data.wpos(); data << uint64(petauramask); // placeholder data << uint32(MAX_AURAS); // client reads (64) Bits from auramask for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication const* aurApp = pet->GetVisibleAura(i)) { petauramask |= (uint64(1) << i); data << uint32(aurApp->GetBase()->GetId()); data << uint16(aurApp->GetFlags()); if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT) { for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) { if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) data << int32(eff->GetAmount()); else data << int32(0); } } } } data.put<uint64>(petMaskPos, petauramask); // GROUP_UPDATE_FLAG_PET_AURAS } // else not needed, flags do not include any PET_ update // GROUP_UPDATE_FLAG_PHASE data << uint32(8); // either 0 or 8, same unk found in SMSG_PHASESHIFT data << uint32(0); // count // for (count) *data << uint16(phaseId) SendPacket(&data); }
void LoadDBCStores(const std::string& dataPath) { std::string dbcPath = dataPath+"dbc/"; const uint32 DBCFilesCount = 60; StoreProblemList bad_dbc_files; uint32 availableDbcLocales = 0xFFFFFFFF; LoadDBC(availableDbcLocales, bad_dbc_files, sAreaStore, dbcPath, "AreaTable.dbc"); // must be after sAreaStore loading for (uint32 i = 0; i < sAreaStore.GetNumRows(); ++i) // areaflag numbered from 0 { if (AreaTableEntry const* area = sAreaStore.LookupEntry(i)) { // fill AreaId->DBC records sAreaFlagByAreaID.insert(AreaFlagByAreaID::value_type(uint16(area->ID), area->exploreFlag)); // fill MapId->DBC records ( skip sub zones and continents) if (area->zone == 0 && area->mapid != 0 && area->mapid != 1 && area->mapid != 530) sAreaFlagByMapID.insert(AreaFlagByMapID::value_type(area->mapid, area->exploreFlag)); } } LoadDBC(availableDbcLocales, bad_dbc_files, sAreaTriggerStore, dbcPath, "AreaTrigger.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sAuctionHouseStore, dbcPath, "AuctionHouse.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sBankBagSlotPricesStore, dbcPath, "BankBagSlotPrices.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sBattlemasterListStore, dbcPath, "BattlemasterList.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCharStartOutfitStore, dbcPath, "CharStartOutfit.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCharTitlesStore, dbcPath, "CharTitles.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sChatChannelsStore, dbcPath, "ChatChannels.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sChrClassesStore, dbcPath, "ChrClasses.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sChrRacesStore, dbcPath, "ChrRaces.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCinematicSequencesStore, dbcPath, "CinematicSequences.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureDisplayInfoStore, dbcPath, "CreatureDisplayInfo.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureFamilyStore, dbcPath, "CreatureFamily.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureSpellDataStore, dbcPath, "CreatureSpellData.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sDurabilityCostsStore, dbcPath, "DurabilityCosts.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sDurabilityQualityStore, dbcPath, "DurabilityQuality.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sEmotesStore, dbcPath, "Emotes.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sEmotesTextStore, dbcPath, "EmotesText.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sFactionStore, dbcPath, "Faction.dbc"); for (uint32 i = 0;i < sFactionStore.GetNumRows(); ++i) { FactionEntry const * faction = sFactionStore.LookupEntry(i); if (faction && faction->team) { SimpleFactionsList &flist = sFactionTeamMap[faction->team]; flist.push_back(i); } } LoadDBC(availableDbcLocales, bad_dbc_files, sFactionTemplateStore, dbcPath, "FactionTemplate.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGemPropertiesStore, dbcPath, "GemProperties.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGtCombatRatingsStore, dbcPath, "gtCombatRatings.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToMeleeCritBaseStore, dbcPath, "gtChanceToMeleeCritBase.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToMeleeCritStore, dbcPath, "gtChanceToMeleeCrit.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToSpellCritBaseStore, dbcPath, "gtChanceToSpellCritBase.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToSpellCritStore, dbcPath, "gtChanceToSpellCrit.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGtOCTRegenHPStore, dbcPath, "gtOCTRegenHP.dbc"); //LoadDBC(availableDbcLocales, bad_dbc_files, sGtOCTRegenMPStore, dbcPath, "gtOCTRegenMP.dbc"); -- not used currently LoadDBC(availableDbcLocales, bad_dbc_files, sGtRegenHPPerSptStore, dbcPath, "gtRegenHPPerSpt.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGtRegenMPPerSptStore, dbcPath, "gtRegenMPPerSpt.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sItemStore, dbcPath, "Item.dbc"); //LoadDBC(availableDbcLocales, bad_dbc_files, sItemDisplayInfoStore, dbcPath, "ItemDisplayInfo.dbc"); -- not used currently //LoadDBC(availableDbcLocales, bad_dbc_files, sItemCondExtCostsStore, dbcPath, "ItemCondExtCosts.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sItemExtendedCostStore, dbcPath, "ItemExtendedCost.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sItemRandomPropertiesStore, dbcPath, "ItemRandomProperties.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sItemRandomSuffixStore, dbcPath, "ItemRandomSuffix.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sItemSetStore, dbcPath, "ItemSet.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sLockStore, dbcPath, "Lock.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sMailTemplateStore, dbcPath, "MailTemplate.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sMapStore, dbcPath, "Map.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sQuestSortStore, dbcPath, "QuestSort.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sRandomPropertiesPointsStore, dbcPath, "RandPropPoints.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSkillLineStore, dbcPath, "SkillLine.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSkillLineAbilityStore, dbcPath, "SkillLineAbility.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSoundEntriesStore, dbcPath, "SoundEntries.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellStore, dbcPath, "Spell.dbc"); for (uint32 i = 1; i < sSpellStore.GetNumRows(); ++i) { SpellEntry const * spell = sSpellStore.LookupEntry(i); if (spell && spell->Category) sSpellCategoryStore[spell->Category].insert(i); // DBC not support uint64 fields but SpellEntry have SpellFamilyFlags mapped at 2 uint32 fields // uint32 field already converted to bigendian if need, but must be swapped for correct uint64 bigendian view #if SKYFIRE_ENDIAN == SKYFIRE_BIGENDIAN std::swap(*((uint32*)(&spell->SpellFamilyFlags)), *(((uint32*)(&spell->SpellFamilyFlags))+1)); #endif } for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) { SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j); if (!skillLine) continue; SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId); if (spellInfo && (spellInfo->Attributes & (SPELL_ATTR_ABILITY | SPELL_ATTR_PASSIVE | SPELL_ATTR_HIDDEN_CLIENTSIDE | SPELL_ATTR_HIDE_IN_COMBAT_LOG)) == (SPELL_ATTR_ABILITY | SPELL_ATTR_PASSIVE | SPELL_ATTR_HIDDEN_CLIENTSIDE | SPELL_ATTR_HIDE_IN_COMBAT_LOG)) { for (unsigned int i = 1; i < sCreatureFamilyStore.GetNumRows(); ++i) { CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(i); if (!cFamily) continue; if (skillLine->skillId != cFamily->skillLine[0] && skillLine->skillId != cFamily->skillLine[1]) continue; sPetFamilySpellsStore[i].insert(spellInfo->Id); } } } LoadDBC(availableDbcLocales, bad_dbc_files, sSpellCastTimesStore, dbcPath, "SpellCastTimes.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellDurationStore, dbcPath, "SpellDuration.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellFocusObjectStore, dbcPath, "SpellFocusObject.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellItemEnchantmentStore, dbcPath, "SpellItemEnchantment.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellItemEnchantmentConditionStore, dbcPath, "SpellItemEnchantmentCondition.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellRadiusStore, dbcPath, "SpellRadius.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellRangeStore, dbcPath, "SpellRange.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellShapeshiftStore, dbcPath, "SpellShapeshiftForm.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sStableSlotPricesStore, dbcPath, "StableSlotPrices.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSummonPropertiesStore, dbcPath, "SummonProperties.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sTalentStore, dbcPath, "Talent.dbc"); // create talent spells set for (unsigned int i = 0; i < sTalentStore.GetNumRows(); ++i) { TalentEntry const *talentInfo = sTalentStore.LookupEntry(i); if (!talentInfo) continue; for (int j = 0; j < 5; j++) if (talentInfo->RankID[j]) sTalentSpellPosMap[talentInfo->RankID[j]] = TalentSpellPos(i, j); } LoadDBC(availableDbcLocales, bad_dbc_files, sTalentTabStore, dbcPath, "TalentTab.dbc"); // prepare fast data access to bit pos of talent ranks for use at inspecting { // fill table by amount of talent ranks and fill sTalentTabBitSizeInInspect // store in with (row, col, talent)->size key for correct sorting by (row, col) typedef std::map<uint32, uint32> TalentBitSize; TalentBitSize sTalentBitSize; for (uint32 i = 1; i < sTalentStore.GetNumRows(); ++i) { TalentEntry const *talentInfo = sTalentStore.LookupEntry(i); if (!talentInfo) continue; TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab); if (!talentTabInfo) continue; // find talent rank uint32 curtalent_maxrank = 0; for (uint32 k = 5; k > 0; --k) { if (talentInfo->RankID[k-1]) { curtalent_maxrank = k; break; } } sTalentBitSize[(talentInfo->Row<<24) + (talentInfo->Col<<16)+talentInfo->TalentID] = curtalent_maxrank; sTalentTabSizeInInspect[talentInfo->TalentTab] += curtalent_maxrank; } // now have all max ranks (and then bit amount used for store talent ranks in inspect) for (uint32 talentTabId = 1; talentTabId < sTalentTabStore.GetNumRows(); ++talentTabId) { TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry(talentTabId); if (!talentTabInfo) continue; // prevent memory corruption; otherwise cls will become 12 below if ((talentTabInfo->ClassMask & CLASSMASK_ALL_PLAYABLE) == 0) continue; // store class talent tab pages uint32 cls = 1; for (uint32 m=1; !(m & talentTabInfo->ClassMask) && cls < MAX_CLASSES; m <<= 1, ++cls) {} sTalentTabPages[cls][talentTabInfo->tabpage]=talentTabId; // add total amount bits for first rank starting from talent tab first talent rank pos. uint32 pos = 0; for (TalentBitSize::iterator itr = sTalentBitSize.begin(); itr != sTalentBitSize.end(); ++itr) { uint32 talentId = itr->first & 0xFFFF; TalentEntry const *talentInfo = sTalentStore.LookupEntry( talentId); if (!talentInfo) continue; if (talentInfo->TalentTab != talentTabId) continue; sTalentPosInInspect[talentId] = pos; pos+= itr->second; } } } LoadDBC(availableDbcLocales, bad_dbc_files, sTaxiNodesStore, dbcPath, "TaxiNodes.dbc"); // Initialize global taxinodes mask memset(sTaxiNodesMask, 0, sizeof(sTaxiNodesMask)); for (uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i) { if (sTaxiNodesStore.LookupEntry(i)) { uint8 field = (uint8)((i - 1) / 32); uint32 submask = 1<<((i-1)%32); sTaxiNodesMask[field] |= submask; } } LoadDBC(availableDbcLocales, bad_dbc_files, sTaxiPathStore, dbcPath, "TaxiPath.dbc"); for (uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++i) if (TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(i)) sTaxiPathSetBySource[entry->from][entry->to] = TaxiPathBySourceAndDestination(entry->ID, entry->price); uint32 pathCount = sTaxiPathStore.GetNumRows(); //## TaxiPathNode.dbc ## Loaded only for initialization different structures LoadDBC(availableDbcLocales, bad_dbc_files, sTaxiPathNodeStore, dbcPath, "TaxiPathNode.dbc"); // Calculate path nodes count std::vector<uint32> pathLength; pathLength.resize(pathCount); // 0 and some other indexes not used for (uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i) if (TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i)) ++pathLength[entry->path]; // Set path length sTaxiPathNodesByPath.resize(pathCount); // 0 and some other indexes not used for (uint32 i = 1; i < sTaxiPathNodesByPath.size(); ++i) sTaxiPathNodesByPath[i].resize(pathLength[i]); // fill data for (uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i) if (TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i)) sTaxiPathNodesByPath[entry->path][entry->index] = TaxiPathNode(entry->mapid, entry->x, entry->y, entry->z, entry->actionFlag, entry->delay); sTaxiPathNodeStore.Clear(); LoadDBC(availableDbcLocales, bad_dbc_files, sTotemCategoryStore, dbcPath, "TotemCategory.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sWMOAreaTableStore, dbcPath, "WMOAreaTable.dbc"); for (uint32 i = 0; i < sWMOAreaTableStore.GetNumRows(); ++i) { if (WMOAreaTableEntry const* entry = sWMOAreaTableStore.LookupEntry(i)) { sWMOAreaInfoByTripple.insert(WMOAreaInfoByTripple::value_type(WMOAreaTableTripple(entry->rootId, entry->adtId, entry->groupId), entry)); } } LoadDBC(availableDbcLocales, bad_dbc_files, sWorldMapAreaStore, dbcPath, "WorldMapArea.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sWorldSafeLocsStore, dbcPath, "WorldSafeLocs.dbc"); // error checks if (bad_dbc_files.size() >= DBCFilesCount) { sLog->outError("\nIncorrect DataDir value in Trinityd.conf or ALL required *.dbc files (%d) not found by path: %sdbc", DBCFilesCount, dataPath.c_str()); exit(1); } else if (!bad_dbc_files.empty()) { std::string str; for (std::list<std::string>::iterator i = bad_dbc_files.begin(); i != bad_dbc_files.end(); ++i) str += *i + "\n"; sLog->outError("\nSome required *.dbc files (%u from %d) not found or not compatible:\n%s", bad_dbc_files.size(), DBCFilesCount, str.c_str()); exit(1); } // check at up-to-date DBC files (53085 is last added spell in 2.4.3) // check at up-to-date DBC files (17514 is last ID in SkillLineAbilities in 2.4.3) // check at up-to-date DBC files (598 is last map added in 2.4.3) // check at up-to-date DBC files (1127 is last gem property added in 2.4.3) // check at up-to-date DBC files (2425 is last item extended cost added in 2.4.3) // check at up-to-date DBC files (71 is last char title added in 2.4.3) // check at up-to-date DBC files (1768 is last area added in 2.4.3) if ( !sSpellStore.LookupEntry(53085) || !sSkillLineAbilityStore.LookupEntry(17514) || !sMapStore.LookupEntry(598) || !sGemPropertiesStore.LookupEntry(1127) || !sItemExtendedCostStore.LookupEntry(2425) || !sCharTitlesStore.LookupEntry(71) || !sAreaStore.LookupEntry(1768)) { sLog->outError("\nYou have _outdated_ DBC files. Please extract correct versions from 2.4.3 client."); exit(1); } sLog->outString(); sLog->outString(">> Initialized %d data stores", DBCFilesCount); }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data ) { DEBUG_LOG("WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); ObjectGuid guid; recv_data >> guid; Player *player = sObjectMgr.GetPlayer(guid); if(!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data << guid.WriteAsPacked(); data << uint32(GROUP_UPDATE_FLAG_STATUS); data << uint16(MEMBER_STATUS_OFFLINE); SendPacket(&data); return; } Pet *pet = player->GetPet(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data << player->GetPackGUID(); uint32 mask1 = 0x00040BFF; // common mask, real flags used 0x000040BFF if(pet) mask1 = 0x7FFFFFFF; // for hunters and other classes with pets Powers powerType = player->getPowerType(); data << uint32(mask1); // group update mask data << uint16(MEMBER_STATUS_ONLINE); // member's online status data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP data << uint8(powerType); // GROUP_UPDATE_FLAG_POWER_TYPE data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL data << uint16(player->GetZoneId()); // GROUP_UPDATE_FLAG_ZONE data << uint16(player->GetPositionX()); // GROUP_UPDATE_FLAG_POSITION data << uint16(player->GetPositionY()); // GROUP_UPDATE_FLAG_POSITION uint64 auramask = 0; size_t maskPos = data.wpos(); data << uint64(auramask); // placeholder for(uint8 i = 0; i < MAX_AURAS; ++i) { if(uint32 aura = player->GetVisibleAura(i)) { auramask |= (uint64(1) << i); data << uint32(aura); data << uint8(1); } } data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS if(pet) { Powers petpowertype = pet->getPowerType(); data << pet->GetObjectGuid(); // GROUP_UPDATE_FLAG_PET_GUID data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(pet->GetDisplayId()); // GROUP_UPDATE_FLAG_PET_MODEL_ID data << uint32(pet->GetHealth()); // GROUP_UPDATE_FLAG_PET_CUR_HP data << uint32(pet->GetMaxHealth()); // GROUP_UPDATE_FLAG_PET_MAX_HP data << uint8(petpowertype); // GROUP_UPDATE_FLAG_PET_POWER_TYPE data << uint16(pet->GetPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_CUR_POWER data << uint16(pet->GetMaxPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_MAX_POWER uint64 petauramask = 0; size_t petMaskPos = data.wpos(); data << uint64(petauramask); // placeholder for(uint8 i = 0; i < MAX_AURAS; ++i) { if(uint32 petaura = pet->GetVisibleAura(i)) { petauramask |= (uint64(1) << i); data << uint32(petaura); data << uint8(1); } } data.put<uint64>(petMaskPos, petauramask); // GROUP_UPDATE_FLAG_PET_AURAS } else { data << uint8(0); // GROUP_UPDATE_FLAG_PET_NAME data << uint64(0); // GROUP_UPDATE_FLAG_PET_AURAS } SendPacket(&data); }
bool ConvertADT(char *filename, char *filename2, int cell_y, int cell_x, uint32 build) { ADT_file adt; if (!adt.loadFile(WorldMpq, filename)) return false; memset(liquid_show, 0, sizeof(liquid_show)); memset(liquid_type, 0, sizeof(liquid_type)); // Prepare map header map_fileheader map; map.mapMagic = *(uint32 const*)MAP_MAGIC; map.versionMagic = *(uint32 const*)MAP_VERSION_MAGIC; map.buildMagic = build; // Get area flags data for (int i = 0; i < ADT_CELLS_PER_GRID; ++i) { for (int j = 0; j < ADT_CELLS_PER_GRID; ++j) { adt_MCNK* cell = adt.cells[i][j]; uint32 areaid = cell->areaid; if (areaid && areaid <= maxAreaId) { if (areas[areaid] != 0xFFFF) { area_flags[i][j] = areas[areaid]; continue; } printf("File: %s\nCan't find area flag for areaid %u [%d, %d].\n", filename, areaid, cell->ix, cell->iy); } area_flags[i][j] = 0xffff; } } //============================================ // Try pack area data //============================================ bool fullAreaData = false; uint32 areaflag = area_flags[0][0]; for (int y=0;y<ADT_CELLS_PER_GRID;y++) { for(int x=0;x<ADT_CELLS_PER_GRID;x++) { if(area_flags[y][x]!=areaflag) { fullAreaData = true; break; } } } map.areaMapOffset = sizeof(map); map.areaMapSize = sizeof(map_areaHeader); map_areaHeader areaHeader; areaHeader.fourcc = *(uint32 const*)MAP_AREA_MAGIC; areaHeader.flags = 0; if (fullAreaData) { areaHeader.gridArea = 0; map.areaMapSize+=sizeof(area_flags); } else { areaHeader.flags |= MAP_AREA_NO_AREA; areaHeader.gridArea = (uint16)areaflag; } // // Get Height map from grid // for (int i=0;i<ADT_CELLS_PER_GRID;i++) { for(int j=0;j<ADT_CELLS_PER_GRID;j++) { adt_MCNK * cell = adt.cells[i][j]; if (!cell) continue; // Height values for triangles stored in order: // 1 2 3 4 5 6 7 8 9 // 10 11 12 13 14 15 16 17 // 18 19 20 21 22 23 24 25 26 // 27 28 29 30 31 32 33 34 // . . . . . . . . // For better get height values merge it to V9 and V8 map // V9 height map: // 1 2 3 4 5 6 7 8 9 // 18 19 20 21 22 23 24 25 26 // . . . . . . . . // V8 height map: // 10 11 12 13 14 15 16 17 // 27 28 29 30 31 32 33 34 // . . . . . . . . // Set map height as grid height for (int y=0; y <= ADT_CELL_SIZE; y++) { int cy = i*ADT_CELL_SIZE + y; for (int x=0; x <= ADT_CELL_SIZE; x++) { int cx = j*ADT_CELL_SIZE + x; V9[cy][cx]=cell->ypos; } } for (int y=0; y < ADT_CELL_SIZE; y++) { int cy = i*ADT_CELL_SIZE + y; for (int x=0; x < ADT_CELL_SIZE; x++) { int cx = j*ADT_CELL_SIZE + x; V8[cy][cx]=cell->ypos; } } // Get custom height adt_MCVT *v = cell->getMCVT(); if (!v) continue; // get V9 height map for (int y=0; y <= ADT_CELL_SIZE; y++) { int cy = i*ADT_CELL_SIZE + y; for (int x=0; x <= ADT_CELL_SIZE; x++) { int cx = j*ADT_CELL_SIZE + x; V9[cy][cx]+=v->height_map[y*(ADT_CELL_SIZE*2+1)+x]; } } // get V8 height map for (int y=0; y < ADT_CELL_SIZE; y++) { int cy = i*ADT_CELL_SIZE + y; for (int x=0; x < ADT_CELL_SIZE; x++) { int cx = j*ADT_CELL_SIZE + x; V8[cy][cx]+=v->height_map[y*(ADT_CELL_SIZE*2+1)+ADT_CELL_SIZE+1+x]; } } } } //============================================ // Try pack height data //============================================ float maxHeight = -20000; float minHeight = 20000; for (int y=0; y<ADT_GRID_SIZE; y++) { for(int x=0;x<ADT_GRID_SIZE;x++) { float h = V8[y][x]; if (maxHeight < h) maxHeight = h; if (minHeight > h) minHeight = h; } } for (int y=0; y<=ADT_GRID_SIZE; y++) { for(int x=0;x<=ADT_GRID_SIZE;x++) { float h = V9[y][x]; if (maxHeight < h) maxHeight = h; if (minHeight > h) minHeight = h; } } // Check for allow limit minimum height (not store height in deep ochean - allow save some memory) if (CONF_allow_height_limit && minHeight < CONF_use_minHeight) { for (int y=0; y<ADT_GRID_SIZE; y++) for(int x=0;x<ADT_GRID_SIZE;x++) if (V8[y][x] < CONF_use_minHeight) V8[y][x] = CONF_use_minHeight; for (int y=0; y<=ADT_GRID_SIZE; y++) for(int x=0;x<=ADT_GRID_SIZE;x++) if (V9[y][x] < CONF_use_minHeight) V9[y][x] = CONF_use_minHeight; if (minHeight < CONF_use_minHeight) minHeight = CONF_use_minHeight; if (maxHeight < CONF_use_minHeight) maxHeight = CONF_use_minHeight; } map.heightMapOffset = map.areaMapOffset + map.areaMapSize; map.heightMapSize = sizeof(map_heightHeader); map_heightHeader heightHeader; heightHeader.fourcc = *(uint32 const*)MAP_HEIGHT_MAGIC; heightHeader.flags = 0; heightHeader.gridHeight = minHeight; heightHeader.gridMaxHeight = maxHeight; if (maxHeight == minHeight) heightHeader.flags |= MAP_HEIGHT_NO_HEIGHT; // Not need store if flat surface if (CONF_allow_float_to_int && (maxHeight - minHeight) < CONF_flat_height_delta_limit) heightHeader.flags |= MAP_HEIGHT_NO_HEIGHT; // Try store as packed in uint16 or uint8 values if (!(heightHeader.flags & MAP_HEIGHT_NO_HEIGHT)) { float step; // Try Store as uint values if (CONF_allow_float_to_int) { float diff = maxHeight - minHeight; if (diff < CONF_float_to_int8_limit) // As uint8 (max accuracy = CONF_float_to_int8_limit/256) { heightHeader.flags|=MAP_HEIGHT_AS_INT8; step = selectUInt8StepStore(diff); } else if (diff<CONF_float_to_int16_limit) // As uint16 (max accuracy = CONF_float_to_int16_limit/65536) { heightHeader.flags|=MAP_HEIGHT_AS_INT16; step = selectUInt16StepStore(diff); } } // Pack it to int values if need if (heightHeader.flags&MAP_HEIGHT_AS_INT8) { for (int y=0; y<ADT_GRID_SIZE; y++) for(int x=0;x<ADT_GRID_SIZE;x++) uint8_V8[y][x] = uint8((V8[y][x] - minHeight) * step + 0.5f); for (int y=0; y<=ADT_GRID_SIZE; y++) for(int x=0;x<=ADT_GRID_SIZE;x++) uint8_V9[y][x] = uint8((V9[y][x] - minHeight) * step + 0.5f); map.heightMapSize+= sizeof(uint8_V9) + sizeof(uint8_V8); } else if (heightHeader.flags&MAP_HEIGHT_AS_INT16) { for (int y=0; y<ADT_GRID_SIZE; y++) for(int x=0;x<ADT_GRID_SIZE;x++) uint16_V8[y][x] = uint16((V8[y][x] - minHeight) * step + 0.5f); for (int y=0; y<=ADT_GRID_SIZE; y++) for(int x=0;x<=ADT_GRID_SIZE;x++) uint16_V9[y][x] = uint16((V9[y][x] - minHeight) * step + 0.5f); map.heightMapSize+= sizeof(uint16_V9) + sizeof(uint16_V8); } else map.heightMapSize+= sizeof(V9) + sizeof(V8); } // Get liquid map for grid (in WOTLK used MH2O chunk) adt_MH2O * h2o = adt.a_grid->getMH2O(); if (h2o) { for (int i=0;i<ADT_CELLS_PER_GRID;i++) { for(int j=0;j<ADT_CELLS_PER_GRID;j++) { adt_liquid_header *h = h2o->getLiquidData(i,j); if (!h) continue; int count = 0; uint64 show = h2o->getLiquidShowMap(h); for (int y=0; y < h->height;y++) { int cy = i*ADT_CELL_SIZE + y + h->yOffset; for (int x=0; x < h->width; x++) { int cx = j*ADT_CELL_SIZE + x + h->xOffset; if (show & 1) { liquid_show[cy][cx] = true; ++count; } show>>=1; } } uint32 type = LiqType[h->liquidType]; switch (type) { case LIQUID_TYPE_WATER: liquid_type[i][j] |= MAP_LIQUID_TYPE_WATER; break; case LIQUID_TYPE_OCEAN: liquid_type[i][j] |= MAP_LIQUID_TYPE_OCEAN; break; case LIQUID_TYPE_MAGMA: liquid_type[i][j] |= MAP_LIQUID_TYPE_MAGMA; break; case LIQUID_TYPE_SLIME: liquid_type[i][j] |= MAP_LIQUID_TYPE_SLIME; break; default: printf("\nCan't find Liquid type %u for map %s\nchunk %d,%d\n", h->liquidType, filename, i, j); break; } // Dark water detect if (type == LIQUID_TYPE_OCEAN) { uint8 *lm = h2o->getLiquidLightMap(h); if (!lm) liquid_type[i][j]|=MAP_LIQUID_TYPE_DARK_WATER; } if (!count && liquid_type[i][j]) printf("Wrong liquid detect in MH2O chunk"); float *height = h2o->getLiquidHeightMap(h); int pos = 0; for (int y=0; y<=h->height;y++) { int cy = i*ADT_CELL_SIZE + y + h->yOffset; for (int x=0; x<= h->width; x++) { int cx = j*ADT_CELL_SIZE + x + h->xOffset; if (height) liquid_height[cy][cx] = height[pos]; else liquid_height[cy][cx] = h->heightLevel1; pos++; } } } } } else { // Get from MCLQ chunk (old) for (int i=0;i<ADT_CELLS_PER_GRID;i++)
void AuthSocket::LoadRealmlist(ByteBuffer &pkt, uint32 acctid) { switch(_build) { case 5875: // 1.12.1 case 6005: // 1.12.2 { pkt << uint32(0); // unused value pkt << uint8(sRealmList.size()); for(RealmList::RealmMap::const_iterator i = sRealmList.begin(); i != sRealmList.end(); ++i) { uint8 AmountOfCharacters; // No SQL injection. id of realm is controlled by the database. QueryResult *result = LoginDatabase.PQuery( "SELECT numchars FROM realmcharacters WHERE realmid = '%d' AND acctid='%u'", i->second.m_ID, acctid); if( result ) { Field *fields = result->Fetch(); AmountOfCharacters = fields[0].GetUInt8(); delete result; } else AmountOfCharacters = 0; bool ok_build = std::find(i->second.realmbuilds.begin(), i->second.realmbuilds.end(), _build) != i->second.realmbuilds.end(); RealmBuildInfo const* buildInfo = ok_build ? FindBuildInfo(_build) : NULL; if (!buildInfo) buildInfo = &i->second.realmBuildInfo; RealmFlags realmflags = i->second.realmflags; // 1.x clients not support explicitly REALM_FLAG_SPECIFYBUILD, so manually form similar name as show in more recent clients std::string name = i->first; if (realmflags & REALM_FLAG_SPECIFYBUILD) { char buf[20]; snprintf(buf, 20," (%u,%u,%u)", buildInfo->major_version, buildInfo->minor_version, buildInfo->bugfix_version); name += buf; } // Show offline state for unsupported client builds and locked realms (1.x clients not support locked state show) if (!ok_build || (i->second.allowedSecurityLevel > _accountSecurityLevel)) realmflags = RealmFlags(realmflags | REALM_FLAG_OFFLINE); pkt << uint32(i->second.icon); // realm type pkt << uint8(realmflags); // realmflags pkt << name; // name pkt << i->second.address; // address pkt << float(i->second.populationLevel); pkt << uint8(AmountOfCharacters); pkt << uint8(i->second.timezone); // realm category pkt << uint8(0x00); // unk, may be realm number/id? } pkt << uint16(0x0002); // unused value (why 2?) break; } case 8606: // 2.4.3 case 10505: // 3.2.2a case 11159: // 3.3.0a case 11403: // 3.3.2 case 11723: // 3.3.3a case 12340: // 3.3.5a default: // and later { pkt << uint32(0); // unused value pkt << uint16(sRealmList.size()); for(RealmList::RealmMap::const_iterator i = sRealmList.begin(); i != sRealmList.end(); ++i) { uint8 AmountOfCharacters; // No SQL injection. id of realm is controlled by the database. QueryResult *result = LoginDatabase.PQuery( "SELECT numchars FROM realmcharacters WHERE realmid = '%d' AND acctid='%u'", i->second.m_ID, acctid); if( result ) { Field *fields = result->Fetch(); AmountOfCharacters = fields[0].GetUInt8(); delete result; } else AmountOfCharacters = 0; bool ok_build = std::find(i->second.realmbuilds.begin(), i->second.realmbuilds.end(), _build) != i->second.realmbuilds.end(); RealmBuildInfo const* buildInfo = ok_build ? FindBuildInfo(_build) : NULL; if (!buildInfo) buildInfo = &i->second.realmBuildInfo; uint8 lock = (i->second.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0; RealmFlags realmFlags = i->second.realmflags; // Show offline state for unsupported client builds if (!ok_build) realmFlags = RealmFlags(realmFlags | REALM_FLAG_OFFLINE); if (!buildInfo) realmFlags = RealmFlags(realmFlags & ~REALM_FLAG_SPECIFYBUILD); pkt << uint8(i->second.icon); // realm type (this is second column in Cfg_Configs.dbc) pkt << uint8(lock); // flags, if 0x01, then realm locked pkt << uint8(realmFlags); // see enum RealmFlags pkt << i->first; // name pkt << i->second.address; // address pkt << float(i->second.populationLevel); pkt << uint8(AmountOfCharacters); pkt << uint8(i->second.timezone); // realm category (Cfg_Categories.dbc) pkt << uint8(0x2C); // unk, may be realm number/id? if (realmFlags & REALM_FLAG_SPECIFYBUILD) { pkt << uint8(buildInfo->major_version); pkt << uint8(buildInfo->minor_version); pkt << uint8(buildInfo->bugfix_version); pkt << uint16(_build); } } pkt << uint16(0x0010); // unused value (why 10?) break; } } }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data ) { DEBUG_LOG("WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); ObjectGuid guid; recv_data >> guid; Player * player = HashMapHolder<Player>::Find(guid); if(!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data << guid.WriteAsPacked(); data << uint32(GROUP_UPDATE_FLAG_STATUS); data << uint16(MEMBER_STATUS_OFFLINE); SendPacket(&data); return; } Pet *pet = player->GetPet(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data << player->GetPackGUID(); uint32 mask1 = 0x00040BFF; // common mask, real flags used 0x000040BFF if(pet) mask1 = 0x7FFFFFFF; // for hunters and other classes with pets uint16 online_status = GetPlayer()->IsReferAFriendLinked(player) ? (MEMBER_STATUS_ONLINE | MEMBER_STATUS_RAF) : MEMBER_STATUS_ONLINE; Powers powerType = player->getPowerType(); data << uint32(mask1); // group update mask data << uint16(online_status); // member's online status data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP data << uint8(powerType); // GROUP_UPDATE_FLAG_POWER_TYPE data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL //verify player coordinates and zoneid to send to teammates uint16 iZoneId = 0; uint16 iCoordX = 0; uint16 iCoordY = 0; if (player->IsInWorld()) { iZoneId = player->GetZoneId(); iCoordX = player->GetPositionX(); iCoordY = player->GetPositionY(); } else if (player->IsBeingTeleported()) // Player is in teleportation { WorldLocation& loc = player->GetTeleportDest(); // So take teleportation destination iZoneId = sTerrainMgr.GetZoneId(loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z); iCoordX = loc.coord_x; iCoordY = loc.coord_y; } else { //unknown player status. } data << uint16(iZoneId); // GROUP_UPDATE_FLAG_ZONE data << uint16(iCoordX); // GROUP_UPDATE_FLAG_POSITION data << uint16(iCoordY); // GROUP_UPDATE_FLAG_POSITION uint64 auramask = 0; size_t maskPos = data.wpos(); data << uint64(auramask); // placeholder for(uint8 i = 0; i < MAX_AURAS; ++i) { MAPLOCK_READ(player,MAP_LOCK_TYPE_AURAS); if(uint32 aura = player->GetVisibleAura(i)) { auramask |= (uint64(1) << i); data << uint32(aura); data << uint8(1); } } data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS if(pet) { Powers petpowertype = pet->getPowerType(); data << pet->GetObjectGuid(); // GROUP_UPDATE_FLAG_PET_GUID data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(pet->GetDisplayId()); // GROUP_UPDATE_FLAG_PET_MODEL_ID data << uint32(pet->GetHealth()); // GROUP_UPDATE_FLAG_PET_CUR_HP data << uint32(pet->GetMaxHealth()); // GROUP_UPDATE_FLAG_PET_MAX_HP data << uint8(petpowertype); // GROUP_UPDATE_FLAG_PET_POWER_TYPE data << uint16(pet->GetPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_CUR_POWER data << uint16(pet->GetMaxPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_MAX_POWER uint64 petauramask = 0; size_t petMaskPos = data.wpos(); data << uint64(petauramask); // placeholder for(uint8 i = 0; i < MAX_AURAS; ++i) { MAPLOCK_READ(pet,MAP_LOCK_TYPE_AURAS); if(uint32 petaura = pet->GetVisibleAura(i)) { petauramask |= (uint64(1) << i); data << uint32(petaura); data << uint8(1); } } data.put<uint64>(petMaskPos, petauramask); // GROUP_UPDATE_FLAG_PET_AURAS } else { data << uint8(0); // GROUP_UPDATE_FLAG_PET_NAME data << uint64(0); // GROUP_UPDATE_FLAG_PET_AURAS } SendPacket(&data); }
void CUser::WarehouseProcess(Packet & pkt) { Packet result(WIZ_WAREHOUSE); uint32 itemid, count; uint16 npcid, reference_pos; uint8 page, srcpos, destpos; _ITEM_TABLE* pTable = NULL; uint8 command = pkt.read<uint8>(); bool bResult = false; if (isDead()) { TRACE("### WarehouseProcess Fail : name=%s(%d), m_bResHpType=%d, hp=%d, x=%d, z=%d ###\n", GetName(), GetSocketID(), m_bResHpType, m_sHp, (int)m_curx, (int)m_curz); return; } if (isTrading()) goto fail_return; if (command == WAREHOUSE_OPEN) { result << uint8(WAREHOUSE_OPEN) << uint8(WAREHOUSE_OPEN) << GetInnCoins(); for (int i = 0; i < WAREHOUSE_MAX; i++) { _ITEM_DATA *pItem = &m_sWarehouseArray[i]; result << pItem->nNum << pItem->sDuration << pItem->sCount << uint8(0) << uint16(0) << uint16(0) << uint16(0) << uint16(0); } Send(&result); return; } pkt >> npcid >> itemid >> page >> srcpos >> destpos; CNpc * pNpc = g_pMain->m_arNpcArray.GetData(npcid); if (pNpc == NULL || pNpc->GetType() != NPC_WAREHOUSE || !isInRange(pNpc, MAX_NPC_RANGE)) goto fail_return; pTable = g_pMain->GetItemPtr( itemid ); if( !pTable ) goto fail_return; reference_pos = 24 * page; // TO-DO: Clean up this entire method. It's horrendous! switch (command) { /* stuff going into the inn */ case WAREHOUSE_INPUT: pkt >> count; // Handle coin input. if (itemid == ITEM_GOLD) { if (!hasCoins(count) || GetInnCoins() + count > COIN_MAX) goto fail_return; m_iBank += count; m_iGold -= count; break; } if (srcpos > HAVE_MAX || reference_pos + destpos > WAREHOUSE_MAX || itemid >= ITEM_NO_TRADE) // Cannot be traded, sold or stored (note: don't check the race, as these items CAN be stored). goto fail_return; if (m_sItemArray[SLOT_MAX+srcpos].isSealed() || m_sItemArray[SLOT_MAX+srcpos].isRented()) goto fail_return; if( m_sItemArray[SLOT_MAX+srcpos].nNum != itemid ) goto fail_return; if( m_sWarehouseArray[reference_pos+destpos].nNum && !pTable->m_bCountable ) goto fail_return; if( m_sItemArray[SLOT_MAX+srcpos].sCount < count ) goto fail_return; m_sWarehouseArray[reference_pos+destpos].nNum = itemid; m_sWarehouseArray[reference_pos+destpos].sDuration = m_sItemArray[SLOT_MAX+srcpos].sDuration; m_sWarehouseArray[reference_pos+destpos].nSerialNum = m_sItemArray[SLOT_MAX+srcpos].nSerialNum; if( pTable->m_bCountable == 0 && m_sWarehouseArray[reference_pos+destpos].nSerialNum == 0 ) m_sWarehouseArray[reference_pos+destpos].nSerialNum = g_pMain->GenerateItemSerial(); if( pTable->m_bCountable ) { m_sWarehouseArray[reference_pos+destpos].sCount += (unsigned short)count; } else { m_sWarehouseArray[reference_pos+destpos].sCount = m_sItemArray[SLOT_MAX+srcpos].sCount; } if( !pTable->m_bCountable ) { m_sItemArray[SLOT_MAX+srcpos].nNum = 0; m_sItemArray[SLOT_MAX+srcpos].sDuration = 0; m_sItemArray[SLOT_MAX+srcpos].sCount = 0; m_sItemArray[SLOT_MAX+srcpos].nSerialNum = 0; } else { m_sItemArray[SLOT_MAX+srcpos].sCount -= (unsigned short)count; if( m_sItemArray[SLOT_MAX+srcpos].sCount <= 0 ) { m_sItemArray[SLOT_MAX+srcpos].nNum = 0; m_sItemArray[SLOT_MAX+srcpos].sDuration = 0; m_sItemArray[SLOT_MAX+srcpos].sCount = 0; m_sItemArray[SLOT_MAX+srcpos].nSerialNum = 0; } } SendItemWeight(); break; /* stuff being taken out of the inn */ case WAREHOUSE_OUTPUT: pkt >> count; if (itemid == ITEM_GOLD) { if (!hasInnCoins(count) || GetCoins() + count > COIN_MAX) goto fail_return; m_iGold += count; m_iBank -= count; break; } if (reference_pos + srcpos > WAREHOUSE_MAX || destpos > HAVE_MAX) goto fail_return; if (pTable->m_bCountable) { // Check weight of countable item. if (((pTable->m_sWeight * count) + m_sItemWeight) > m_sMaxWeight) { goto fail_return; } } else { // Check weight of non-countable item. if ((pTable->m_sWeight + m_sItemWeight) > m_sMaxWeight) { goto fail_return; } } if( m_sWarehouseArray[reference_pos+srcpos].nNum != itemid ) goto fail_return; if( m_sItemArray[SLOT_MAX+destpos].nNum && !pTable->m_bCountable ) goto fail_return; if( m_sWarehouseArray[reference_pos+srcpos].sCount < count ) goto fail_return; m_sItemArray[SLOT_MAX+destpos].nNum = itemid; m_sItemArray[SLOT_MAX+destpos].sDuration = m_sWarehouseArray[reference_pos+srcpos].sDuration; m_sItemArray[SLOT_MAX+destpos].nSerialNum = m_sWarehouseArray[reference_pos+srcpos].nSerialNum; if( pTable->m_bCountable ) m_sItemArray[SLOT_MAX+destpos].sCount += (unsigned short)count; else { if( m_sItemArray[SLOT_MAX+destpos].nSerialNum == 0 ) m_sItemArray[SLOT_MAX+destpos].nSerialNum = g_pMain->GenerateItemSerial(); m_sItemArray[SLOT_MAX+destpos].sCount = m_sWarehouseArray[reference_pos+srcpos].sCount; } if( !pTable->m_bCountable ) { m_sWarehouseArray[reference_pos+srcpos].nNum = 0; m_sWarehouseArray[reference_pos+srcpos].sDuration = 0; m_sWarehouseArray[reference_pos+srcpos].sCount = 0; m_sWarehouseArray[reference_pos+srcpos].nSerialNum = 0; } else { m_sWarehouseArray[reference_pos+srcpos].sCount -= (unsigned short)count; if( m_sWarehouseArray[reference_pos+srcpos].sCount <= 0 ) { m_sWarehouseArray[reference_pos+srcpos].nNum = 0; m_sWarehouseArray[reference_pos+srcpos].sDuration = 0; m_sWarehouseArray[reference_pos+srcpos].sCount = 0; m_sWarehouseArray[reference_pos+srcpos].nSerialNum = 0; } } SendItemWeight(); //TRACE("WARE OUTPUT : %s %s %d %d %d %d %d", m_id, m_Accountid, ITEM_WAREHOUSE_GET, 0, itemid, count, m_sItemArray[SLOT_MAX+destpos].sDuration ); break; case WAREHOUSE_MOVE: if( reference_pos+srcpos > WAREHOUSE_MAX ) goto fail_return; if( m_sWarehouseArray[reference_pos+srcpos].nNum != itemid ) goto fail_return; if( m_sWarehouseArray[reference_pos+destpos].nNum ) goto fail_return; m_sWarehouseArray[reference_pos+destpos].nNum = itemid; m_sWarehouseArray[reference_pos+destpos].sDuration = m_sWarehouseArray[reference_pos+srcpos].sDuration; m_sWarehouseArray[reference_pos+destpos].sCount = m_sWarehouseArray[reference_pos+srcpos].sCount; m_sWarehouseArray[reference_pos+destpos].nSerialNum = m_sWarehouseArray[reference_pos+srcpos].nSerialNum; m_sWarehouseArray[reference_pos+srcpos].nNum = 0; m_sWarehouseArray[reference_pos+srcpos].sDuration = 0; m_sWarehouseArray[reference_pos+srcpos].sCount = 0; m_sWarehouseArray[reference_pos+srcpos].nSerialNum = 0; break; case WAREHOUSE_INVENMOVE: if( itemid != m_sItemArray[SLOT_MAX+srcpos].nNum ) goto fail_return; { short duration = m_sItemArray[SLOT_MAX+srcpos].sDuration; short itemcount = m_sItemArray[SLOT_MAX+srcpos].sCount; __int64 serial = m_sItemArray[SLOT_MAX+srcpos].nSerialNum; m_sItemArray[SLOT_MAX+srcpos].nNum = m_sItemArray[SLOT_MAX+destpos].nNum; m_sItemArray[SLOT_MAX+srcpos].sDuration = m_sItemArray[SLOT_MAX+destpos].sDuration; m_sItemArray[SLOT_MAX+srcpos].sCount = m_sItemArray[SLOT_MAX+destpos].sCount; m_sItemArray[SLOT_MAX+srcpos].nSerialNum = m_sItemArray[SLOT_MAX+destpos].nSerialNum; m_sItemArray[SLOT_MAX+destpos].nNum = itemid; m_sItemArray[SLOT_MAX+destpos].sDuration = duration; m_sItemArray[SLOT_MAX+destpos].sCount = itemcount; m_sItemArray[SLOT_MAX+destpos].nSerialNum = serial; } break; } bResult = true; fail_return: // hmm... result << uint8(command) << bResult; Send(&result); }
void CPUcore::disassemble_opcode(char *output, uint32 addr) { static reg24_t pc; char t[256]; char *s = output; if(false /* in_opcode() == true */) { strcpy(s, "?????? <CPU within opcode>"); return; } pc.d = addr; sprintf(s, "%.6x: ", (uint32)pc.d); uint8 op = dreadb(pc.d); pc.w++; uint8 op0 = dreadb(pc.d); pc.w++; uint8 op1 = dreadb(pc.d); pc.w++; uint8 op2 = dreadb(pc.d); #define op8 ((op0)) #define op16 ((op0) | (op1 << 8)) #define op24 ((op0) | (op1 << 8) | (op2 << 16)) #define a8 (regs.e || regs.p.m) #define x8 (regs.e || regs.p.x) switch(op) { case 0x00: sprintf(t, "brk #$%.2x ", op8); break; case 0x01: sprintf(t, "ora ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; case 0x02: sprintf(t, "cop #$%.2x ", op8); break; case 0x03: sprintf(t, "ora $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; case 0x04: sprintf(t, "tsb $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; case 0x05: sprintf(t, "ora $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; case 0x06: sprintf(t, "asl $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; case 0x07: sprintf(t, "ora [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; case 0x08: sprintf(t, "php "); break; case 0x09: if(a8)sprintf(t, "ora #$%.2x ", op8); else sprintf(t, "ora #$%.4x ", op16); break; case 0x0a: sprintf(t, "asl a "); break; case 0x0b: sprintf(t, "phd "); break; case 0x0c: sprintf(t, "tsb $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; case 0x0d: sprintf(t, "ora $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; case 0x0e: sprintf(t, "asl $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; case 0x0f: sprintf(t, "ora $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; case 0x10: sprintf(t, "bpl $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; case 0x11: sprintf(t, "ora ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; case 0x12: sprintf(t, "ora ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; case 0x13: sprintf(t, "ora ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; case 0x14: sprintf(t, "trb $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; case 0x15: sprintf(t, "ora $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; case 0x16: sprintf(t, "asl $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; case 0x17: sprintf(t, "ora [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; case 0x18: sprintf(t, "clc "); break; case 0x19: sprintf(t, "ora $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; case 0x1a: sprintf(t, "inc "); break; case 0x1b: sprintf(t, "tcs "); break; case 0x1c: sprintf(t, "trb $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; case 0x1d: sprintf(t, "ora $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; case 0x1e: sprintf(t, "asl $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; case 0x1f: sprintf(t, "ora $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; case 0x20: sprintf(t, "jsr $%.4x [%.6x]", op16, decode(OPTYPE_ADDR_PC, op16)); break; case 0x21: sprintf(t, "and ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; case 0x22: sprintf(t, "jsl $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; case 0x23: sprintf(t, "and $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; case 0x24: sprintf(t, "bit $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; case 0x25: sprintf(t, "and $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; case 0x26: sprintf(t, "rol $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; case 0x27: sprintf(t, "and [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; case 0x28: sprintf(t, "plp "); break; case 0x29: if(a8)sprintf(t, "and #$%.2x ", op8); else sprintf(t, "and #$%.4x ", op16); break; case 0x2a: sprintf(t, "rol a "); break; case 0x2b: sprintf(t, "pld "); break; case 0x2c: sprintf(t, "bit $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; case 0x2d: sprintf(t, "and $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; case 0x2e: sprintf(t, "rol $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; case 0x2f: sprintf(t, "and $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; case 0x30: sprintf(t, "bmi $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; case 0x31: sprintf(t, "and ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; case 0x32: sprintf(t, "and ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; case 0x33: sprintf(t, "and ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; case 0x34: sprintf(t, "bit $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; case 0x35: sprintf(t, "and $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; case 0x36: sprintf(t, "rol $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; case 0x37: sprintf(t, "and [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; case 0x38: sprintf(t, "sec "); break; case 0x39: sprintf(t, "and $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; case 0x3a: sprintf(t, "dec "); break; case 0x3b: sprintf(t, "tsc "); break; case 0x3c: sprintf(t, "bit $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; case 0x3d: sprintf(t, "and $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; case 0x3e: sprintf(t, "rol $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; case 0x3f: sprintf(t, "and $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; case 0x40: sprintf(t, "rti "); break; case 0x41: sprintf(t, "eor ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; case 0x42: sprintf(t, "wdm "); break; case 0x43: sprintf(t, "eor $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; case 0x44: sprintf(t, "mvp $%.2x,$%.2x ", op1, op8); break; case 0x45: sprintf(t, "eor $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; case 0x46: sprintf(t, "lsr $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; case 0x47: sprintf(t, "eor [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; case 0x48: sprintf(t, "pha "); break; case 0x49: if(a8)sprintf(t, "eor #$%.2x ", op8); else sprintf(t, "eor #$%.4x ", op16); break; case 0x4a: sprintf(t, "lsr a "); break; case 0x4b: sprintf(t, "phk "); break; case 0x4c: sprintf(t, "jmp $%.4x [%.6x]", op16, decode(OPTYPE_ADDR_PC, op16)); break; case 0x4d: sprintf(t, "eor $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; case 0x4e: sprintf(t, "lsr $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; case 0x4f: sprintf(t, "eor $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; case 0x50: sprintf(t, "bvc $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; case 0x51: sprintf(t, "eor ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; case 0x52: sprintf(t, "eor ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; case 0x53: sprintf(t, "eor ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; case 0x54: sprintf(t, "mvn $%.2x,$%.2x ", op1, op8); break; case 0x55: sprintf(t, "eor $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; case 0x56: sprintf(t, "lsr $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; case 0x57: sprintf(t, "eor [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; case 0x58: sprintf(t, "cli "); break; case 0x59: sprintf(t, "eor $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; case 0x5a: sprintf(t, "phy "); break; case 0x5b: sprintf(t, "tcd "); break; case 0x5c: sprintf(t, "jml $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; case 0x5d: sprintf(t, "eor $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; case 0x5e: sprintf(t, "lsr $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; case 0x5f: sprintf(t, "eor $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; case 0x60: sprintf(t, "rts "); break; case 0x61: sprintf(t, "adc ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; case 0x62: sprintf(t, "per $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; case 0x63: sprintf(t, "adc $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; case 0x64: sprintf(t, "stz $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; case 0x65: sprintf(t, "adc $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; case 0x66: sprintf(t, "ror $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; case 0x67: sprintf(t, "adc [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; case 0x68: sprintf(t, "pla "); break; case 0x69: if(a8)sprintf(t, "adc #$%.2x ", op8); else sprintf(t, "adc #$%.4x ", op16); break; case 0x6a: sprintf(t, "ror a "); break; case 0x6b: sprintf(t, "rtl "); break; case 0x6c: sprintf(t, "jmp ($%.4x) [%.6x]", op16, decode(OPTYPE_IADDR_PC, op16)); break; case 0x6d: sprintf(t, "adc $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; case 0x6e: sprintf(t, "ror $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; case 0x6f: sprintf(t, "adc $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; case 0x70: sprintf(t, "bvs $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; case 0x71: sprintf(t, "adc ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; case 0x72: sprintf(t, "adc ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; case 0x73: sprintf(t, "adc ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; case 0x74: sprintf(t, "stz $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; case 0x75: sprintf(t, "adc $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; case 0x76: sprintf(t, "ror $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; case 0x77: sprintf(t, "adc [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; case 0x78: sprintf(t, "sei "); break; case 0x79: sprintf(t, "adc $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; case 0x7a: sprintf(t, "ply "); break; case 0x7b: sprintf(t, "tdc "); break; case 0x7c: sprintf(t, "jmp ($%.4x,x) [%.6x]", op16, decode(OPTYPE_IADDRX, op16)); break; case 0x7d: sprintf(t, "adc $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; case 0x7e: sprintf(t, "ror $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; case 0x7f: sprintf(t, "adc $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; case 0x80: sprintf(t, "bra $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; case 0x81: sprintf(t, "sta ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; case 0x82: sprintf(t, "brl $%.4x [%.6x]", uint16(decode(OPTYPE_RELW, op16)), decode(OPTYPE_RELW, op16)); break; case 0x83: sprintf(t, "sta $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; case 0x84: sprintf(t, "sty $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; case 0x85: sprintf(t, "sta $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; case 0x86: sprintf(t, "stx $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; case 0x87: sprintf(t, "sta [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; case 0x88: sprintf(t, "dey "); break; case 0x89: if(a8)sprintf(t, "bit #$%.2x ", op8); else sprintf(t, "bit #$%.4x ", op16); break; case 0x8a: sprintf(t, "txa "); break; case 0x8b: sprintf(t, "phb "); break; case 0x8c: sprintf(t, "sty $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; case 0x8d: sprintf(t, "sta $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; case 0x8e: sprintf(t, "stx $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; case 0x8f: sprintf(t, "sta $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; case 0x90: sprintf(t, "bcc $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; case 0x91: sprintf(t, "sta ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; case 0x92: sprintf(t, "sta ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; case 0x93: sprintf(t, "sta ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; case 0x94: sprintf(t, "sty $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; case 0x95: sprintf(t, "sta $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; case 0x96: sprintf(t, "stx $%.2x,y [%.6x]", op8, decode(OPTYPE_DPY, op8)); break; case 0x97: sprintf(t, "sta [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; case 0x98: sprintf(t, "tya "); break; case 0x99: sprintf(t, "sta $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; case 0x9a: sprintf(t, "txs "); break; case 0x9b: sprintf(t, "txy "); break; case 0x9c: sprintf(t, "stz $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; case 0x9d: sprintf(t, "sta $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; case 0x9e: sprintf(t, "stz $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; case 0x9f: sprintf(t, "sta $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; case 0xa0: if(x8)sprintf(t, "ldy #$%.2x ", op8); else sprintf(t, "ldy #$%.4x ", op16); break; case 0xa1: sprintf(t, "lda ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; case 0xa2: if(x8)sprintf(t, "ldx #$%.2x ", op8); else sprintf(t, "ldx #$%.4x ", op16); break; case 0xa3: sprintf(t, "lda $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; case 0xa4: sprintf(t, "ldy $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; case 0xa5: sprintf(t, "lda $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; case 0xa6: sprintf(t, "ldx $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; case 0xa7: sprintf(t, "lda [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; case 0xa8: sprintf(t, "tay "); break; case 0xa9: if(a8)sprintf(t, "lda #$%.2x ", op8); else sprintf(t, "lda #$%.4x ", op16); break; case 0xaa: sprintf(t, "tax "); break; case 0xab: sprintf(t, "plb "); break; case 0xac: sprintf(t, "ldy $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; case 0xad: sprintf(t, "lda $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; case 0xae: sprintf(t, "ldx $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; case 0xaf: sprintf(t, "lda $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; case 0xb0: sprintf(t, "bcs $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; case 0xb1: sprintf(t, "lda ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; case 0xb2: sprintf(t, "lda ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; case 0xb3: sprintf(t, "lda ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; case 0xb4: sprintf(t, "ldy $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; case 0xb5: sprintf(t, "lda $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; case 0xb6: sprintf(t, "ldx $%.2x,y [%.6x]", op8, decode(OPTYPE_DPY, op8)); break; case 0xb7: sprintf(t, "lda [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; case 0xb8: sprintf(t, "clv "); break; case 0xb9: sprintf(t, "lda $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; case 0xba: sprintf(t, "tsx "); break; case 0xbb: sprintf(t, "tyx "); break; case 0xbc: sprintf(t, "ldy $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; case 0xbd: sprintf(t, "lda $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; case 0xbe: sprintf(t, "ldx $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; case 0xbf: sprintf(t, "lda $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; case 0xc0: if(x8)sprintf(t, "cpy #$%.2x ", op8); else sprintf(t, "cpy #$%.4x ", op16); break; case 0xc1: sprintf(t, "cmp ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; case 0xc2: sprintf(t, "rep #$%.2x ", op8); break; case 0xc3: sprintf(t, "cmp $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; case 0xc4: sprintf(t, "cpy $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; case 0xc5: sprintf(t, "cmp $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; case 0xc6: sprintf(t, "dec $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; case 0xc7: sprintf(t, "cmp [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; case 0xc8: sprintf(t, "iny "); break; case 0xc9: if(a8)sprintf(t, "cmp #$%.2x ", op8); else sprintf(t, "cmp #$%.4x ", op16); break; case 0xca: sprintf(t, "dex "); break; case 0xcb: sprintf(t, "wai "); break; case 0xcc: sprintf(t, "cpy $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; case 0xcd: sprintf(t, "cmp $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; case 0xce: sprintf(t, "dec $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; case 0xcf: sprintf(t, "cmp $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; case 0xd0: sprintf(t, "bne $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; case 0xd1: sprintf(t, "cmp ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; case 0xd2: sprintf(t, "cmp ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; case 0xd3: sprintf(t, "cmp ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; case 0xd4: sprintf(t, "pei ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; case 0xd5: sprintf(t, "cmp $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; case 0xd6: sprintf(t, "dec $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; case 0xd7: sprintf(t, "cmp [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; case 0xd8: sprintf(t, "cld "); break; case 0xd9: sprintf(t, "cmp $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; case 0xda: sprintf(t, "phx "); break; case 0xdb: sprintf(t, "stp "); break; case 0xdc: sprintf(t, "jmp [$%.4x] [%.6x]", op16, decode(OPTYPE_ILADDR, op16)); break; case 0xdd: sprintf(t, "cmp $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; case 0xde: sprintf(t, "dec $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; case 0xdf: sprintf(t, "cmp $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; case 0xe0: if(x8)sprintf(t, "cpx #$%.2x ", op8); else sprintf(t, "cpx #$%.4x ", op16); break; case 0xe1: sprintf(t, "sbc ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; case 0xe2: sprintf(t, "sep #$%.2x ", op8); break; case 0xe3: sprintf(t, "sbc $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; case 0xe4: sprintf(t, "cpx $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; case 0xe5: sprintf(t, "sbc $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; case 0xe6: sprintf(t, "inc $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; case 0xe7: sprintf(t, "sbc [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; case 0xe8: sprintf(t, "inx "); break; case 0xe9: if(a8)sprintf(t, "sbc #$%.2x ", op8); else sprintf(t, "sbc #$%.4x ", op16); break; case 0xea: sprintf(t, "nop "); break; case 0xeb: sprintf(t, "xba "); break; case 0xec: sprintf(t, "cpx $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; case 0xed: sprintf(t, "sbc $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; case 0xee: sprintf(t, "inc $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; case 0xef: sprintf(t, "sbc $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; case 0xf0: sprintf(t, "beq $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; case 0xf1: sprintf(t, "sbc ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; case 0xf2: sprintf(t, "sbc ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; case 0xf3: sprintf(t, "sbc ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; case 0xf4: sprintf(t, "pea $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; case 0xf5: sprintf(t, "sbc $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; case 0xf6: sprintf(t, "inc $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; case 0xf7: sprintf(t, "sbc [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; case 0xf8: sprintf(t, "sed "); break; case 0xf9: sprintf(t, "sbc $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; case 0xfa: sprintf(t, "plx "); break; case 0xfb: sprintf(t, "xce "); break; case 0xfc: sprintf(t, "jsr ($%.4x,x) [%.6x]", op16, decode(OPTYPE_IADDRX, op16)); break; case 0xfd: sprintf(t, "sbc $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; case 0xfe: sprintf(t, "inc $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; case 0xff: sprintf(t, "sbc $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; } #undef op8 #undef op16 #undef op24 #undef a8 #undef x8 strcat(s, t); strcat(s, " "); sprintf(t, "A:%.4x X:%.4x Y:%.4x S:%.4x D:%.4x DB:%.2x ", regs.a.w, regs.x.w, regs.y.w, regs.s.w, regs.d.w, regs.db); strcat(s, t); if(regs.e) { sprintf(t, "%c%c%c%c%c%c%c%c", regs.p.n ? 'N' : 'n', regs.p.v ? 'V' : 'v', regs.p.m ? '1' : '0', regs.p.x ? 'B' : 'b', regs.p.d ? 'D' : 'd', regs.p.i ? 'I' : 'i', regs.p.z ? 'Z' : 'z', regs.p.c ? 'C' : 'c'); } else { sprintf(t, "%c%c%c%c%c%c%c%c", regs.p.n ? 'N' : 'n', regs.p.v ? 'V' : 'v', regs.p.m ? 'M' : 'm', regs.p.x ? 'X' : 'x', regs.p.d ? 'D' : 'd', regs.p.i ? 'I' : 'i', regs.p.z ? 'Z' : 'z', regs.p.c ? 'C' : 'c'); } strcat(s, t); strcat(s, " "); sprintf(t, "V:%3d H:%4d", cpu.vcounter(), cpu.hcounter()); strcat(s, t); }
/** * @brief * * @param filename * @param filename2 * @param cell_y * @param cell_x * @return bool */ bool ConvertADT(char* filename, char* filename2) { ADT_file adt; if (!adt.loadFile(filename)) { return false; } adt_MCIN* cells = adt.a_grid->getMCIN(); if (!cells) { printf("Can not find cells in '%s'\n", filename); return false; } memset(liquid_show, 0, sizeof(liquid_show)); memset(liquid_flags, 0, sizeof(liquid_flags)); memset(liquid_entry, 0, sizeof(liquid_entry)); // Prepare map header map_fileheader map; map.mapMagic = *(uint32 const*)MAP_MAGIC; map.versionMagic = *(uint32 const*)MAP_VERSION_MAGIC; // Get area flags data for (int i = 0; i < ADT_CELLS_PER_GRID; i++) { for (int j = 0; j < ADT_CELLS_PER_GRID; j++) { adt_MCNK* cell = cells->getMCNK(i, j); uint32 areaid = cell->areaid; if (areaid && areaid <= maxAreaId) { if (areas[areaid] != 0xffff) { area_flags[i][j] = areas[areaid]; continue; } printf("File: %s\nCan not find area flag for area %u [%d, %d].\n", filename, areaid, cell->ix, cell->iy); } area_flags[i][j] = 0xffff; } } //============================================ // Try pack area data //============================================ bool fullAreaData = false; uint32 areaflag = area_flags[0][0]; for (int y = 0; y < ADT_CELLS_PER_GRID; y++) { for (int x = 0; x < ADT_CELLS_PER_GRID; x++) { if (area_flags[y][x] != areaflag) { fullAreaData = true; break; } } } map.areaMapOffset = sizeof(map); map.areaMapSize = sizeof(map_areaHeader); map_areaHeader areaHeader; areaHeader.fourcc = *(uint32 const*)MAP_AREA_MAGIC; areaHeader.flags = 0; if (fullAreaData) { areaHeader.gridArea = 0; map.areaMapSize += sizeof(area_flags); } else { areaHeader.flags |= MAP_AREA_NO_AREA; areaHeader.gridArea = (uint16)areaflag; } // // Get Height map from grid // for (int i = 0; i < ADT_CELLS_PER_GRID; i++) { for (int j = 0; j < ADT_CELLS_PER_GRID; j++) { adt_MCNK* cell = cells->getMCNK(i, j); if (!cell) { continue; } // Height values for triangles stored in order: // 1 2 3 4 5 6 7 8 9 // 10 11 12 13 14 15 16 17 // 18 19 20 21 22 23 24 25 26 // 27 28 29 30 31 32 33 34 // . . . . . . . . // For better get height values merge it to V9 and V8 map // V9 height map: // 1 2 3 4 5 6 7 8 9 // 18 19 20 21 22 23 24 25 26 // . . . . . . . . // V8 height map: // 10 11 12 13 14 15 16 17 // 27 28 29 30 31 32 33 34 // . . . . . . . . // Set map height as grid height for (int y = 0; y <= ADT_CELL_SIZE; y++) { int cy = i * ADT_CELL_SIZE + y; for (int x = 0; x <= ADT_CELL_SIZE; x++) { int cx = j * ADT_CELL_SIZE + x; V9[cy][cx] = cell->ypos; } } for (int y = 0; y < ADT_CELL_SIZE; y++) { int cy = i * ADT_CELL_SIZE + y; for (int x = 0; x < ADT_CELL_SIZE; x++) { int cx = j * ADT_CELL_SIZE + x; V8[cy][cx] = cell->ypos; } } // Get custom height adt_MCVT* v = cell->getMCVT(); if (!v) { continue; } // get V9 height map for (int y = 0; y <= ADT_CELL_SIZE; y++) { int cy = i * ADT_CELL_SIZE + y; for (int x = 0; x <= ADT_CELL_SIZE; x++) { int cx = j * ADT_CELL_SIZE + x; V9[cy][cx] += v->height_map[y * (ADT_CELL_SIZE * 2 + 1) + x]; } } // get V8 height map for (int y = 0; y < ADT_CELL_SIZE; y++) { int cy = i * ADT_CELL_SIZE + y; for (int x = 0; x < ADT_CELL_SIZE; x++) { int cx = j * ADT_CELL_SIZE + x; V8[cy][cx] += v->height_map[y * (ADT_CELL_SIZE * 2 + 1) + ADT_CELL_SIZE + 1 + x]; } } } } //============================================ // Try pack height data //============================================ float maxHeight = -20000; float minHeight = 20000; for (int y = 0; y < ADT_GRID_SIZE; y++) { for (int x = 0; x < ADT_GRID_SIZE; x++) { float h = V8[y][x]; if (maxHeight < h) { maxHeight = h; } if (minHeight > h) { minHeight = h; } } } for (int y = 0; y <= ADT_GRID_SIZE; y++) { for (int x = 0; x <= ADT_GRID_SIZE; x++) { float h = V9[y][x]; if (maxHeight < h) { maxHeight = h; } if (minHeight > h) { minHeight = h; } } } // Check for allow limit minimum height (not store height in deep ochean - allow save some memory) if (CONF_allow_height_limit && minHeight < CONF_use_minHeight) { for (int y = 0; y < ADT_GRID_SIZE; y++) for (int x = 0; x < ADT_GRID_SIZE; x++) if (V8[y][x] < CONF_use_minHeight) { V8[y][x] = CONF_use_minHeight; } for (int y = 0; y <= ADT_GRID_SIZE; y++) for (int x = 0; x <= ADT_GRID_SIZE; x++) if (V9[y][x] < CONF_use_minHeight) { V9[y][x] = CONF_use_minHeight; } if (minHeight < CONF_use_minHeight) { minHeight = CONF_use_minHeight; } if (maxHeight < CONF_use_minHeight) { maxHeight = CONF_use_minHeight; } } map.heightMapOffset = map.areaMapOffset + map.areaMapSize; map.heightMapSize = sizeof(map_heightHeader); map_heightHeader heightHeader; heightHeader.fourcc = *(uint32 const*)MAP_HEIGHT_MAGIC; heightHeader.flags = 0; heightHeader.gridHeight = minHeight; heightHeader.gridMaxHeight = maxHeight; if (maxHeight == minHeight) { heightHeader.flags |= MAP_HEIGHT_NO_HEIGHT; } // Not need store if flat surface if (CONF_allow_float_to_int && (maxHeight - minHeight) < CONF_flat_height_delta_limit) { heightHeader.flags |= MAP_HEIGHT_NO_HEIGHT; } // Try store as packed in uint16 or uint8 values if (!(heightHeader.flags & MAP_HEIGHT_NO_HEIGHT)) { float step = 0.0f; // Try Store as uint values if (CONF_allow_float_to_int) { float diff = maxHeight - minHeight; if (diff < CONF_float_to_int8_limit) // As uint8 (max accuracy = CONF_float_to_int8_limit/256) { heightHeader.flags |= MAP_HEIGHT_AS_INT8; step = selectUInt8StepStore(diff); } else if (diff < CONF_float_to_int16_limit) // As uint16 (max accuracy = CONF_float_to_int16_limit/65536) { heightHeader.flags |= MAP_HEIGHT_AS_INT16; step = selectUInt16StepStore(diff); } } // Pack it to int values if need if (heightHeader.flags & MAP_HEIGHT_AS_INT8) { for (int y = 0; y < ADT_GRID_SIZE; y++) for (int x = 0; x < ADT_GRID_SIZE; x++) { uint8_V8[y][x] = uint8((V8[y][x] - minHeight) * step + 0.5f); } for (int y = 0; y <= ADT_GRID_SIZE; y++) for (int x = 0; x <= ADT_GRID_SIZE; x++) { uint8_V9[y][x] = uint8((V9[y][x] - minHeight) * step + 0.5f); } map.heightMapSize += sizeof(uint8_V9) + sizeof(uint8_V8); } else if (heightHeader.flags & MAP_HEIGHT_AS_INT16) { for (int y = 0; y < ADT_GRID_SIZE; y++) for (int x = 0; x < ADT_GRID_SIZE; x++) { uint16_V8[y][x] = uint16((V8[y][x] - minHeight) * step + 0.5f); } for (int y = 0; y <= ADT_GRID_SIZE; y++) for (int x = 0; x <= ADT_GRID_SIZE; x++) { uint16_V9[y][x] = uint16((V9[y][x] - minHeight) * step + 0.5f); } map.heightMapSize += sizeof(uint16_V9) + sizeof(uint16_V8); } else { map.heightMapSize += sizeof(V9) + sizeof(V8); } } // Get from MCLQ chunk (old) for (int i = 0; i < ADT_CELLS_PER_GRID; i++) { for (int j = 0; j < ADT_CELLS_PER_GRID; j++) { adt_MCNK* cell = cells->getMCNK(i, j); if (!cell) { continue; } adt_MCLQ* liquid = cell->getMCLQ(); int count = 0; if (!liquid || cell->sizeMCLQ <= 8) { continue; } for (int y = 0; y < ADT_CELL_SIZE; y++) { int cy = i * ADT_CELL_SIZE + y; for (int x = 0; x < ADT_CELL_SIZE; x++) { int cx = j * ADT_CELL_SIZE + x; if (liquid->flags[y][x] != 0x0F) { liquid_show[cy][cx] = true; if (liquid->flags[y][x] & (1 << 7)) { liquid_flags[i][j] |= MAP_LIQUID_TYPE_DARK_WATER; } ++count; } } } uint32 c_flag = cell->flags; if (c_flag & (1 << 2)) { liquid_entry[i][j] = 1; liquid_flags[i][j] |= MAP_LIQUID_TYPE_WATER; // water } if (c_flag & (1 << 3)) { liquid_entry[i][j] = 2; liquid_flags[i][j] |= MAP_LIQUID_TYPE_OCEAN; // ocean } if (c_flag & (1 << 4)) { liquid_entry[i][j] = 3; liquid_flags[i][j] |= MAP_LIQUID_TYPE_MAGMA; // magma/slime } if (!count && liquid_flags[i][j]) { fprintf(stderr, "Wrong liquid type detected in MCLQ chunk"); } for (int y = 0; y <= ADT_CELL_SIZE; y++) { int cy = i * ADT_CELL_SIZE + y; for (int x = 0; x <= ADT_CELL_SIZE; x++) { int cx = j * ADT_CELL_SIZE + x; liquid_height[cy][cx] = liquid->liquid[y][x].height; } } } } // Get liquid map for grid (in WOTLK used MH2O chunk) adt_MH2O* h2o = adt.a_grid->getMH2O(); if (h2o) { for (int i = 0; i < ADT_CELLS_PER_GRID; i++) { for (int j = 0; j < ADT_CELLS_PER_GRID; j++) { adt_liquid_header* h = h2o->getLiquidData(i, j); if (!h) { continue; } int count = 0; uint64 show = h2o->getLiquidShowMap(h); for (int y = 0; y < h->height; y++) { int cy = i * ADT_CELL_SIZE + y + h->yOffset; for (int x = 0; x < h->width; x++) { int cx = j * ADT_CELL_SIZE + x + h->xOffset; if (show & 1) { liquid_show[cy][cx] = true; ++count; } show >>= 1; } } liquid_entry[i][j] = h->liquidType; switch (LiqType[h->liquidType]) { case LIQUID_TYPE_WATER: liquid_flags[i][j] |= MAP_LIQUID_TYPE_WATER; break; case LIQUID_TYPE_OCEAN: liquid_flags[i][j] |= MAP_LIQUID_TYPE_OCEAN; break; case LIQUID_TYPE_MAGMA: liquid_flags[i][j] |= MAP_LIQUID_TYPE_MAGMA; break; case LIQUID_TYPE_SLIME: liquid_flags[i][j] |= MAP_LIQUID_TYPE_SLIME; break; default: printf("\nCan not find liquid type %u for map %s\nchunk %d,%d\n", h->liquidType, filename, i, j); break; } // Dark water detect if (LiqType[h->liquidType] == LIQUID_TYPE_OCEAN) { uint8* lm = h2o->getLiquidLightMap(h); if (!lm) { liquid_flags[i][j] |= MAP_LIQUID_TYPE_DARK_WATER; } } if (!count && liquid_flags[i][j]) { printf("Wrong liquid type detected in MH2O chunk"); } float* height = h2o->getLiquidHeightMap(h); int pos = 0; for (int y = 0; y <= h->height; y++) { int cy = i * ADT_CELL_SIZE + y + h->yOffset; for (int x = 0; x <= h->width; x++) { int cx = j * ADT_CELL_SIZE + x + h->xOffset; if (height) { liquid_height[cy][cx] = height[pos]; } else { liquid_height[cy][cx] = h->heightLevel1; } pos++; } } } } } //============================================ // Pack liquid data //============================================ uint8 type = liquid_flags[0][0]; bool fullType = false; for (int y = 0; y < ADT_CELLS_PER_GRID; y++) { for (int x = 0; x < ADT_CELLS_PER_GRID; x++) { if (liquid_flags[y][x] != type) { fullType = true; y = ADT_CELLS_PER_GRID; break; } } } map_liquidHeader liquidHeader; // no water data (if all grid have 0 liquid type) if (type == 0 && !fullType) { // No liquid data map.liquidMapOffset = 0; map.liquidMapSize = 0; } else { int minX = 255, minY = 255; int maxX = 0, maxY = 0; maxHeight = -20000; minHeight = 20000; for (int y = 0; y < ADT_GRID_SIZE; y++) { for (int x = 0; x < ADT_GRID_SIZE; x++) { if (liquid_show[y][x]) { if (minX > x) { minX = x; } if (maxX < x) { maxX = x; } if (minY > y) { minY = y; } if (maxY < y) { maxY = y; } float h = liquid_height[y][x]; if (maxHeight < h) { maxHeight = h; } if (minHeight > h) { minHeight = h; } } else { liquid_height[y][x] = CONF_use_minHeight; } } } map.liquidMapOffset = map.heightMapOffset + map.heightMapSize; map.liquidMapSize = sizeof(map_liquidHeader); liquidHeader.fourcc = *(uint32 const*)MAP_LIQUID_MAGIC; liquidHeader.flags = 0; liquidHeader.liquidType = 0; liquidHeader.offsetX = minX; liquidHeader.offsetY = minY; liquidHeader.width = maxX - minX + 1 + 1; liquidHeader.height = maxY - minY + 1 + 1; liquidHeader.liquidLevel = minHeight; if (maxHeight == minHeight) { liquidHeader.flags |= MAP_LIQUID_NO_HEIGHT; } // Not need store if flat surface if (CONF_allow_float_to_int && (maxHeight - minHeight) < CONF_flat_liquid_delta_limit) { liquidHeader.flags |= MAP_LIQUID_NO_HEIGHT; } if (!fullType) { liquidHeader.flags |= MAP_LIQUID_NO_TYPE; } if (liquidHeader.flags & MAP_LIQUID_NO_TYPE) { liquidHeader.liquidType = type; } else { map.liquidMapSize += sizeof(liquid_entry) + sizeof(liquid_flags); } if (!(liquidHeader.flags & MAP_LIQUID_NO_HEIGHT)) { map.liquidMapSize += sizeof(float) * liquidHeader.width * liquidHeader.height; } } // map hole info uint16 holes[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID]; if (map.liquidMapOffset) { map.holesOffset = map.liquidMapOffset + map.liquidMapSize; } else { map.holesOffset = map.heightMapOffset + map.heightMapSize; } map.holesSize = sizeof(holes); memset(holes, 0, map.holesSize); for (int i = 0; i < ADT_CELLS_PER_GRID; ++i) { for (int j = 0; j < ADT_CELLS_PER_GRID; ++j) { adt_MCNK* cell = cells->getMCNK(i, j); if (!cell) { continue; } holes[i][j] = cell->holes; } } // Ok all data prepared - store it FILE* output = fopen(filename2, "wb"); if (!output) { printf("Can not create the output file '%s'\n", filename2); return false; } fwrite(&map, sizeof(map), 1, output); // Store area data fwrite(&areaHeader, sizeof(areaHeader), 1, output); if (!(areaHeader.flags & MAP_AREA_NO_AREA)) { fwrite(area_flags, sizeof(area_flags), 1, output); } // Store height data fwrite(&heightHeader, sizeof(heightHeader), 1, output); if (!(heightHeader.flags & MAP_HEIGHT_NO_HEIGHT)) { if (heightHeader.flags & MAP_HEIGHT_AS_INT16) { fwrite(uint16_V9, sizeof(uint16_V9), 1, output); fwrite(uint16_V8, sizeof(uint16_V8), 1, output); } else if (heightHeader.flags & MAP_HEIGHT_AS_INT8) { fwrite(uint8_V9, sizeof(uint8_V9), 1, output); fwrite(uint8_V8, sizeof(uint8_V8), 1, output); } else { fwrite(V9, sizeof(V9), 1, output); fwrite(V8, sizeof(V8), 1, output); } } // Store liquid data if need if (map.liquidMapOffset) { fwrite(&liquidHeader, sizeof(liquidHeader), 1, output); if (!(liquidHeader.flags & MAP_LIQUID_NO_TYPE)) { fwrite(liquid_entry, sizeof(liquid_entry), 1, output); fwrite(liquid_flags, sizeof(liquid_flags), 1, output); } if (!(liquidHeader.flags & MAP_LIQUID_NO_HEIGHT)) { for (int y = 0; y < liquidHeader.height; y++) { fwrite(&liquid_height[y + liquidHeader.offsetY][liquidHeader.offsetX], sizeof(float), liquidHeader.width, output); } } } // store hole data fwrite(holes, map.holesSize, 1, output); fclose(output); return true; }
void LoadDBCStores(const std::string& dataPath) { std::string dbcPath = dataPath+"dbc/"; const uint32 DBCFilesCount = 90; barGoLink bar(DBCFilesCount); StoreProblemList bad_dbc_files; uint32 availableDbcLocales = 0xFFFFFFFF; LoadDBC(availableDbcLocales, bar, bad_dbc_files, sAreaStore, dbcPath, "AreaTable.dbc"); // must be after sAreaStore loading for (uint32 i = 0; i < sAreaStore.GetNumRows(); ++i) // areaflag numbered from 0 { if (AreaTableEntry const* area = sAreaStore.LookupEntry(i)) { // fill AreaId->DBC records sAreaFlagByAreaID.insert(AreaFlagByAreaID::value_type(uint16(area->ID),area->exploreFlag)); // fill MapId->DBC records (skip sub zones and continents) if (area->zone == 0 && area->mapid != 0 && area->mapid != 1 && area->mapid != 530 && area->mapid != 571) sAreaFlagByMapID.insert(AreaFlagByMapID::value_type(area->mapid,area->exploreFlag)); } } LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAchievementStore, dbcPath,"Achievement.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAchievementCriteriaStore, dbcPath,"Achievement_Criteria.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaTriggerStore, dbcPath,"AreaTrigger.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaGroupStore, dbcPath,"AreaGroup.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaPOIStore, dbcPath,"AreaPOI.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAuctionHouseStore, dbcPath,"AuctionHouse.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBankBagSlotPricesStore, dbcPath,"BankBagSlotPrices.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBattlemasterListStore, dbcPath,"BattlemasterList.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBarberShopStyleStore, dbcPath,"BarberShopStyle.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharStartOutfitStore, dbcPath,"CharStartOutfit.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharTitlesStore, dbcPath,"CharTitles.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChatChannelsStore, dbcPath,"ChatChannels.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChrClassesStore, dbcPath,"ChrClasses.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChrRacesStore, dbcPath,"ChrRaces.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCinematicSequencesStore, dbcPath,"CinematicSequences.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureDisplayInfoStore, dbcPath,"CreatureDisplayInfo.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureFamilyStore, dbcPath,"CreatureFamily.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureSpellDataStore, dbcPath,"CreatureSpellData.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureTypeStore, dbcPath,"CreatureType.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCurrencyTypesStore, dbcPath,"CurrencyTypes.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sDurabilityCostsStore, dbcPath,"DurabilityCosts.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sDurabilityQualityStore, dbcPath,"DurabilityQuality.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sEmotesStore, dbcPath,"Emotes.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sEmotesTextStore, dbcPath,"EmotesText.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sFactionStore, dbcPath,"Faction.dbc"); for (uint32 i=0; i<sFactionStore.GetNumRows(); ++i) { FactionEntry const * faction = sFactionStore.LookupEntry(i); if (faction && faction->team) { SimpleFactionsList &flist = sFactionTeamMap[faction->team]; flist.push_back(i); } } LoadDBC(availableDbcLocales,bar,bad_dbc_files,sFactionTemplateStore, dbcPath,"FactionTemplate.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGameObjectDisplayInfoStore, dbcPath,"GameObjectDisplayInfo.dbc"); for (uint32 i = 0; i < sGameObjectDisplayInfoStore.GetNumRows(); ++i) { if (GameObjectDisplayInfoEntry const * info = sGameObjectDisplayInfoStore.LookupEntry(i)) { if (info->maxX < info->minX) std::swap(*(float*)(&info->maxX), *(float*)(&info->minX)); if (info->maxY < info->minY) std::swap(*(float*)(&info->maxY), *(float*)(&info->minY)); if (info->maxZ < info->minZ) std::swap(*(float*)(&info->maxZ), *(float*)(&info->minZ)); } } LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGemPropertiesStore, dbcPath,"GemProperties.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGlyphPropertiesStore, dbcPath,"GlyphProperties.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGlyphSlotStore, dbcPath,"GlyphSlot.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtBarberShopCostBaseStore,dbcPath,"gtBarberShopCostBase.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtCombatRatingsStore, dbcPath,"gtCombatRatings.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToMeleeCritBaseStore, dbcPath,"gtChanceToMeleeCritBase.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToMeleeCritStore, dbcPath,"gtChanceToMeleeCrit.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToSpellCritBaseStore, dbcPath,"gtChanceToSpellCritBase.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToSpellCritStore, dbcPath,"gtChanceToSpellCrit.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtOCTRegenHPStore, dbcPath,"gtOCTRegenHP.dbc"); //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtOCTRegenMPStore, dbcPath,"gtOCTRegenMP.dbc"); -- not used currently LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtRegenHPPerSptStore, dbcPath,"gtRegenHPPerSpt.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtRegenMPPerSptStore, dbcPath,"gtRegenMPPerSpt.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sHolidaysStore, dbcPath,"Holidays.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemStore, dbcPath,"Item.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemBagFamilyStore, dbcPath,"ItemBagFamily.dbc"); //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemDisplayInfoStore, dbcPath,"ItemDisplayInfo.dbc"); -- not used currently //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemCondExtCostsStore, dbcPath,"ItemCondExtCosts.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemExtendedCostStore, dbcPath,"ItemExtendedCost.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemLimitCategoryStore, dbcPath,"ItemLimitCategory.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemRandomPropertiesStore,dbcPath,"ItemRandomProperties.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemRandomSuffixStore, dbcPath,"ItemRandomSuffix.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemSetStore, dbcPath,"ItemSet.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sLFGDungeonStore, dbcPath,"LFGDungeons.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sLockStore, dbcPath,"Lock.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMailTemplateStore, dbcPath,"MailTemplate.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMapStore, dbcPath,"Map.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMapDifficultyStore, dbcPath,"MapDifficulty.dbc"); // fill data for (uint32 i = 1; i < sMapDifficultyStore.GetNumRows(); ++i) if (MapDifficultyEntry const* entry = sMapDifficultyStore.LookupEntry(i)) sMapDifficultyMap[MAKE_PAIR32(entry->MapId,entry->Difficulty)] = MapDifficulty(entry->resetTime,entry->maxPlayers,strlen(entry->areaTriggerText)>0); sMapDifficultyStore.Clear(); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMovieStore, dbcPath,"Movie.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sOverrideSpellDataStore, dbcPath,"OverrideSpellData.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestSortStore, dbcPath,"QuestSort.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sPvPDifficultyStore, dbcPath,"PvpDifficulty.dbc"); for (uint32 i = 0; i < sPvPDifficultyStore.GetNumRows(); ++i) if (PvPDifficultyEntry const* entry = sPvPDifficultyStore.LookupEntry(i)) if (entry->bracketId > MAX_BATTLEGROUND_BRACKETS) ASSERT(false && "Need update MAX_BATTLEGROUND_BRACKETS by DBC data"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestXPStore, dbcPath,"QuestXP.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestFactionRewardStore, dbcPath,"QuestFactionReward.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sRandomPropertiesPointsStore, dbcPath,"RandPropPoints.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sScalingStatDistributionStore, dbcPath,"ScalingStatDistribution.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sScalingStatValuesStore, dbcPath,"ScalingStatValues.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSkillLineStore, dbcPath,"SkillLine.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSkillLineAbilityStore, dbcPath,"SkillLineAbility.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSoundEntriesStore, dbcPath,"SoundEntries.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellStore, dbcPath,"Spell.dbc", &CustomSpellEntryfmt, &CustomSpellEntryIndex); for (uint32 i = 1; i < sSpellStore.GetNumRows(); ++i) { SpellEntry const * spell = sSpellStore.LookupEntry(i); if (spell && spell->Category) sSpellCategoryStore[spell->Category].insert(i); } for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) { SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j); if (!skillLine) continue; SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId); if (spellInfo && IsPassiveSpell(spellInfo->Id)) { for (uint32 i = 1; i < sCreatureFamilyStore.GetNumRows(); ++i) { CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(i); if (!cFamily) continue; if (skillLine->skillId != cFamily->skillLine[0] && skillLine->skillId != cFamily->skillLine[1]) continue; if (spellInfo->spellLevel) continue; if (skillLine->learnOnGetSkill != ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL) continue; sPetFamilySpellsStore[i].insert(spellInfo->Id); } } } LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellCastTimesStore, dbcPath,"SpellCastTimes.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellDifficultyStore, dbcPath,"SpellDifficulty.dbc", &CustomSpellDifficultyfmt, &CustomSpellDifficultyIndex); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellDurationStore, dbcPath,"SpellDuration.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellFocusObjectStore, dbcPath,"SpellFocusObject.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellItemEnchantmentStore,dbcPath,"SpellItemEnchantment.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellItemEnchantmentConditionStore,dbcPath,"SpellItemEnchantmentCondition.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRadiusStore, dbcPath,"SpellRadius.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRangeStore, dbcPath,"SpellRange.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRuneCostStore, dbcPath,"SpellRuneCost.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellShapeshiftStore, dbcPath,"SpellShapeshiftForm.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sStableSlotPricesStore, dbcPath,"StableSlotPrices.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSummonPropertiesStore, dbcPath,"SummonProperties.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTalentStore, dbcPath,"Talent.dbc"); // Create Spelldifficulty searcher for (uint32 i = 0; i < sSpellDifficultyStore.GetNumRows(); ++i) { SpellDifficultyEntry const *spellDiff = sSpellDifficultyStore.LookupEntry(i); if (!spellDiff) continue; SpellDifficultyEntry newEntry; for (int x = 0; x < MAX_DIFFICULTY; ++x) { if (spellDiff->SpellID[x] <= 0 || !sSpellStore.LookupEntry(spellDiff->SpellID[x])) { if (spellDiff->SpellID[x] > 0)//don't show error if spell is <= 0, not all modes have spells and there are unknown negative values sLog.outErrorDb("spelldifficulty_dbc: spell %i at field id:%u at spellid%i does not exist in SpellStore (spell.dbc), loaded as 0", spellDiff->SpellID[x], spellDiff->ID, x); newEntry.SpellID[x] = 0;//spell was <= 0 or invalid, set to 0 } else newEntry.SpellID[x] = spellDiff->SpellID[x]; } if (newEntry.SpellID[0] <= 0 || newEntry.SpellID[1] <= 0)//id0-1 must be always set! continue; for (int x = 0; x < MAX_DIFFICULTY; ++x) sSpellMgr.SetSpellDifficultyId(uint32(newEntry.SpellID[x]), spellDiff->ID); } // create talent spells set for (unsigned int i = 0; i < sTalentStore.GetNumRows(); ++i) { TalentEntry const *talentInfo = sTalentStore.LookupEntry(i); if (!talentInfo) continue; for (int j = 0; j < MAX_TALENT_RANK; j++) if (talentInfo->RankID[j]) sTalentSpellPosMap[talentInfo->RankID[j]] = TalentSpellPos(i,j); } LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTalentTabStore, dbcPath,"TalentTab.dbc"); // prepare fast data access to bit pos of talent ranks for use at inspecting { // now have all max ranks (and then bit amount used for store talent ranks in inspect) for (uint32 talentTabId = 1; talentTabId < sTalentTabStore.GetNumRows(); ++talentTabId) { TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry(talentTabId); if (!talentTabInfo) continue; // prevent memory corruption; otherwise cls will become 12 below if ((talentTabInfo->ClassMask & CLASSMASK_ALL_PLAYABLE) == 0) continue; // store class talent tab pages uint32 cls = 1; for (uint32 m=1; !(m & talentTabInfo->ClassMask) && cls < MAX_CLASSES; m <<= 1, ++cls) {} sTalentTabPages[cls][talentTabInfo->tabpage]=talentTabId; } } LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiNodesStore, dbcPath,"TaxiNodes.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiPathStore, dbcPath,"TaxiPath.dbc"); for (uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++i) if (TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(i)) sTaxiPathSetBySource[entry->from][entry->to] = TaxiPathBySourceAndDestination(entry->ID,entry->price); uint32 pathCount = sTaxiPathStore.GetNumRows(); //## TaxiPathNode.dbc ## Loaded only for initialization different structures LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiPathNodeStore, dbcPath,"TaxiPathNode.dbc"); // Calculate path nodes count std::vector<uint32> pathLength; pathLength.resize(pathCount); // 0 and some other indexes not used for (uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i) if (TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i)) { if (pathLength[entry->path] < entry->index + 1) pathLength[entry->path] = entry->index + 1; } // Set path length sTaxiPathNodesByPath.resize(pathCount); // 0 and some other indexes not used for (uint32 i = 1; i < sTaxiPathNodesByPath.size(); ++i) sTaxiPathNodesByPath[i].resize(pathLength[i]); // fill data for (uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i) if (TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i)) sTaxiPathNodesByPath[entry->path].set(entry->index, entry); // Initialize global taxinodes mask // include existed nodes that have at least single not spell base (scripted) path { std::set<uint32> spellPaths; for (uint32 i = 1; i < sSpellStore.GetNumRows (); ++i) if (SpellEntry const* sInfo = sSpellStore.LookupEntry (i)) for (int j = 0; j < MAX_SPELL_EFFECTS; ++j) if (sInfo->Effect[j] == SPELL_EFFECT_SEND_TAXI) spellPaths.insert(sInfo->EffectMiscValue[j]); memset(sTaxiNodesMask,0,sizeof(sTaxiNodesMask)); memset(sOldContinentsNodesMask,0,sizeof(sOldContinentsNodesMask)); memset(sHordeTaxiNodesMask,0,sizeof(sHordeTaxiNodesMask)); memset(sAllianceTaxiNodesMask,0,sizeof(sAllianceTaxiNodesMask)); memset(sDeathKnightTaxiNodesMask,0,sizeof(sDeathKnightTaxiNodesMask)); for (uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i) { TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(i); if (!node) continue; TaxiPathSetBySource::const_iterator src_i = sTaxiPathSetBySource.find(i); if (src_i != sTaxiPathSetBySource.end() && !src_i->second.empty()) { bool ok = false; for (TaxiPathSetForSource::const_iterator dest_i = src_i->second.begin(); dest_i != src_i->second.end(); ++dest_i) { // not spell path if (spellPaths.find(dest_i->second.ID) == spellPaths.end()) { ok = true; break; } } if (!ok) continue; } // valid taxi network node uint8 field = (uint8)((i - 1) / 32); uint32 submask = 1<<((i-1)%32); sTaxiNodesMask[field] |= submask; if (node->MountCreatureID[0] && node->MountCreatureID[0] != 32981) sHordeTaxiNodesMask[field] |= submask; if (node->MountCreatureID[1] && node->MountCreatureID[1] != 32981) sAllianceTaxiNodesMask[field] |= submask; if (node->MountCreatureID[0] == 32981 || node->MountCreatureID[1] == 32981) sDeathKnightTaxiNodesMask[field] |= submask; // old continent node (+ nodes virtually at old continents, check explicitly to avoid loading map files for zone info) if (node->map_id < 2 || i == 82 || i == 83 || i == 93 || i == 94) sOldContinentsNodesMask[field] |= submask; // fix DK node at Ebon Hold if (i == 315) { ((TaxiNodesEntry*)node)->MountCreatureID[1] = 32981; } } } LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTotemCategoryStore, dbcPath,"TotemCategory.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sVehicleStore, dbcPath,"Vehicle.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sVehicleSeatStore, dbcPath,"VehicleSeat.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWMOAreaTableStore, dbcPath,"WMOAreaTable.dbc"); for(uint32 i = 0; i < sWMOAreaTableStore.GetNumRows(); ++i) { if(WMOAreaTableEntry const* entry = sWMOAreaTableStore.LookupEntry(i)) { sWMOAreaInfoByTripple.insert(WMOAreaInfoByTripple::value_type(WMOAreaTableTripple(entry->rootId, entry->adtId, entry->groupId), entry)); } } LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldMapAreaStore, dbcPath,"WorldMapArea.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldMapOverlayStore, dbcPath,"WorldMapOverlay.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldSafeLocsStore, dbcPath,"WorldSafeLocs.dbc"); // error checks if (bad_dbc_files.size() >= DBCFilesCount) { sLog.outError("\nIncorrect DataDir value in worldserver.conf or ALL required *.dbc files (%d) not found by path: %sdbc",DBCFilesCount,dataPath.c_str()); exit(1); } else if (!bad_dbc_files.empty()) { std::string str; for (std::list<std::string>::iterator i = bad_dbc_files.begin(); i != bad_dbc_files.end(); ++i) str += *i + "\n"; sLog.outError("\nSome required *.dbc files (%u from %d) not found or not compatible:\n%s",(uint32)bad_dbc_files.size(),DBCFilesCount,str.c_str()); exit(1); } // Check loaded DBC files proper version if (!sAreaStore.LookupEntry(3617) || // last area (areaflag) added in 3.3.5a !sCharTitlesStore.LookupEntry(177) || // last char title added in 3.3.5a !sGemPropertiesStore.LookupEntry(1629) || // last added spell in 3.3.5a !sItemStore.LookupEntry(56806) || // last gem property added in 3.3.5a !sItemExtendedCostStore.LookupEntry(2997) || // last item extended cost added in 3.3.5a !sMapStore.LookupEntry(724) || // last map added in 3.3.5a !sSpellStore.LookupEntry(80864) ) // last client known item added in 3.3.5a { sLog.outError("\nYou have _outdated_ DBC files. Please extract correct versions from current using client."); exit(1); } sLog.outString(); sLog.outString(">> Initialized %d data stores", DBCFilesCount); }
void InstanceSaveManager::_ResetOrWarnAll(uint32 mapid, Difficulty difficulty, bool warn, time_t resetTime) { // global reset for all instances of the given map MapEntry const* mapEntry = sMapStore.LookupEntry(mapid); if (!mapEntry->Instanceable()) return; time_t now = time(NULL); if (!warn) { MapDifficulty const* mapDiff = GetMapDifficultyData(mapid, difficulty); if (!mapDiff || !mapDiff->resetTime) { sLog->outError("InstanceSaveManager::ResetOrWarnAll: not valid difficulty or no reset delay for map %d", mapid); return; } // remove all binds to instances of the given map for (InstanceSaveHashMap::iterator itr = m_instanceSaveById.begin(); itr != m_instanceSaveById.end();) { if (itr->second->GetMapId() == mapid && itr->second->GetDifficulty() == difficulty) _ResetSave(itr); else ++itr; } // delete them from the DB, even if not loaded SQLTransaction trans = CharacterDatabase.BeginTransaction(); trans->PAppend("DELETE FROM character_instance USING character_instance LEFT JOIN instance ON character_instance.instance = id WHERE map = '%u' and difficulty='%u'", mapid, difficulty); trans->PAppend("DELETE FROM group_instance USING group_instance LEFT JOIN instance ON group_instance.instance = id WHERE map = '%u' and difficulty='%u'", mapid, difficulty); trans->PAppend("DELETE FROM instance WHERE map = '%u' and difficulty='%u'", mapid, difficulty); CharacterDatabase.CommitTransaction(trans); // calculate the next reset time uint32 diff = sWorld->getIntConfig(CONFIG_INSTANCE_RESET_TIME_HOUR) * HOUR; uint32 period = uint32(((mapDiff->resetTime * sWorld->getRate(RATE_INSTANCE_RESET_TIME))/DAY) * DAY); if (period < DAY) period = DAY; uint32 next_reset = ((resetTime + MINUTE) / DAY * DAY) + period + diff; SetResetTimeFor(mapid, difficulty, next_reset); ScheduleReset(true, time_t(next_reset-3600), InstResetEvent(1, mapid, difficulty, 0)); // Update it in the DB PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_GLOBAL_INSTANCE_RESETTIME); stmt->setUInt32(0, next_reset); stmt->setUInt16(1, uint16(mapid)); stmt->setUInt8(2, uint8(difficulty)); CharacterDatabase.Execute(stmt); } // note: this isn't fast but it's meant to be executed very rarely Map const* map = sMapMgr->CreateBaseMap(mapid); // _not_ include difficulty MapInstanced::InstancedMaps &instMaps = ((MapInstanced*)map)->GetInstancedMaps(); MapInstanced::InstancedMaps::iterator mitr; uint32 timeLeft; for (mitr = instMaps.begin(); mitr != instMaps.end(); ++mitr) { Map* map2 = mitr->second; if (!map2->IsDungeon()) continue; if (warn) { if (now <= resetTime) timeLeft = 0; else timeLeft = uint32(now - resetTime); ((InstanceMap*)map2)->SendResetWarnings(timeLeft); } else ((InstanceMap*)map2)->Reset(INSTANCE_RESET_GLOBAL); } // TODO: delete creature/gameobject respawn times even if the maps are not loaded }
//---------------------------------------------------------------------- int ana(void) { cmd.Op1.dtyp = dt_byte; code = ua_next_byte(); cmd.itype = (is_cmos ? cmos : nmos)[code]; if ( cmd.itype == M65_null ) return 0; switch ( code & 0x1F ) { // +08 PHP PLP PHA PLA DEY TAY INY INX Implied // +18 CLC SEC CLI SEI TYA CLV CLD SED Implied // +1a NOP* NOP* NOP* NOP* TXS TSX NOP* NOP* Implied // +1a inc dec phy ply txs tsx phx ply case 0x1A: case 0x08: case 0x18: switch ( cmd.itype ) { case M65_inc: case M65_dec: cmd.Op1.type = o_reg; cmd.Op1.reg = rA; } break; // +0a ASL ROL LSR ROR TXA TAX DEX NOP Accu/impl case 0x0A: switch ( cmd.itype ) { case M65_asl: case M65_rol: case M65_lsr: case M65_ror: cmd.Op1.type = o_reg; cmd.Op1.reg = rA; } break; // +00 BRK JSR RTI RTS NOP*/bra LDY CPY CPX Impl/immed // +02 t t t t NOP*t LDX NOP*t NOP*t ? /immed // +09 ORA AND EOR ADC NOP* LDA CMP SBC Immediate // +0b ANC** ANC** ASR** ARR** ANE** LXA** SBX** SBC* Immediate case 0x00: case 0x02: case 0x09: case 0x0B: switch ( cmd.itype ) { case M65_jsr: cmd.Op1.dtyp = dt_code; cmd.Op1.type = o_near; cmd.Op1.addr = ua_next_word(); break; case M65_brk: case M65_rti: case M65_rts: break; case M65_bra: goto M65_RELATIVE; default: cmd.Op1.type = o_imm; cmd.Op1.value = ua_next_byte(); break; } break; // +0c NOP*/tsb BIT JMP JMP () STY LDY CPY CPX Absolute // +0d ORA AND EOR ADC STA LDA CMP SBC Absolute // +0e ASL ROL LSR ROR STX LDX DEC INC Absolute // +0f SLO* RLA* SRE* RRA* SAX* LAX* DCP* ISB* Absolute // +0f bbr0 bbr2 bbr4 bbr6 bbs0 bbs2 bbs4 bbs6 Zero page relative case 0x0F: if ( is_cmos ) goto ZP_RELATIVE; case 0x0C: case 0x0D: case 0x0E: M65_ABSOLUTE: switch ( cmd.itype ) { case M65_jmp: cmd.Op1.dtyp = dt_code; cmd.Op1.type = o_near; break; case M65_jmpi: cmd.Op1.dtyp = dt_word; cmd.indirect = 1; /* no break */ default: cmd.Op1.type = o_mem; break; } cmd.Op1.addr = ua_next_word(); break; // +1c NOP*/trb NOP*/bit NOP* NOP*/jmp SHY**/stz LDY NOP* NOP* Absolute,x // +1d ORA AND EOR ADC STA LDA CMP SBC Absolute,x // +1e ASL ROL LSR ROR SHX**y) LDX y) DEC INC Absolute,x // +1f SLO* RLA* SRE* RRA* SHA**y) LAX* y) DCP ISB Absolute,x // +0f bbr1 bbr3 bbr5 bbr7 bbs1 bbs3 bbs5 bbs7 Zero page relative case 0x1F: if ( is_cmos ) { ZP_RELATIVE: cmd.Op1.type = o_mem; cmd.Op1.addr = ua_next_byte(); cmd.Op2.dtyp = dt_code; cmd.Op2.type = o_near; char x = ua_next_byte(); cmd.Op2.addr = cmd.ip + cmd.size + x; break; } /* fall thru */ case 0x1C: case 0x1D: case 0x1E: cmd.Op1.type = o_displ; cmd.Op1.phrase = rX; switch ( cmd.itype ) { case M65_stz: if ( code == 0x9E ) break; case M65_trb: goto M65_ABSOLUTE; case M65_shx: case M65_sha: case M65_ldx: case M65_lax: cmd.Op1.phrase = rY; break; case M65_jmpi: cmd.Op1.phrase = riX; break; } cmd.Op1.addr = ua_next_word(); break; // +19 ORA AND EOR ADC STA LDA CMP SBC Absolute,y // +1b SLO* RLA* SRE* RRA* SHS** LAS** DCP* ISB* Absolute,y case 0x19: case 0x1B: cmd.Op1.type = o_displ; cmd.Op1.phrase = rY; cmd.Op1.addr = ua_next_word(); break; // +10 BPL BMI BVC BVS BCC BCS BNE BEQ Relative case 0x10: M65_RELATIVE: cmd.Op1.dtyp = dt_code; cmd.Op1.type = o_near; { char x = ua_next_byte(); cmd.Op1.addr = cmd.ip + cmd.size + x; } break; // +01 ORA AND EOR ADC STA LDA CMP SBC (indir,x) // +03 SLO* RLA* SRE* RRA* SAX* LAX* y) DCP* ISB* (indir,x) case 0x01: case 0x03: cmd.Op1.type = o_displ; cmd.Op1.phrase = uint16((cmd.itype == M65_lax) ? riY : riX); cmd.Op1.addr = ua_next_byte(); // а для LAX? break; // +11 ORA AND EOR ADC STA LDA CMP SBC (indir),y // +13 SLO* RLA* SRE* RRA* SHA** LAX* DCP* ISB* (indir),y case 0x11: case 0x13: cmd.Op1.type = o_displ; cmd.Op1.phrase = riY; cmd.Op1.addr = ua_next_byte(); break; // +04 NOP*/tsb BIT NOP* NOP*/stz STY LDY CPY CPX Zeropage // +05 ORA AND EOR ADC STA LDA CMP SBC Zeropage // +06 ASL ROL LSR ROR STX LDX DEC INC Zeropage // +07 SLO* RLA* SRE* RRA* SAX* LAX* DCP* ISB* Zeropage // +07 rmb0 rmb2 rmb4 rmb6 smb0 smb2 smb4 smb6 Zeropage case 0x04: case 0x05: case 0x06: case 0x07: ZEROPAGE: cmd.Op1.type = o_mem; cmd.Op1.addr = ua_next_byte(); break; // +14 NOP*/trb NOP*/bit NOP* NOP*/stz STY LDY NOP* NOP* Zeropage,x // +15 ORA AND EOR ADC STA LDA CMP SBC Zeropage,x // +16 ASL ROL LSR ROR STX y) LDX y) DEC INC Zeropage,x // +17 SLO* RLA* SRE* RRA* SAX* y) LAX* y) DCP ISB Zeropage,x // +17 rmb1 rmb3 rmb5 rmb7 smb1 smb3 smb5 smb7 Zeropage case 0x17: if ( is_cmos ) goto ZEROPAGE; /* fall thru */ case 0x14: case 0x15: case 0x16: cmd.Op1.type = o_displ; cmd.Op1.phrase = zX; switch ( cmd.itype ) { case M65_trb: goto ZEROPAGE; case M65_stx: case M65_sax: case M65_ldx: case M65_lax: cmd.Op1.phrase = zY; break; } cmd.Op1.addr = ua_next_byte(); break; // +12 ora and eor adc sta lda cmp sbc Zeropage, indirect case 0x12: cmd.indirect = 1; cmd.Op1.type = o_mem; cmd.Op1.addr = ua_next_byte(); break; default: error("ana: bad code %x",code); } if ( cmd.itype == M65_nop ) cmd.Op1.type = o_void; return cmd.size; }
void LoadDBCStores(const std::string& dataPath) { std::string dbcPath = dataPath + "dbc/"; uint32 build = ReadDBCBuild(dbcPath); // Check the expected DBC version if (!IsAcceptableClientBuild(build)) { if (build) sLog.outError("Found DBC files for build %u but mangosd expected DBC for one from builds: %s Please extract correct DBC files.", build, AcceptableClientBuildsListStr().c_str()); else sLog.outError("Incorrect DataDir value in mangosd.conf or not found build info (outdated DBC files). Required one from builds: %s Please extract correct DBC files.", AcceptableClientBuildsListStr().c_str()); Log::WaitBeforeContinueIfNeed(); exit(1); } const uint32 DBCFilesCount = 94; BarGoLink bar(DBCFilesCount); StoreProblemList bad_dbc_files; LocalData availableDbcLocales(build); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sAreaStore, dbcPath, "AreaTable.dbc"); // must be after sAreaStore loading for (uint32 i = 0; i < sAreaStore.GetNumRows(); ++i) // areaflag numbered from 0 { if (AreaTableEntry const* area = sAreaStore.LookupEntry(i)) { // fill AreaId->DBC records sAreaFlagByAreaID.insert(AreaFlagByAreaID::value_type(uint16(area->ID), area->exploreFlag)); // fill MapId->DBC records ( skip sub zones and continents ) if (area->zone == 0 && area->mapid != 0 && area->mapid != 1 && area->mapid != 530 && area->mapid != 571) sAreaFlagByMapID.insert(AreaFlagByMapID::value_type(area->mapid, area->exploreFlag)); } } LoadDBC(availableDbcLocales, bar, bad_dbc_files, sAchievementStore, dbcPath, "Achievement.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sAchievementCriteriaStore, dbcPath, "Achievement_Criteria.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sAreaTriggerStore, dbcPath, "AreaTrigger.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sAreaGroupStore, dbcPath, "AreaGroup.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sAuctionHouseStore, dbcPath, "AuctionHouse.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sBankBagSlotPricesStore, dbcPath, "BankBagSlotPrices.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sBattlemasterListStore, dbcPath, "BattlemasterList.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sBarberShopStyleStore, dbcPath, "BarberShopStyle.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCharStartOutfitStore, dbcPath, "CharStartOutfit.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCharTitlesStore, dbcPath, "CharTitles.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sChatChannelsStore, dbcPath, "ChatChannels.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sChrClassesStore, dbcPath, "ChrClasses.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sChrRacesStore, dbcPath, "ChrRaces.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCinematicSequencesStore, dbcPath, "CinematicSequences.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCreatureDisplayInfoStore, dbcPath, "CreatureDisplayInfo.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCreatureDisplayInfoExtraStore, dbcPath, "CreatureDisplayInfoExtra.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCreatureFamilyStore, dbcPath, "CreatureFamily.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCreatureSpellDataStore, dbcPath, "CreatureSpellData.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCreatureTypeStore, dbcPath, "CreatureType.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCurrencyTypesStore, dbcPath, "CurrencyTypes.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sDestructibleModelDataStore, dbcPath, "DestructibleModelData.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sDungeonEncounterStore, dbcPath, "DungeonEncounter.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sDurabilityCostsStore, dbcPath, "DurabilityCosts.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sDurabilityQualityStore, dbcPath, "DurabilityQuality.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sEmotesStore, dbcPath, "Emotes.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sEmotesTextStore, dbcPath, "EmotesText.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sFactionStore, dbcPath, "Faction.dbc"); for (uint32 i = 0; i < sFactionStore.GetNumRows(); ++i) { FactionEntry const* faction = sFactionStore.LookupEntry(i); if (faction && faction->team) { SimpleFactionsList& flist = sFactionTeamMap[faction->team]; flist.push_back(i); } } LoadDBC(availableDbcLocales, bar, bad_dbc_files, sFactionTemplateStore, dbcPath, "FactionTemplate.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sGameObjectDisplayInfoStore, dbcPath, "GameObjectDisplayInfo.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sGemPropertiesStore, dbcPath, "GemProperties.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sGlyphPropertiesStore, dbcPath, "GlyphProperties.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sGlyphSlotStore, dbcPath, "GlyphSlot.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sGtBarberShopCostBaseStore, dbcPath, "gtBarberShopCostBase.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sGtCombatRatingsStore, dbcPath, "gtCombatRatings.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sGtChanceToMeleeCritBaseStore, dbcPath, "gtChanceToMeleeCritBase.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sGtChanceToMeleeCritStore, dbcPath, "gtChanceToMeleeCrit.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sGtChanceToSpellCritBaseStore, dbcPath, "gtChanceToSpellCritBase.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sGtChanceToSpellCritStore, dbcPath, "gtChanceToSpellCrit.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sGtOCTClassCombatRatingScalarStore, dbcPath, "gtOCTClassCombatRatingScalar.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sGtOCTRegenHPStore, dbcPath, "gtOCTRegenHP.dbc"); // LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtOCTRegenMPStore, dbcPath,"gtOCTRegenMP.dbc"); -- not used currently LoadDBC(availableDbcLocales, bar, bad_dbc_files, sGtRegenHPPerSptStore, dbcPath, "gtRegenHPPerSpt.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sGtRegenMPPerSptStore, dbcPath, "gtRegenMPPerSpt.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sHolidaysStore, dbcPath, "Holidays.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sItemStore, dbcPath, "Item.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sItemBagFamilyStore, dbcPath, "ItemBagFamily.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sItemClassStore, dbcPath, "ItemClass.dbc"); //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemDisplayInfoStore, dbcPath,"ItemDisplayInfo.dbc"); // Transmogrification // LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemCondExtCostsStore, dbcPath,"ItemCondExtCosts.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sItemExtendedCostStore, dbcPath, "ItemExtendedCost.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sItemLimitCategoryStore, dbcPath, "ItemLimitCategory.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sItemRandomPropertiesStore, dbcPath, "ItemRandomProperties.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sItemRandomSuffixStore, dbcPath, "ItemRandomSuffix.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sItemSetStore, dbcPath, "ItemSet.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sLiquidTypeStore, dbcPath, "LiquidType.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sLockStore, dbcPath, "Lock.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sMailTemplateStore, dbcPath, "MailTemplate.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sMapStore, dbcPath, "Map.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sMapDifficultyStore, dbcPath, "MapDifficulty.dbc"); // fill data for (uint32 i = 1; i < sMapDifficultyStore.GetNumRows(); ++i) if (MapDifficultyEntry const* entry = sMapDifficultyStore.LookupEntry(i)) sMapDifficultyMap[MAKE_PAIR32(entry->MapId, entry->Difficulty)] = entry; LoadDBC(availableDbcLocales, bar, bad_dbc_files, sMovieStore, dbcPath, "Movie.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sOverrideSpellDataStore, dbcPath, "OverrideSpellData.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sQuestFactionRewardStore, dbcPath, "QuestFactionReward.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sQuestSortStore, dbcPath, "QuestSort.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sQuestXPLevelStore, dbcPath, "QuestXP.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sPvPDifficultyStore, dbcPath, "PvpDifficulty.dbc"); for (uint32 i = 0; i < sPvPDifficultyStore.GetNumRows(); ++i) if (PvPDifficultyEntry const* entry = sPvPDifficultyStore.LookupEntry(i)) if (entry->bracketId > MAX_BATTLEGROUND_BRACKETS) MANGOS_ASSERT(false && "Need update MAX_BATTLEGROUND_BRACKETS by DBC data"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sRandomPropertiesPointsStore, dbcPath, "RandPropPoints.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sScalingStatDistributionStore, dbcPath, "ScalingStatDistribution.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sScalingStatValuesStore, dbcPath, "ScalingStatValues.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSkillLineStore, dbcPath, "SkillLine.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSkillLineAbilityStore, dbcPath, "SkillLineAbility.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSkillRaceClassInfoStore, dbcPath, "SkillRaceClassInfo.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSoundEntriesStore, dbcPath, "SoundEntries.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellStore, dbcPath, "Spell.dbc"); for (uint32 i = 1; i < sSpellStore.GetNumRows(); ++i) { SpellEntry const* spell = sSpellStore.LookupEntry(i); if (spell && spell->Category) sSpellCategoryStore[spell->Category].insert(i); // DBC not support uint64 fields but SpellEntry have SpellFamilyFlags mapped at 2 uint32 fields // uint32 field already converted to bigendian if need, but must be swapped for correct uint64 bigendian view #if MANGOS_ENDIAN == MANGOS_BIGENDIAN std::swap(*((uint32*)(&spell->SpellFamilyFlags)), *(((uint32*)(&spell->SpellFamilyFlags)) + 1)); #endif } for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) { SkillLineAbilityEntry const* skillLine = sSkillLineAbilityStore.LookupEntry(j); if (!skillLine) continue; SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId); if (spellInfo && (spellInfo->Attributes & (SPELL_ATTR_UNK4 | SPELL_ATTR_PASSIVE | SPELL_ATTR_UNK7 | SPELL_ATTR_UNK8)) == (SPELL_ATTR_UNK4 | SPELL_ATTR_PASSIVE | SPELL_ATTR_UNK7 | SPELL_ATTR_UNK8)) { for (unsigned int i = 1; i < sCreatureFamilyStore.GetNumRows(); ++i) { CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(i); if (!cFamily) continue; if (skillLine->skillId != cFamily->skillLine[0] && skillLine->skillId != cFamily->skillLine[1]) continue; sPetFamilySpellsStore[i].insert(spellInfo->Id); } } } LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellCastTimesStore, dbcPath, "SpellCastTimes.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellDurationStore, dbcPath, "SpellDuration.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellDifficultyStore, dbcPath, "SpellDifficulty.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellFocusObjectStore, dbcPath, "SpellFocusObject.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellItemEnchantmentStore, dbcPath, "SpellItemEnchantment.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellItemEnchantmentConditionStore, dbcPath, "SpellItemEnchantmentCondition.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellRadiusStore, dbcPath, "SpellRadius.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellRangeStore, dbcPath, "SpellRange.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellRuneCostStore, dbcPath, "SpellRuneCost.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellShapeshiftFormStore, dbcPath, "SpellShapeshiftForm.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sStableSlotPricesStore, dbcPath, "StableSlotPrices.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSummonPropertiesStore, dbcPath, "SummonProperties.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sTalentStore, dbcPath, "Talent.dbc"); // create talent spells set for (unsigned int i = 0; i < sTalentStore.GetNumRows(); ++i) { TalentEntry const* talentInfo = sTalentStore.LookupEntry(i); if (!talentInfo) continue; for (int j = 0; j < MAX_TALENT_RANK; ++j) if (talentInfo->RankID[j]) sTalentSpellPosMap[talentInfo->RankID[j]] = TalentSpellPos(i, j); } LoadDBC(availableDbcLocales, bar, bad_dbc_files, sTalentTabStore, dbcPath, "TalentTab.dbc"); // prepare fast data access to bit pos of talent ranks for use at inspecting { // now have all max ranks (and then bit amount used for store talent ranks in inspect) for (uint32 talentTabId = 1; talentTabId < sTalentTabStore.GetNumRows(); ++talentTabId) { TalentTabEntry const* talentTabInfo = sTalentTabStore.LookupEntry(talentTabId); if (!talentTabInfo) continue; // prevent memory corruption; otherwise cls will become 12 below if ((talentTabInfo->ClassMask & CLASSMASK_ALL_PLAYABLE) == 0) continue; // store class talent tab pages uint32 cls = 1; for (uint32 m = 1; !(m & talentTabInfo->ClassMask) && cls < MAX_CLASSES; m <<= 1, ++cls) {} sTalentTabPages[cls][talentTabInfo->tabpage] = talentTabId; } } LoadDBC(availableDbcLocales, bar, bad_dbc_files, sTaxiNodesStore, dbcPath, "TaxiNodes.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sTaxiPathStore, dbcPath, "TaxiPath.dbc"); for (uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++i) if (TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(i)) sTaxiPathSetBySource[entry->from][entry->to] = TaxiPathBySourceAndDestination(entry->ID, entry->price); uint32 pathCount = sTaxiPathStore.GetNumRows(); //## TaxiPathNode.dbc ## Loaded only for initialization different structures LoadDBC(availableDbcLocales, bar, bad_dbc_files, sTaxiPathNodeStore, dbcPath, "TaxiPathNode.dbc"); // Calculate path nodes count std::vector<uint32> pathLength; pathLength.resize(pathCount); // 0 and some other indexes not used for (uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i) if (TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i)) { if (pathLength[entry->path] < entry->index + 1) pathLength[entry->path] = entry->index + 1; } // Set path length sTaxiPathNodesByPath.resize(pathCount); // 0 and some other indexes not used for (uint32 i = 1; i < sTaxiPathNodesByPath.size(); ++i) sTaxiPathNodesByPath[i].resize(pathLength[i]); // fill data (pointers to sTaxiPathNodeStore elements for (uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i) if (TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i)) sTaxiPathNodesByPath[entry->path].set(entry->index, entry); // Initialize global taxinodes mask // include existing nodes that have at least single not spell base (scripted) path { std::set<uint32> spellPaths; for (uint32 i = 1; i < sSpellStore.GetNumRows(); ++i) if (SpellEntry const* sInfo = sSpellStore.LookupEntry(i)) for (int j = 0; j < MAX_EFFECT_INDEX; ++j) if (sInfo->Effect[j] == 123 /*SPELL_EFFECT_SEND_TAXI*/) spellPaths.insert(sInfo->EffectMiscValue[j]); memset(sTaxiNodesMask, 0, sizeof(sTaxiNodesMask)); memset(sOldContinentsNodesMask, 0, sizeof(sTaxiNodesMask)); for (uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i) { TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(i); if (!node) continue; TaxiPathSetBySource::const_iterator src_i = sTaxiPathSetBySource.find(i); if (src_i != sTaxiPathSetBySource.end() && !src_i->second.empty()) { bool ok = false; for (TaxiPathSetForSource::const_iterator dest_i = src_i->second.begin(); dest_i != src_i->second.end(); ++dest_i) { // not spell path if (spellPaths.find(dest_i->second.ID) == spellPaths.end()) { ok = true; break; } } if (!ok) continue; } // valid taxi network node uint8 field = (uint8)((i - 1) / 32); uint32 submask = 1 << ((i - 1) % 32); sTaxiNodesMask[field] |= submask; // old continent node (+ nodes virtually at old continents, check explicitly to avoid loading map files for zone info) if (node->map_id < 2 || i == 82 || i == 83 || i == 93 || i == 94) sOldContinentsNodesMask[field] |= submask; // Hack DK node at Ebon Hold (unclear if bad dbc data or we need to revisit our checks in ObjectMgr::GetNearestTaxiNode ) if (i == 315) (const_cast<TaxiNodesEntry*>(node))->MountCreatureID[1] = node->MountCreatureID[0]; } } LoadDBC(availableDbcLocales, bar, bad_dbc_files, sTeamContributionPoints, dbcPath, "TeamContributionPoints.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sTotemCategoryStore, dbcPath, "TotemCategory.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sVehicleStore, dbcPath, "Vehicle.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sVehicleSeatStore, dbcPath, "VehicleSeat.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sWorldMapAreaStore, dbcPath, "WorldMapArea.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sWMOAreaTableStore, dbcPath, "WMOAreaTable.dbc"); for (uint32 i = 0; i < sWMOAreaTableStore.GetNumRows(); ++i) { if (WMOAreaTableEntry const* entry = sWMOAreaTableStore.LookupEntry(i)) { sWMOAreaInfoByTripple.insert(WMOAreaInfoByTripple::value_type(WMOAreaTableTripple(entry->rootId, entry->adtId, entry->groupId), entry)); } } LoadDBC(availableDbcLocales, bar, bad_dbc_files, sWorldMapOverlayStore, dbcPath, "WorldMapOverlay.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sWorldSafeLocsStore, dbcPath, "WorldSafeLocs.dbc"); // error checks if (bad_dbc_files.size() >= DBCFilesCount) { sLog.outError("\nIncorrect DataDir value in mangosd.conf or ALL required *.dbc files (%d) not found by path: %sdbc", DBCFilesCount, dataPath.c_str()); Log::WaitBeforeContinueIfNeed(); exit(1); } else if (!bad_dbc_files.empty()) { std::string str; for (std::list<std::string>::iterator i = bad_dbc_files.begin(); i != bad_dbc_files.end(); ++i) str += *i + "\n"; sLog.outError("\nSome required *.dbc files (%u from %d) not found or not compatible:\n%s", (uint32)bad_dbc_files.size(), DBCFilesCount, str.c_str()); Log::WaitBeforeContinueIfNeed(); exit(1); } // Check loaded DBC files proper version if (!sAreaStore.LookupEntry(3617) || // last area (areaflag) added in 3.3.5a !sCharTitlesStore.LookupEntry(177) || // last char title added in 3.3.5a !sGemPropertiesStore.LookupEntry(1629) || // last gem property added in 3.3.5a !sItemStore.LookupEntry(56806) || // last client known item added in 3.3.5a !sItemExtendedCostStore.LookupEntry(2997) || // last item extended cost added in 3.3.5a !sMapStore.LookupEntry(724) || // last map added in 3.3.5a !sSpellStore.LookupEntry(80864)) // last added spell in 3.3.5a { sLog.outError("\nYou have mixed version DBC files. Please re-extract DBC files for one from client build: %s", AcceptableClientBuildsListStr().c_str()); Log::WaitBeforeContinueIfNeed(); exit(1); } sLog.outString(); sLog.outString(">> Initialized %d data stores", DBCFilesCount); }
void LoadDBCStores(const std::string& dataPath) { std::string dbcPath = dataPath + "dbc/"; const uint32 DBCFilesCount = 50; BarGoLink bar(DBCFilesCount); StoreProblemList bad_dbc_files; // bitmask for index of fullLocaleNameList uint32 availableDbcLocales = 0xFFFFFFFF; LoadDBC(availableDbcLocales, bar, bad_dbc_files, sAreaStore, dbcPath, "AreaTable.dbc"); // must be after sAreaStore loading for (uint32 i = 1; i <= sAreaStore.GetNumRows(); ++i) // areaid numbered from 1 { if (AreaTableEntry const* area = sAreaStore.LookupEntry(i)) { // fill AreaId->DBC records sAreaIDByAreaFlag.insert(AreaIDByAreaFlag::value_type(uint16(area->exploreFlag), area->ID)); // fill MapId->DBC records ( skip sub zones and continents ) if (area->zone == 0 && area->mapid != 0 && area->mapid != 1) sAreaFlagByMapID.insert(AreaFlagByMapID::value_type(area->mapid, area->exploreFlag)); } } LoadDBC(availableDbcLocales, bar, bad_dbc_files, sAreaTriggerStore, dbcPath, "AreaTrigger.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sAuctionHouseStore, dbcPath, "AuctionHouse.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sBankBagSlotPricesStore, dbcPath, "BankBagSlotPrices.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCharStartOutfitStore, dbcPath, "CharStartOutfit.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sChatChannelsStore, dbcPath, "ChatChannels.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sChrClassesStore, dbcPath, "ChrClasses.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sChrRacesStore, dbcPath, "ChrRaces.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCinematicCameraStore, dbcPath, "CinematicCamera.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCinematicSequencesStore, dbcPath, "CinematicSequences.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCreatureDisplayInfoStore, dbcPath, "CreatureDisplayInfo.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCreatureDisplayInfoExtraStore, dbcPath, "CreatureDisplayInfoExtra.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCreatureFamilyStore, dbcPath, "CreatureFamily.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCreatureSpellDataStore, dbcPath, "CreatureSpellData.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCreatureTypeStore, dbcPath, "CreatureType.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sDurabilityCostsStore, dbcPath, "DurabilityCosts.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sDurabilityQualityStore, dbcPath, "DurabilityQuality.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sEmotesStore, dbcPath, "Emotes.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sEmotesTextStore, dbcPath, "EmotesText.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sFactionStore, dbcPath, "Faction.dbc"); for (uint32 i = 0; i < sFactionStore.GetNumRows(); ++i) { FactionEntry const* faction = sFactionStore.LookupEntry(i); if (faction && faction->team) { SimpleFactionsList& flist = sFactionTeamMap[faction->team]; flist.push_back(i); } } LoadDBC(availableDbcLocales, bar, bad_dbc_files, sFactionTemplateStore, dbcPath, "FactionTemplate.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sGameObjectDisplayInfoStore, dbcPath, "GameObjectDisplayInfo.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sItemBagFamilyStore, dbcPath, "ItemBagFamily.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sItemClassStore, dbcPath, "ItemClass.dbc"); // LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemDisplayInfoStore, dbcPath,"ItemDisplayInfo.dbc"); -- not used currently // LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemCondExtCostsStore, dbcPath,"ItemCondExtCosts.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sItemRandomPropertiesStore, dbcPath, "ItemRandomProperties.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sItemSetStore, dbcPath, "ItemSet.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sLiquidTypeStore, dbcPath, "LiquidType.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sLockStore, dbcPath, "Lock.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sMailTemplateStore, dbcPath, "MailTemplate.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sMapStore, dbcPath, "Map.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sQuestSortStore, dbcPath, "QuestSort.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSkillLineStore, dbcPath, "SkillLine.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSkillLineAbilityStore, dbcPath, "SkillLineAbility.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSkillRaceClassInfoStore, dbcPath, "SkillRaceClassInfo.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSoundEntriesStore, dbcPath, "SoundEntries.dbc"); for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) { SkillLineAbilityEntry const* skillLine = sSkillLineAbilityStore.LookupEntry(j); if (!skillLine) continue; SpellEntry const* spellInfo = sSpellTemplate.LookupEntry<SpellEntry>(skillLine->spellId); if (spellInfo && (spellInfo->Attributes & (SPELL_ATTR_ABILITY | SPELL_ATTR_PASSIVE | SPELL_ATTR_HIDDEN_CLIENTSIDE | SPELL_ATTR_HIDE_IN_COMBAT_LOG)) == (SPELL_ATTR_ABILITY | SPELL_ATTR_PASSIVE | SPELL_ATTR_HIDDEN_CLIENTSIDE | SPELL_ATTR_HIDE_IN_COMBAT_LOG)) { for (unsigned int i = 1; i < sCreatureFamilyStore.GetNumRows(); ++i) { CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(i); if (!cFamily) continue; if (skillLine->skillId != cFamily->skillLine[0] && skillLine->skillId != cFamily->skillLine[1]) continue; sPetFamilySpellsStore[i].insert(spellInfo->Id); } } } LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellCastTimesStore, dbcPath, "SpellCastTimes.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellDurationStore, dbcPath, "SpellDuration.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellFocusObjectStore, dbcPath, "SpellFocusObject.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellItemEnchantmentStore, dbcPath, "SpellItemEnchantment.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellRadiusStore, dbcPath, "SpellRadius.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellRangeStore, dbcPath, "SpellRange.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellShapeshiftFormStore, dbcPath, "SpellShapeshiftForm.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sStableSlotPricesStore, dbcPath, "StableSlotPrices.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sTalentStore, dbcPath, "Talent.dbc"); // create talent spells set for (unsigned int i = 0; i < sTalentStore.GetNumRows(); ++i) { TalentEntry const* talentInfo = sTalentStore.LookupEntry(i); if (!talentInfo) continue; for (int j = 0; j < 5; ++j) if (talentInfo->RankID[j]) sTalentSpellPosMap[talentInfo->RankID[j]] = TalentSpellPos(i, j); } LoadDBC(availableDbcLocales, bar, bad_dbc_files, sTalentTabStore, dbcPath, "TalentTab.dbc"); // prepare fast data access to bit pos of talent ranks for use at inspecting { // fill table by amount of talent ranks and fill sTalentTabBitSizeInInspect // store in with (row,col,talent)->size key for correct sorting by (row,col) typedef std::map<uint32, uint32> TalentBitSize; TalentBitSize sTalentBitSize; for (uint32 i = 1; i < sTalentStore.GetNumRows(); ++i) { TalentEntry const* talentInfo = sTalentStore.LookupEntry(i); if (!talentInfo) continue; TalentTabEntry const* talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TalentTab); if (!talentTabInfo) continue; // find talent rank uint32 curtalent_maxrank = 0; for (uint32 k = 5; k > 0; --k) { if (talentInfo->RankID[k - 1]) { curtalent_maxrank = k; break; } } sTalentBitSize[(talentInfo->Row << 24) + (talentInfo->Col << 16) + talentInfo->TalentID] = curtalent_maxrank; sTalentTabSizeInInspect[talentInfo->TalentTab] += curtalent_maxrank; } // now have all max ranks (and then bit amount used for store talent ranks in inspect) for (uint32 talentTabId = 1; talentTabId < sTalentTabStore.GetNumRows(); ++talentTabId) { TalentTabEntry const* talentTabInfo = sTalentTabStore.LookupEntry(talentTabId); if (!talentTabInfo) continue; // prevent memory corruption; otherwise cls will become 12 below if ((talentTabInfo->ClassMask & CLASSMASK_ALL_PLAYABLE) == 0) continue; // store class talent tab pages uint32 cls = 1; for (uint32 m = 1; !(m & talentTabInfo->ClassMask) && cls < MAX_CLASSES; m <<= 1, ++cls) {} sTalentTabPages[cls][talentTabInfo->tabpage] = talentTabId; // add total amount bits for first rank starting from talent tab first talent rank pos. uint32 pos = 0; for (TalentBitSize::iterator itr = sTalentBitSize.begin(); itr != sTalentBitSize.end(); ++itr) { uint32 talentId = itr->first & 0xFFFF; TalentEntry const* talentInfo = sTalentStore.LookupEntry(talentId); if (!talentInfo) continue; if (talentInfo->TalentTab != talentTabId) continue; sTalentPosInInspect[talentId] = pos; pos += itr->second; } } } LoadDBC(availableDbcLocales, bar, bad_dbc_files, sTaxiNodesStore, dbcPath, "TaxiNodes.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sTaxiPathStore, dbcPath, "TaxiPath.dbc"); for (uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++i) if (TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(i)) sTaxiPathSetBySource[entry->from][entry->to] = TaxiPathBySourceAndDestination(entry->ID, entry->price); uint32 pathCount = sTaxiPathStore.GetNumRows(); //## TaxiPathNode.dbc ## Loaded only for initialization different structures LoadDBC(availableDbcLocales, bar, bad_dbc_files, sTaxiPathNodeStore, dbcPath, "TaxiPathNode.dbc"); // Calculate path nodes count std::vector<uint32> pathLength; pathLength.resize(pathCount); // 0 and some other indexes not used for (uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i) if (TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i)) { if (pathLength[entry->path] < entry->index + 1) pathLength[entry->path] = entry->index + 1; } // Set path length sTaxiPathNodesByPath.resize(pathCount); // 0 and some other indexes not used for (uint32 i = 1; i < sTaxiPathNodesByPath.size(); ++i) sTaxiPathNodesByPath[i].resize(pathLength[i]); // fill data (pointers to sTaxiPathNodeStore elements for (uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i) if (TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i)) sTaxiPathNodesByPath[entry->path][entry->index] = entry; // Initialize global taxinodes mask // include existing nodes that have at least single not spell base (scripted) path { std::set<uint32> spellPaths; for (uint32 i = 1; i < sSpellTemplate.GetMaxEntry(); ++i) if (SpellEntry const* sInfo = sSpellTemplate.LookupEntry<SpellEntry>(i)) for (int j = 0; j < MAX_EFFECT_INDEX; ++j) if (sInfo->Effect[j] == 123 /*SPELL_EFFECT_SEND_TAXI*/) spellPaths.insert(sInfo->EffectMiscValue[j]); memset(sTaxiNodesMask, 0, sizeof(sTaxiNodesMask)); for (uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i) { TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(i); if (!node) continue; TaxiPathSetBySource::const_iterator src_i = sTaxiPathSetBySource.find(i); if (src_i != sTaxiPathSetBySource.end() && !src_i->second.empty()) { bool ok = false; for (const auto& dest_i : src_i->second) { // not spell path if (spellPaths.find(dest_i.second.ID) == spellPaths.end()) { ok = true; break; } } if (!ok) continue; } // valid taxi network node uint8 field = (uint8)((i - 1) / 32); uint32 submask = 1 << ((i - 1) % 32); sTaxiNodesMask[field] |= submask; } } LoadDBC(availableDbcLocales, bar, bad_dbc_files, sWorldMapAreaStore, dbcPath, "WorldMapArea.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sWMOAreaTableStore, dbcPath, "WMOAreaTable.dbc"); for (uint32 i = 0; i < sWMOAreaTableStore.GetNumRows(); ++i) { if (WMOAreaTableEntry const* entry = sWMOAreaTableStore.LookupEntry(i)) { sWMOAreaInfoByTripple.insert(WMOAreaInfoByTripple::value_type(WMOAreaTableTripple(entry->rootId, entry->adtId, entry->groupId), entry)); } } // LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldMapOverlayStore, dbcPath,"WorldMapOverlay.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sWorldSafeLocsStore, dbcPath, "WorldSafeLocs.dbc"); // error checks if (bad_dbc_files.size() >= DBCFilesCount) { sLog.outError("\nIncorrect DataDir value in mangosd.conf or ALL required *.dbc files (%d) not found by path: %sdbc", DBCFilesCount, dataPath.c_str()); Log::WaitBeforeContinueIfNeed(); exit(1); } if (!bad_dbc_files.empty()) { std::string str; for (auto& bad_dbc_file : bad_dbc_files) str += bad_dbc_file + "\n"; sLog.outError("\nSome required *.dbc files (%u from %d) not found or not compatible:\n%s", (uint32)bad_dbc_files.size(), DBCFilesCount, str.c_str()); Log::WaitBeforeContinueIfNeed(); exit(1); } // Check loaded DBC files proper version if (!sSkillLineAbilityStore.LookupEntry(15030) || !sMapStore.LookupEntry(533) || !sAreaStore.LookupEntry(3486)) { sLog.outError("\nYou have _outdated_ DBC files. Please re-extract DBC files for one from client build: %s", AcceptableClientBuildsListStr().c_str()); Log::WaitBeforeContinueIfNeed(); exit(1); } sLog.outString(">> Initialized %d data stores", DBCFilesCount); sLog.outString(); }
void HCIPDU::set_uint32(uint16 offset,uint32 data) { set_uint16(offset,uint16(data & 0xffff)) ; set_uint16(offset+2,uint16(data >> 16)) ; }
void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacket *data) { uint32 mask = player->GetGroupUpdateFlag(); if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) // if update power type, update current/max power also mask |= (GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER); if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) // same for pets mask |= (GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER); uint32 byteCount = 0; for (int i = 1; i < GROUP_UPDATE_FLAGS_COUNT; ++i) if (mask & (1 << i)) byteCount += GroupUpdateLength[i]; data->Initialize(SMSG_PARTY_MEMBER_STATS, 8 + 4 + byteCount); *data << player->GetPackGUID(); *data << uint32(mask); if (mask & GROUP_UPDATE_FLAG_STATUS) { if (player) { if (player->IsPvP()) *data << uint16(MEMBER_STATUS_ONLINE | MEMBER_STATUS_PVP); else *data << uint16(MEMBER_STATUS_ONLINE); } else *data << uint16(MEMBER_STATUS_OFFLINE); } if (mask & GROUP_UPDATE_FLAG_CUR_HP) *data << uint32(player->GetHealth()); if (mask & GROUP_UPDATE_FLAG_MAX_HP) *data << uint32(player->GetMaxHealth()); Powers powerType = player->getPowerType(); if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) *data << uint8(powerType); if (mask & GROUP_UPDATE_FLAG_CUR_POWER) *data << uint16(player->GetPower(powerType)); if (mask & GROUP_UPDATE_FLAG_MAX_POWER) *data << uint16(player->GetMaxPower(powerType)); if (mask & GROUP_UPDATE_FLAG_LEVEL) *data << uint16(player->getLevel()); if (mask & GROUP_UPDATE_FLAG_ZONE) *data << uint16(player->GetZoneId()); if (mask & GROUP_UPDATE_FLAG_POSITION) *data << uint16(player->GetPositionX()) << uint16(player->GetPositionY()); if (mask & GROUP_UPDATE_FLAG_AURAS) { const uint64& auramask = player->GetAuraUpdateMask(); *data << uint64(auramask); for(uint32 i = 0; i < MAX_AURAS; ++i) { if(auramask & (uint64(1) << i)) { *data << uint32(player->GetVisibleAura(i)); *data << uint8(1); } } } Pet *pet = player->GetPet(); if (mask & GROUP_UPDATE_FLAG_PET_GUID) *data << (pet ? pet->GetObjectGuid() : ObjectGuid()); if (mask & GROUP_UPDATE_FLAG_PET_NAME) { if(pet) *data << pet->GetName(); else *data << uint8(0); } if (mask & GROUP_UPDATE_FLAG_PET_MODEL_ID) { if(pet) *data << uint16(pet->GetDisplayId()); else *data << uint16(0); } if (mask & GROUP_UPDATE_FLAG_PET_CUR_HP) { if(pet) *data << uint32(pet->GetHealth()); else *data << uint32(0); } if (mask & GROUP_UPDATE_FLAG_PET_MAX_HP) { if(pet) *data << uint32(pet->GetMaxHealth()); else *data << uint32(0); } if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) { if(pet) *data << uint8(pet->getPowerType()); else *data << uint8(0); } if (mask & GROUP_UPDATE_FLAG_PET_CUR_POWER) { if(pet) *data << uint16(pet->GetPower(pet->getPowerType())); else *data << uint16(0); } if (mask & GROUP_UPDATE_FLAG_PET_MAX_POWER) { if(pet) *data << uint16(pet->GetMaxPower(pet->getPowerType())); else *data << uint16(0); } if (mask & GROUP_UPDATE_FLAG_PET_AURAS) { if(pet) { const uint64& auramask = pet->GetAuraUpdateMask(); *data << uint64(auramask); for(uint32 i = 0; i < MAX_AURAS; ++i) { if(auramask & (uint64(1) << i)) { *data << uint32(pet->GetVisibleAura(i)); *data << uint8(1); } } } else *data << uint64(0); } if (mask & GROUP_UPDATE_FLAG_VEHICLE_SEAT) *data << uint32(player->m_movementInfo.GetTransportDBCSeat()); }
void HCIPDU::set_uint24(uint16 offset,uint24 data) { set_uint16(offset,uint16(data & 0xffff)) ; set_uint8(offset+2,uint8(data >> 16)) ; }
// Realm List command handler bool AuthSocket::_HandleRealmList() { sLog->outStaticDebug("Entering _HandleRealmList"); if (socket().recv_len() < 5) return false; socket().recv_skip(5); // Get the user id (else close the connection) // No SQL injection (prepared statement) PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_ID_BY_NAME); stmt->setString(0, _login); PreparedQueryResult result = LoginDatabase.Query(stmt); if (!result) { sLog->outError("'%s:%d' [ERROR] user %s tried to login but we cannot find him in the database.", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str()); socket().shutdown(); return false; } Field* fields = result->Fetch(); uint32 id = fields[0].GetUInt32(); // Update realm list if need sRealmList->UpdateIfNeed(); // Circle through realms in the RealmList and construct the return packet (including # of user characters in each realm) ByteBuffer pkt; size_t RealmListSize = 0; for (RealmList::RealmMap::const_iterator i = sRealmList->begin(); i != sRealmList->end(); ++i) { // don't work with realms which not compatible with the client if ((_expversion & POST_BC_EXP_FLAG) && i->second.gamebuild != _build) continue; else if ((_expversion & PRE_BC_EXP_FLAG) && !AuthHelper::IsPreBCAcceptedClientBuild(i->second.gamebuild)) continue; uint8 AmountOfCharacters; // No SQL injection. id of realm is controlled by the database. stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_NUM_CHARS_ON_REALM); stmt->setUInt32(0, i->second.m_ID); stmt->setUInt32(1, id); result = LoginDatabase.Query(stmt); if (result) AmountOfCharacters = (*result)[0].GetUInt8(); else AmountOfCharacters = 0; uint8 lock = (i->second.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0; pkt << i->second.icon; // realm type if ( _expversion & POST_BC_EXP_FLAG ) // only 2.x and 3.x clients pkt << lock; // if 1, then realm locked pkt << uint8(i->second.flag); // RealmFlags pkt << i->first; pkt << i->second.address; pkt << i->second.populationLevel; pkt << AmountOfCharacters; pkt << i->second.timezone; // realm category if (_expversion & POST_BC_EXP_FLAG) // 2.x and 3.x clients pkt << (uint8)0x2C; // unk, may be realm number/id? else pkt << (uint8)0x0; // 1.12.1 and 1.12.2 clients if (i->second.flag & REALM_FLAG_SPECIFYBUILD) { // TODO: Make this customizable pkt << uint8(3); pkt << uint8(3); pkt << uint8(5); pkt << uint16(12340); } ++RealmListSize; } if ( _expversion & POST_BC_EXP_FLAG ) // 2.x and 3.x clients { pkt << (uint8)0x10; pkt << (uint8)0x00; } else // 1.12.1 and 1.12.2 clients { pkt << (uint8)0x00; pkt << (uint8)0x02; } // make a ByteBuffer which stores the RealmList's size ByteBuffer RealmListSizeBuffer; RealmListSizeBuffer << (uint32)0; if (_expversion & POST_BC_EXP_FLAG) // only 2.x and 3.x clients RealmListSizeBuffer << (uint16)RealmListSize; else RealmListSizeBuffer << (uint32)RealmListSize; ByteBuffer hdr; hdr << (uint8) REALM_LIST; hdr << (uint16)(pkt.size() + RealmListSizeBuffer.size()); hdr.append(RealmListSizeBuffer); // append RealmList's size buffer hdr.append(pkt); // append realms in the realmlist socket().send((char const*)hdr.contents(), hdr.size()); return true; }
void CEnlargetMapData::CreateTransformTerrainMesh( string strTitle, DWORD dwWidth, DWORD dwDepth ) { string strMapName(""); size_t npos = strTitle.rfind("\\"); if( npos != -1 ) strMapName = strTitle.substr(npos+1, strTitle.length()); npos = strMapName.rfind("."); if( npos != -1 ) strMapName = strMapName.substr(0, npos); if( strMapName.empty() ) { MessageBox(NULL,"需要切割的地图名为空,请重新选择","提示",MB_OK); return; } // rgn mask int newGridCnt = 0, SceneLightCount = 0; DWORD newVertexCnt = 0; DWORD dwMapWidth = dwWidth * REGION_SPACE; DWORD dwMapDepth = dwDepth * REGION_SPACE; newGridCnt = dwMapWidth * dwMapDepth; newVertexCnt = (dwMapWidth + 1) * (dwMapDepth + 1); ////////////////////////////////////////////////////////////////////////// CMapEditApp::GetInst()->GetDataScene()->SetWidth( uint16(dwWidth) ); CMapEditApp::GetInst()->GetDataScene()->SetHeight( uint16(dwDepth) ); CMapEditApp::GetInst()->GetDataScene()->Create(); CSyncSystem::BeginSyncFun(); CMapEditApp::GetInst()->InitNewRenderScene(); CMapEditApp::GetInst()->GetRenderScene()->InitSceneRes(); CTerrainMesh *pTerrainNew = NULL; pTerrainNew = new CTerrainMesh; pTerrainNew->Create(dwWidth,dwDepth,m_strDefaultTerrainTexName,false,false); if( pTerrainNew == NULL ) return; CTerrainMesh * pWaterNew = new CTerrainMesh; pWaterNew->Create(dwWidth,dwDepth,m_strDefaultWaterTexName,true,false); pTerrainNew->SetWater(pWaterNew); pTerrainNew->m_strMapName = strMapName; Ast(newVertexCnt == pTerrainNew->GetVertexCount()); int nNewVertexIndex = 0, nOldVertexIndex = 0; DWORD dwNewGridIndex = 0, dwOldGridIndex = 0; ////////////////////////////////////////////////////////////////////////// ///顶点信息 uint8 uReSizeMapType = terrain->GetResizeMapType(); for ( DWORD n = 0; n < newVertexCnt; ++n ) { DWORD dwVertexIndexOld = 0, oColor = VERTEX_COLOR, sColor = VERTEX_COLOR; float fPositionY = 0.0f; CVector3f vNormal(0.0, 1.0f, 0.0f); short sLogicHeight = 0; if ( terrain->IsOverlappingByVertexIndex(dwWidth, dwDepth, n, dwVertexIndexOld, uReSizeMapType) ) { SVertex &VertexOld = terrain->GetVertex(dwVertexIndexOld); SVertex &VertexNew = pTerrainNew->GetVertex(n); VertexNew.oColor = VertexOld.oColor; VertexNew.sColor = VertexOld.sColor; VertexNew.vPosition.y = VertexOld.vPosition.y; VertexNew.vNormal = VertexOld.vNormal; VertexNew.fLogicHeight = short(VertexOld.fLogicHeight); pWaterNew->GetVertex(n).vPosition.y = VertexNew.vPosition.y + WATER_LAYER_BASE; } } ////////////////////////////////////////////////////////////////////////// // grids string strName = ""; SGrid * pGridOld = NULL; float delta = 0.001f; float U[2][4] = { {delta, 0.5f, 0.5f, delta}, {0.5f, 1.0f - delta, 1.0f - delta, 0.5f} }; float V[2][4] = { {1.0f - delta, 1.0f - delta, 0.5f, 0.5f}, {0.5f, 0.5f, delta, delta} }; map<int, int>::iterator iiter; bool bOldMapStart = true; int nOldSatrtGridInNewIndex = 0; for (int i = 0; i < newGridCnt; ++i ) { int x = i % dwMapWidth; int z = i / dwMapWidth; int nX = x % 2; int nZ = z % 2; DWORD dwGridIndexOld = 0; int nOldDivideRegionIndex = 0, nNewDivideRegionIndex = 0; SGrid * pGridNew = &pTerrainNew->GetGrid(i); pGridNew->dwGridIndex = i; if ( terrain->IsOverlappingByGridIndex(dwWidth, dwDepth, i, dwGridIndexOld, uReSizeMapType) ) { if( bOldMapStart ) { nOldSatrtGridInNewIndex = i; bOldMapStart = false; } pGridOld = &terrain->GetGrid(dwGridIndexOld); nOldDivideRegionIndex = pGridOld->m_nDivideRegionIndex; pGridNew->bGridHide = pGridOld->bGridHide; pGridNew->nBlockType = pGridOld->nBlockType; pGridNew->nodeInfo.strTextureNames[0] = pGridOld->nodeInfo.strTextureNames[0]; pGridNew->nodeInfo.strTextureNames[1] = pGridOld->nodeInfo.strTextureNames[1]; pGridNew->bCliffLayerOne = pGridOld->bCliffLayerOne; pGridNew->nMaterialIndex = pGridOld->nMaterialIndex; pGridNew->bMatNotEffectByTileSets = pGridOld->bMatNotEffectByTileSets;///强行设置该格子不受图素包设置影响,默认为受影响 for (int m = 0; m < 4; ++m) { pGridNew->uv[0][m] = pGridOld->uv[0][m]; pGridNew->uv[1][m] = pGridOld->uv[1][m]; pGridNew->subGridTypes[m] = pGridOld->subGridTypes[m]; } pGridNew->vCenter.y = pGridOld->vCenter.y; pGridNew->vecCenterObjects = pGridOld->vecCenterObjects; pGridNew->bEffectByVertexColor = pGridOld->bEffectByVertexColor; this->mapRevertSplitMapGridIndex[dwGridIndexOld] = i; this->m_OldMapRegionIndexMap[nOldDivideRegionIndex] = pGridNew->m_nDivideRegionIndex; pGridNew->bSide = pGridOld->bSide; for ( vector< CTObjectPtr >::iterator iter = pGridNew->vecCenterObjects.begin(); iter != pGridNew->vecCenterObjects.end(); ++iter) { CTObjectPtr p = (*iter); CEditModelGroup *pModelGroup = p->GetModelGroup(); CMapEditObject *pMapEditObject = NULL; pMapEditObject = pModelGroup->GetSelfPresentation(0); int nOldModelCenterGridIndex = pMapEditObject->sModelSavePro.nCenterGridIndex; iiter = this->mapRevertSplitMapGridIndex.find(nOldModelCenterGridIndex); if( iiter != this->mapRevertSplitMapGridIndex.end() ) pMapEditObject->sModelSavePro.nCenterGridIndex = iiter->second; } } else { pGridNew->nodeInfo.strTextureNames[0] = m_strDefaultTerrainTexName; pGridNew->nodeInfo.strTextureNames[1] = m_strDefaultTerrainTexName; for (int m = 0; m < 4; ++m) { pGridNew->uv[0][m].x = U[nX][m]; pGridNew->uv[0][m].y = V[nZ][m]; } } } vector<int> vecGridIndicesRiver = this->CreateRiverInfo(pWaterNew); CMapEditApp::GetInst()->SetTerrainMesh(pTerrainNew); pTerrainNew->InitTerrain((CEditTerrainMgr*)CMapEditApp::GetInst()->GetDataScene()->GetTerrainMgr()); size_t size = vecGridIndicesRiver.size(); for (size_t i = 0; i < size; ++i ) { pWaterNew->AdjustWaterMeshVisibility(vecGridIndicesRiver[i],true); } this->ChangeRegionLightInfo(); }
//Note: target_guid used only in CHAT_MSG_WHISPER_INFORM mode (in this case channelName ignored) void ChatHandler::FillMessageData(WorldPacket* data, WorldSession* session, uint8 type, uint32 language, const char *channelName, uint64 target_guid, const char *message, Unit* speaker, const char* addonPrefix /*= NULL*/) { uint32 messageLength = (message ? strlen(message) : 0) + 1; data->Initialize(SMSG_MESSAGECHAT, 100); // guess size *data << uint8(type); if ((type != CHAT_MSG_CHANNEL && type != CHAT_MSG_WHISPER) || language == LANG_ADDON) *data << uint32(language); else *data << uint32(LANG_UNIVERSAL); switch (type) { case CHAT_MSG_SAY: case CHAT_MSG_PARTY: case CHAT_MSG_PARTY_LEADER: case CHAT_MSG_RAID: case CHAT_MSG_GUILD: case CHAT_MSG_OFFICER: case CHAT_MSG_YELL: case CHAT_MSG_WHISPER: case CHAT_MSG_CHANNEL: case CHAT_MSG_RAID_LEADER: case CHAT_MSG_RAID_WARNING: case CHAT_MSG_BG_SYSTEM_NEUTRAL: case CHAT_MSG_BG_SYSTEM_ALLIANCE: case CHAT_MSG_BG_SYSTEM_HORDE: case CHAT_MSG_INSTANCE_CHAT: case CHAT_MSG_INSTANCE_CHAT_LEADER: target_guid = session ? session->GetPlayer()->GetGUID() : 0; break; case CHAT_MSG_MONSTER_SAY: case CHAT_MSG_MONSTER_PARTY: case CHAT_MSG_MONSTER_YELL: case CHAT_MSG_MONSTER_WHISPER: case CHAT_MSG_MONSTER_EMOTE: case CHAT_MSG_RAID_BOSS_EMOTE: case CHAT_MSG_RAID_BOSS_WHISPER: case CHAT_MSG_BATTLENET: case CHAT_MSG_QUEST_BOSS_EMOTE: { *data << uint64(speaker->GetGUID()); *data << uint32(0); // 2.1.0 *data << uint32(strlen(speaker->GetName().c_str()) + 1); *data << speaker->GetName(); uint64 listener_guid = 0; *data << uint64(listener_guid); if (listener_guid && !IS_PLAYER_GUID(listener_guid)) { *data << uint32(1); // string listener_name_length *data << uint8(0); // string listener_name } *data << uint32(messageLength); *data << message; *data << uint16(0); if (type == CHAT_MSG_RAID_BOSS_WHISPER || type == CHAT_MSG_RAID_BOSS_EMOTE || CHAT_MSG_QUEST_BOSS_EMOTE) { *data << float(0.0f); // Added in 4.2.0, unk *data << uint8(0); // Added in 4.2.0, unk } return; } default: if (type != CHAT_MSG_WHISPER_INFORM && type != CHAT_MSG_IGNORED && type != CHAT_MSG_DND && type != CHAT_MSG_AFK) target_guid = 0; // only for CHAT_MSG_WHISPER_INFORM used original value target_guid break; } *data << uint64(target_guid); // there 0 for BG messages *data << uint32(0); // can be chat msg group or something if (type == CHAT_MSG_CHANNEL) { ASSERT(channelName); *data << channelName; *data << uint64(target_guid); } else if (type == uint8(CHAT_MSG_ADDON)) { ASSERT(addonPrefix); *data << addonPrefix; } else *data << uint64(target_guid); switch (type) { case CHAT_MSG_PARTY: case CHAT_MSG_PARTY_LEADER: case CHAT_MSG_RAID: case CHAT_MSG_RAID_LEADER: case CHAT_MSG_RAID_WARNING: *data << uint64(0); break; default: break; } *data << uint32(messageLength); *data << message; if (session != 0 && type != CHAT_MSG_WHISPER_INFORM && type != CHAT_MSG_DND && type != CHAT_MSG_AFK) *data << uint16(session->GetPlayer()->GetChatTag()); else *data << uint16(0); }
void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacket* data) { uint32 mask = player->GetGroupUpdateFlag(); if (mask == GROUP_UPDATE_FLAG_NONE) return; if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) // if update power type, update current/max power also mask |= (GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER); if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) // same for pets mask |= (GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER); data->Initialize(SMSG_PARTY_MEMBER_STATS, 80); // average value data->append(player->GetPackGUID()); *data << uint32(mask); if (mask & GROUP_UPDATE_FLAG_STATUS) { if (player) { if (player->IsPvP()) *data << uint16(MEMBER_STATUS_ONLINE | MEMBER_STATUS_PVP); else *data << uint16(MEMBER_STATUS_ONLINE); } else *data << uint16(MEMBER_STATUS_OFFLINE); } if (mask & GROUP_UPDATE_FLAG_CUR_HP) *data << uint32(player->GetHealth()); if (mask & GROUP_UPDATE_FLAG_MAX_HP) *data << uint32(player->GetMaxHealth()); Powers powerType = player->getPowerType(); if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) *data << uint8(powerType); if (mask & GROUP_UPDATE_FLAG_CUR_POWER) *data << uint16(player->GetPower(powerType)); if (mask & GROUP_UPDATE_FLAG_MAX_POWER) *data << uint16(player->GetMaxPower(powerType)); if (mask & GROUP_UPDATE_FLAG_LEVEL) *data << uint16(player->getLevel()); if (mask & GROUP_UPDATE_FLAG_ZONE) *data << uint16(player->GetZoneId()); if (mask & GROUP_UPDATE_FLAG_POSITION) *data << uint16(player->GetPositionX()) << uint16(player->GetPositionY()) << uint16(player->GetPositionZ()); if (mask & GROUP_UPDATE_FLAG_AURAS) { // if true client clears auras that are not covered by auramask // TODO: looks like now client requires all active auras to be in the beginning of the auramask // e.g. if you have holes in the aura mask the values after are ignored. *data << uint8(0); uint64 auramask = player->GetAuraUpdateMaskForRaid(); *data << uint64(auramask); *data << uint32(MAX_AURAS); // client reads (64) Bits from auramask for (uint32 i = 0; i < MAX_AURAS; ++i) { if (auramask & (uint64(1) << i)) { AuraApplication const* aurApp = player->GetVisibleAura(i); if (!aurApp) { *data << uint32(0); *data << uint16(0); continue; } *data << uint32(aurApp->GetBase()->GetId()); *data << uint16(aurApp->GetFlags()); if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT) { for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) { if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) *data << int32(eff->GetAmount()); else *data << int32(0); } } } } } Pet* pet = player->GetPet(); if (mask & GROUP_UPDATE_FLAG_PET_GUID) { if (pet) *data << uint64(pet->GetGUID()); else *data << uint64(0); } if (mask & GROUP_UPDATE_FLAG_PET_NAME) { if (pet) *data << pet->GetName(); else *data << uint8(0); } if (mask & GROUP_UPDATE_FLAG_PET_MODEL_ID) { if (pet) *data << uint16(pet->GetDisplayId()); else *data << uint16(0); } if (mask & GROUP_UPDATE_FLAG_PET_CUR_HP) { if (pet) *data << uint32(pet->GetHealth()); else *data << uint32(0); } if (mask & GROUP_UPDATE_FLAG_PET_MAX_HP) { if (pet) *data << uint32(pet->GetMaxHealth()); else *data << uint32(0); } if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) { if (pet) *data << uint8(pet->getPowerType()); else *data << uint8(0); } if (mask & GROUP_UPDATE_FLAG_PET_CUR_POWER) { if (pet) *data << uint16(pet->GetPower(pet->getPowerType())); else *data << uint16(0); } if (mask & GROUP_UPDATE_FLAG_PET_MAX_POWER) { if (pet) *data << uint16(pet->GetMaxPower(pet->getPowerType())); else *data << uint16(0); } if (mask & GROUP_UPDATE_FLAG_VEHICLE_SEAT) { if (Vehicle* veh = player->GetVehicle()) *data << uint32(veh->GetVehicleInfo()->m_seatID[player->_movementInfo.t_seat]); else *data << uint32(0); } if (mask & GROUP_UPDATE_FLAG_PET_AURAS) { if (pet) { *data << uint8(0); // if true client clears auras that are not covered by auramask uint64 auramask = pet->GetAuraUpdateMaskForRaid(); *data << uint64(auramask); *data << uint32(MAX_AURAS); // client reads (64) Bits from auramask for (uint32 i = 0; i < MAX_AURAS; ++i) { if (auramask & (uint64(1) << i)) { AuraApplication const* aurApp = pet->GetVisibleAura(i); if (!aurApp) { *data << uint32(0); *data << uint16(0); continue; } *data << uint32(aurApp->GetBase()->GetId()); *data << uint16(aurApp->GetFlags()); if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT) { for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) { if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) *data << int32(eff->GetAmount()); else *data << int32(0); } } } } } else { *data << uint8(0); *data << uint64(0); } } if (mask & GROUP_UPDATE_FLAG_PHASE) // 4.0.6 unk { *data << uint32(8); // either 0 or 8, same unk found in SMSG_PHASESHIFT *data << uint32(0); // count // for (count) *data << uint16(phaseId) } }