diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 0132e96c..58b95b4b 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -70,7 +70,7 @@ jobs: - name: Build run: | export INSTALL_PREFIX=$PWD/result - taskset -c 0-2 ./build-linux.sh . Release + ./build-linux.sh . Release - name: Package artifacts run: | diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 663625dd..64045875 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -1,4 +1,4 @@ -name: Pull Request Build +name: Pull Request Build on: workflow_dispatch: diff --git a/.github/workflows/stable.yml b/.github/workflows/stable.yml index 00b1c966..2c94203e 100644 --- a/.github/workflows/stable.yml +++ b/.github/workflows/stable.yml @@ -69,7 +69,7 @@ jobs: - name: Build run: | export INSTALL_PREFIX=$PWD/result - taskset -c 1-3 ./build-linux.sh . Release + ./build-linux.sh . Release - name: Package artifacts run: | @@ -130,12 +130,12 @@ jobs: - name: Publish stable server release uses: akkuman/gitea-release-action@v1 with: - name: ${{ steps.vars.outputs.version }} Server + name: v${{ steps.vars.outputs.version }} Server direction: upload server_url: ${{ gitea.server_url }} repository: ${{ gitea.repository }} token: ${{ gitea.token }} - tag_name: ${{ steps.vars.outputs.version }}-Dedicated-Server + tag_name: v${{ steps.vars.outputs.version }}-Dedicated-Server prerelease: false # override: true verbose: true @@ -152,12 +152,12 @@ jobs: - name: Publish stable client release uses: akkuman/gitea-release-action@v1 with: - name: ${{ steps.vars.outputs.version }} + name: v${{ steps.vars.outputs.version }} direction: upload server_url: ${{ gitea.server_url }} repository: ${{ gitea.repository }} token: ${{ gitea.token }} - tag_name: ${{ steps.vars.outputs.version }} + tag_name: v${{ steps.vars.outputs.version }} prerelease: false # override: true verbose: true @@ -187,4 +187,4 @@ jobs: for ARTIFACT_ID in $(echo "$ARTIFACTS" | jq -r '.artifacts[].id // empty'); do curl -s -X DELETE -H "$AUTH" \ "$API/repos/$REPO/actions/artifacts/$ARTIFACT_ID" - done \ No newline at end of file + done diff --git a/.gitignore b/.gitignore index 4830ca69..0f9541ac 100644 --- a/.gitignore +++ b/.gitignore @@ -440,3 +440,6 @@ result-* # macOS .DS_Store + +# stop dlcs from prs +Minecraft.Client/Windows64Media/DLC/* \ No newline at end of file diff --git a/Minecraft.Client/ClientConnection.cpp b/Minecraft.Client/ClientConnection.cpp index 6b27244f..8fb1ceb7 100644 --- a/Minecraft.Client/ClientConnection.cpp +++ b/Minecraft.Client/ClientConnection.cpp @@ -1655,7 +1655,7 @@ void ClientConnection::handleChat(shared_ptr packet) message = packet->m_stringArgs[0]; message = app.EscapeHTMLString(message); //do this to enforce escaped string - message = app.FormatChatMessage(message); //this needs to be last cause it converts colors to html colors that would have been escaped + message = app.FormatColoredString(message); //this needs to be last cause it converts colors to html colors that would have been escaped } else { message = L""; } @@ -2823,7 +2823,7 @@ void ClientConnection::handleTextureAndGeometry(shared_ptrdwSkinID); - send(std::make_shared(packet->textureName, pbData, dwBytes, app.GetAdditionalSkinBoxes(packet->dwSkinID), uiAnimOverrideBitmask)); + send(std::make_shared(packet->textureName, pbData, dwBytes, app.GetAdditionalSkinBoxes(packet->dwSkinID), app.GetSkinOffsets(packet->dwSkinID), uiAnimOverrideBitmask)); } } } @@ -2840,6 +2840,11 @@ void ClientConnection::handleTextureAndGeometry(shared_ptrdwSkinID,packet->BoxDataA,packet->dwBoxC); } + // Add the offet data + if(packet->dwOffsetC!=0) + { + app.SetSkinOffsets(packet->dwSkinID,packet->OffsetDataA,packet->dwOffsetC); + } // Add the anim override app.SetAnimOverrideBitmask(packet->dwSkinID,packet->uiAnimOverrideBitmask); @@ -4341,7 +4346,8 @@ void ClientConnection::handleSetPlayerTeamPacket(shared_ptr void ClientConnection::handleParticleEvent(shared_ptr packet) { - ePARTICLE_TYPE particleId = (ePARTICLE_TYPE)Integer::parseInt(packet->getName()); + wstring particleName = packet->getName(); + ePARTICLE_TYPE particleId = (ePARTICLE_TYPE)Integer::parseInt(particleName); for (int i = 0; i < packet->getCount(); i++) { diff --git a/Minecraft.Client/Common/Consoles_App.cpp b/Minecraft.Client/Common/Consoles_App.cpp index 89042597..7593da75 100644 --- a/Minecraft.Client/Common/Consoles_App.cpp +++ b/Minecraft.Client/Common/Consoles_App.cpp @@ -201,6 +201,7 @@ CMinecraftApp::CMinecraftApp() InitializeCriticalSection(&csTMSPPDownloadQueue); InitializeCriticalSection(&csAdditionalModelParts); InitializeCriticalSection(&csAdditionalSkinBoxes); + InitializeCriticalSection(&csSkinOffsets); InitializeCriticalSection(&csAnimOverrideBitmask); InitializeCriticalSection(&csMemFilesLock); InitializeCriticalSection(&csMemTPDLock); @@ -245,8 +246,7 @@ CMinecraftApp::CMinecraftApp() } -void CMinecraftApp::GetSkinAdjustments(_SkinAdjustments* out, - unsigned int skinId) +void CMinecraftApp::GetSkinAdjustments(_SkinAdjustments* out, unsigned int skinId) { _SkinAdjustments adj; @@ -264,8 +264,7 @@ void CMinecraftApp::GetSkinAdjustments(_SkinAdjustments* out, *out = adj; } -void CMinecraftApp::SetSkinAdjustments(unsigned int skinId, - const _SkinAdjustments& adj) +void CMinecraftApp::SetSkinAdjustments(unsigned int skinId, const _SkinAdjustments& adj) { EnterCriticalSection(&csAdditionalSkinBoxes); @@ -7027,72 +7026,102 @@ wstring CMinecraftApp::EscapeHTMLString(const wstring& desc) return finalString; } -wstring CMinecraftApp::FormatChatMessage(const wstring& desc, bool applyStyling) -{ - static std::wregex IDS_Pattern(LR"(\{\*IDS_(\d+)\*\})"); //maybe theres a better way to do translateable IDS - static std::wstring_view colorFormatString = L""; - - wstring results = desc; - wchar_t replacements[64]; - - swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_0), 0xFFFFFFFF); - results = replaceAll(results, L"\u00A70", replacements); - - swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_1), 0xFFFFFFFF); - results = replaceAll(results, L"\u00A71", replacements); - - swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_2), 0xFFFFFFFF); - results = replaceAll(results, L"\u00A72", replacements); - - swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_3), 0xFFFFFFFF); - results = replaceAll(results, L"\u00A73", replacements); - - swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_4), 0xFFFFFFFF); - results = replaceAll(results, L"\u00A74", replacements); - - swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_5), 0xFFFFFFFF); - results = replaceAll(results, L"\u00A75", replacements); - - swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_6), 0xFFFFFFFF); - results = replaceAll(results, L"\u00A76", replacements); - - swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_7), 0xFFFFFFFF); - results = replaceAll(results, L"\u00A77", replacements); - - swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_8), 0xFFFFFFFF); - results = replaceAll(results, L"\u00A78", replacements); - - swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_9), 0xFFFFFFFF); - results = replaceAll(results, L"\u00A79", replacements); - - swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_a), 0xFFFFFFFF); - results = replaceAll(results, L"\u00A7a", replacements); - - swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_b), 0xFFFFFFFF); - results = replaceAll(results, L"\u00A7b", replacements); - - swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_c), 0xFFFFFFFF); - results = replaceAll(results, L"\u00A7c", replacements); - - swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_d), 0xFFFFFFFF); - results = replaceAll(results, L"\u00A7d", replacements); - - swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_e), 0xFFFFFFFF); - results = replaceAll(results, L"\u00A7e", replacements); - - swprintf(replacements, 64, (applyStyling ? colorFormatString.data() : L""), GetHTMLColour(eHTMLColor_f), 0xFFFFFFFF); - results = replaceAll(results, L"\u00A7f", replacements); - results = replaceAll(results, L"\u00A7r", replacements); //we only support color so reset is the same as white color - - if (applyStyling) { - std::wsmatch match; - while (std::regex_search(results, match, IDS_Pattern)) { - results = replaceAll(results, match[0], app.GetString(std::stoi(match[1].str()))); - } +eMinecraftColour GetColorFromCode(wchar_t _char) { + switch (_char) { + case L'0': return eHTMLColor_0; + case L'1': return eHTMLColor_1; + case L'2': return eHTMLColor_2; + case L'3': return eHTMLColor_3; + case L'4': return eHTMLColor_4; + case L'5': return eHTMLColor_5; + case L'6': return eHTMLColor_6; + case L'7': return eHTMLColor_7; + case L'8': return eHTMLColor_8; + case L'9': return eHTMLColor_9; + case L'a': return eHTMLColor_a; + case L'b': return eHTMLColor_b; + case L'c': return eHTMLColor_c; + case L'd': return eHTMLColor_d; + case L'e': return eHTMLColor_e; + case L'f': return eHTMLColor_f; + default: return eMinecraftColour_NOT_SET; } - +} - return results; +wstring CMinecraftApp::FormatColoredString(const wstring& string) { + static constexpr std::wstring_view colorFormatString = L""; + + wstring result; + + bool fontOpen = false; + bool italicOpen = false; + + auto CloseItalic = [&]() { + if (italicOpen) { + result += L""; + italicOpen = false; + } + }; + + auto CloseFont = [&]() { + if (fontOpen) { + result += L""; + fontOpen = false; + } + }; + + wchar_t buffer[64]; + + for (size_t i = 0; i < string.length(); ++i) { + if (string[i] == L'\u00A7' && i + 1 < string.length()) { + wchar_t code = towlower(string[i + 1]); + + if (GetColorFromCode(code) != eMinecraftColour_NOT_SET) { + bool restoreItalic = italicOpen; + + CloseItalic(); + CloseFont(); + + swprintf(buffer, _countof(buffer), colorFormatString.data(), GetHTMLColour(GetColorFromCode(code))); + + result += buffer; + fontOpen = true; + + if (restoreItalic) { + result += L""; + italicOpen = true; + } + + ++i; + continue; + } + + if (code == L'o') { + if (!italicOpen) { + result += L""; + italicOpen = true; + } + + ++i; + continue; + } + + if (code == L'r') { + CloseItalic(); + CloseFont(); + + ++i; + continue; + } + } + + result += string[i]; + } + + CloseItalic(); + CloseFont(); + + return result; } wstring CMinecraftApp::GetActionReplacement(int iPad, unsigned char ucAction) @@ -9751,7 +9780,14 @@ void CMinecraftApp::SetAdditionalSkinBoxes(DWORD dwSkinID, SKIN_BOX *SkinBoxA, D { EntityRenderDispatcher *dispatcher = EntityRenderDispatcher::instance; EntityRenderer *renderer = dispatcher ? dispatcher->getRenderer(eTYPE_PLAYER) : nullptr; - Model *pModel = renderer ? renderer->getModel() : nullptr; + unsigned int m_uiAnimOverrideBitmask = GetAnimOverrideBitmask(dwSkinID); + Model *pModel; + if (m_uiAnimOverrideBitmask & (1 << HumanoidModel::eAnim_SlimModel)) + pModel = renderer ? renderer->getModel(2) : nullptr; + else if (m_uiAnimOverrideBitmask & (1 << HumanoidModel::eAnim_WideModel)) + pModel = renderer ? renderer->getModel(1) : nullptr; + else + pModel = renderer ? renderer->getModel(0) : nullptr; vector *pvModelPart = new vector; vector *pvSkinBoxes = new vector; @@ -9784,7 +9820,14 @@ vector * CMinecraftApp::SetAdditionalSkinBoxes(DWORD dwSkinID, vect { EntityRenderDispatcher *dispatcher = EntityRenderDispatcher::instance; EntityRenderer *renderer = dispatcher ? dispatcher->getRenderer(eTYPE_PLAYER) : nullptr; - Model *pModel = renderer ? renderer->getModel() : nullptr; + unsigned int m_uiAnimOverrideBitmask = GetAnimOverrideBitmask(dwSkinID); + Model *pModel; + if (m_uiAnimOverrideBitmask & (1 << HumanoidModel::eAnim_SlimModel)) + pModel = renderer ? renderer->getModel(2) : nullptr; + else if (m_uiAnimOverrideBitmask & (1 << HumanoidModel::eAnim_WideModel)) + pModel = renderer ? renderer->getModel(1) : nullptr; + else + pModel = renderer ? renderer->getModel(0) : nullptr; vector *pvModelPart = new vector; EnterCriticalSection( &csAdditionalModelParts ); @@ -9809,6 +9852,44 @@ vector * CMinecraftApp::SetAdditionalSkinBoxes(DWORD dwSkinID, vect return pvModelPart; } +void CMinecraftApp::SetSkinOffsets(DWORD dwSkinID, SKIN_OFFSET *SkinOffsetA, DWORD dwSkinOffsetC) +{ + vector *pvSkinOffset = new vector; + + EnterCriticalSection( &csSkinOffsets ); + + app.DebugPrintf("*** SetSkinOffsets - Adding skin offsets for skin %d from array of Skin Offsets\n",dwSkinID&0x0FFFFFFF); + + for(unsigned int i=0;ipush_back(&SkinOffsetA[i]); + } + + + m_SkinOffsets.insert( std::pair *>(dwSkinID, pvSkinOffset) ); + + LeaveCriticalSection( &csSkinOffsets ); + +} + +vector * CMinecraftApp::SetSkinOffsets(DWORD dwSkinID, vector *pvSkinOffsetA) +{ + vector *pvSkinOffset = new vector; + + EnterCriticalSection( &csSkinOffsets ); + app.DebugPrintf("*** SetSkinOffsets - Inserting skin offsets for skin %d from array of Skin Offsets\n",dwSkinID&0x0FFFFFFF); + + for( auto& it : *pvSkinOffsetA ) + { + pvSkinOffset->push_back(it); + } + + m_SkinOffsets.emplace(dwSkinID, pvSkinOffsetA); + + LeaveCriticalSection( &csSkinOffsets ); + return pvSkinOffset; +} + vector *CMinecraftApp::GetAdditionalModelParts(DWORD dwSkinID) { @@ -9844,6 +9925,23 @@ vector *CMinecraftApp::GetAdditionalSkinBoxes(DWORD dwSkinID) return pvSkinBoxes; } +vector *CMinecraftApp::GetSkinOffsets(DWORD dwSkinID) +{ + EnterCriticalSection( &csSkinOffsets ); + vector *pvSkinOffsets=nullptr; + if(m_SkinOffsets.size()>0) + { + auto it = m_SkinOffsets.find(dwSkinID); + if(it!=m_SkinOffsets.end()) + { + pvSkinOffsets = (*it).second; + } + } + + LeaveCriticalSection( &csSkinOffsets ); + return pvSkinOffsets; +} + unsigned int CMinecraftApp::GetAnimOverrideBitmask(DWORD dwSkinID) { EnterCriticalSection( &csAnimOverrideBitmask ); diff --git a/Minecraft.Client/Common/Consoles_App.h b/Minecraft.Client/Common/Consoles_App.h index 52f4c043..7359d700 100644 --- a/Minecraft.Client/Common/Consoles_App.h +++ b/Minecraft.Client/Common/Consoles_App.h @@ -21,6 +21,7 @@ using namespace std; #include "./GameRules/ConsoleGameRulesConstants.h" #include "./GameRules/GameRuleManager.h" #include "../SkinBox.h" +#include "../SkinOffset.h" #include "../ArchiveFile.h" #include "lce_filesystem/FolderFile.h" @@ -574,7 +575,7 @@ public: int GetHTMLFontSize(EHTMLFontSize size); wstring FormatHTMLString(int iPad, const wstring& desc, int shadowColour = 0xFFFFFFFF, bool override = false); wstring EscapeHTMLString(const wstring &desc); - wstring FormatChatMessage(const wstring& desc, bool applyStyling = true); + wstring FormatColoredString(const wstring& desc); wstring GetActionReplacement(int iPad, unsigned char ucAction); wstring GetVKReplacement(unsigned int uiVKey, bool override = false); wstring GetIconReplacement(unsigned int uiIcon); @@ -848,6 +849,7 @@ private: CRITICAL_SECTION csTMSPPDownloadQueue; CRITICAL_SECTION csAdditionalModelParts; CRITICAL_SECTION csAdditionalSkinBoxes; + CRITICAL_SECTION csSkinOffsets; CRITICAL_SECTION csAnimOverrideBitmask; bool m_bCorruptSaveDeleted; wstring m_currentSaveFolderName; // 4J Added: for hardcore world deletion on Win64 @@ -870,6 +872,9 @@ public: vector * SetAdditionalSkinBoxes(DWORD dwSkinID, vector *pvSkinBoxA); vector *GetAdditionalModelParts(DWORD dwSkinID); vector *GetAdditionalSkinBoxes(DWORD dwSkinID); + void SetSkinOffsets(DWORD dwSkinID, SKIN_OFFSET *SkinOffsetA, DWORD dwSkinOffsetC); + vector * SetSkinOffsets(DWORD dwSkinID, vector *pvSkinOffsetA); + vector *GetSkinOffsets(DWORD dwSkinID); void SetAnimOverrideBitmask(DWORD dwSkinID,unsigned int uiAnimOverrideBitmask); unsigned int GetAnimOverrideBitmask(DWORD dwSkinID); @@ -900,6 +905,7 @@ private: // vector of additional skin model parts, indexed by the skin texture id unordered_map *> m_AdditionalModelParts; unordered_map *> m_AdditionalSkinBoxes; + unordered_map *> m_SkinOffsets; unordered_map m_AnimOverrides; diff --git a/Minecraft.Client/Common/DLC/DLCManager.cpp b/Minecraft.Client/Common/DLC/DLCManager.cpp index 219fbe20..2e307423 100644 --- a/Minecraft.Client/Common/DLC/DLCManager.cpp +++ b/Minecraft.Client/Common/DLC/DLCManager.cpp @@ -109,6 +109,7 @@ const WCHAR *DLCManager::wchTypeNamesA[]= L"ENCHANTTEXTFOCUSCOLOUR", L"DATAPATH", L"PACKVERSION", + L"OFFSET", }; DLCManager::DLCManager() diff --git a/Minecraft.Client/Common/DLC/DLCManager.h b/Minecraft.Client/Common/DLC/DLCManager.h index dc3d1a02..8a60a3c7 100644 --- a/Minecraft.Client/Common/DLC/DLCManager.h +++ b/Minecraft.Client/Common/DLC/DLCManager.h @@ -45,6 +45,7 @@ public: e_DLCParamType_EnchantmentTextFocusColour, e_DLCParamType_DataPath, e_DLCParamType_PackVersion, + e_DLCParamType_Offset, e_DLCParamType_Max, diff --git a/Minecraft.Client/Common/DLC/DLCSkinFile.cpp b/Minecraft.Client/Common/DLC/DLCSkinFile.cpp index fb5282af..e309da78 100644 --- a/Minecraft.Client/Common/DLC/DLCSkinFile.cpp +++ b/Minecraft.Client/Common/DLC/DLCSkinFile.cpp @@ -120,9 +120,9 @@ void DLCSkinFile::addParameter(DLCManager::EDLCParameterType type, const wstring #ifdef __PS3__ // 4J Stu - The Xbox version used swscanf_s which isn't available in GCC. - swscanf(value.c_str(), L"%10ls%f%f%f%f%f%f%f%f", wchBodyPart, + swscanf(value.c_str(), L"%10ls%f%f%f%f%f%f%f%f%f%f%f", wchBodyPart, #else - swscanf_s(value.c_str(), L"%9ls%f%f%f%f%f%f%f%f", wchBodyPart,10, + swscanf_s(value.c_str(), L"%9ls%f%f%f%f%f%f%f%f%f%f%f", wchBodyPart,10, #endif &pSkinBox->fX, &pSkinBox->fY, @@ -131,7 +131,10 @@ void DLCSkinFile::addParameter(DLCManager::EDLCParameterType type, const wstring &pSkinBox->fH, &pSkinBox->fD, &pSkinBox->fU, - &pSkinBox->fV); + &pSkinBox->fV, + &pSkinBox->fA, + &pSkinBox->fM, + &pSkinBox->fS); if(wcscmp(wchBodyPart,L"HEAD")==0) { @@ -157,11 +160,216 @@ void DLCSkinFile::addParameter(DLCManager::EDLCParameterType type, const wstring { pSkinBox->ePart=eBodyPart_Leg1; } + else if(wcscmp(wchBodyPart,L"HEADWEAR")==0) + { + pSkinBox->ePart=eBodyPart_Headwear; + } + else if(wcscmp(wchBodyPart,L"JACKET")==0) + { + pSkinBox->ePart=eBodyPart_Jacket; + } + else if(wcscmp(wchBodyPart,L"SLEEVE0")==0) + { + pSkinBox->ePart=eBodyPart_Sleeve0; + } + else if(wcscmp(wchBodyPart,L"SLEEVE1")==0) + { + pSkinBox->ePart=eBodyPart_Sleeve1; + } + else if(wcscmp(wchBodyPart,L"PANTS0")==0) + { + pSkinBox->ePart=eBodyPart_Pants0; + } + else if(wcscmp(wchBodyPart,L"PANTS1")==0) + { + pSkinBox->ePart=eBodyPart_Pants1; + } + else if(wcscmp(wchBodyPart,L"WAIST")==0) + { + pSkinBox->ePart=eBodyPart_Waist; + } + else if(wcscmp(wchBodyPart,L"LEGGING0")==0) + { + pSkinBox->ePart=eBodyPart_Legging0; + } + else if(wcscmp(wchBodyPart,L"LEGGING1")==0) + { + pSkinBox->ePart=eBodyPart_Legging1; + } + else if(wcscmp(wchBodyPart,L"SOCK0")==0) + { + pSkinBox->ePart=eBodyPart_Sock0; + } + else if(wcscmp(wchBodyPart,L"SOCK1")==0) + { + pSkinBox->ePart=eBodyPart_Sock1; + } + else if(wcscmp(wchBodyPart,L"BOOT0")==0) + { + pSkinBox->ePart=eBodyPart_Boot0; + } + else if(wcscmp(wchBodyPart,L"BOOT1")==0) + { + pSkinBox->ePart=eBodyPart_Boot1; + } + else if(wcscmp(wchBodyPart,L"ARMARMOR0")==0) + { + pSkinBox->ePart=eBodyPart_ArmArmor0; + } + else if(wcscmp(wchBodyPart,L"ARMARMOR1")==0) + { + pSkinBox->ePart=eBodyPart_ArmArmor1; + } + else if(wcscmp(wchBodyPart,L"BODYARMOR")==0) + { + pSkinBox->ePart=eBodyPart_BodyArmor; + } + else if(wcscmp(wchBodyPart,L"BELT")==0) + { + pSkinBox->ePart=eBodyPart_Belt; + } // add this to the skin's vector of parts m_AdditionalBoxes.push_back(pSkinBox); } break; + case DLCManager::e_DLCParamType_Offset: + { + WCHAR wchBodyPart[10]; + wchar_t wchDirection[2]; + SKIN_OFFSET *pSkinOffset = new SKIN_OFFSET; + ZeroMemory(pSkinOffset,sizeof(SKIN_OFFSET)); + +#ifdef __PS3__ + // 4J Stu - The Xbox version used swscanf_s which isn't available in GCC. + swscanf(value.c_str(), L"%10ls%2ls%f", wchBodyPart, +#else + swscanf_s(value.c_str(), L"%9ls%2ls%f", wchBodyPart,10, wchDirection,2, +#endif + &pSkinOffset->fO); + + if(wcscmp(wchDirection,L"X")==0) + { + pSkinOffset->fD=eOffsetDirection_X; + } + else if (wcscmp(wchDirection,L"Y")==0) + { + pSkinOffset->fD=eOffsetDirection_Y; + } + else if(wcscmp(wchDirection,L"Z")==0) + { + pSkinOffset->fD=eOffsetDirection_Z; + } + + if(wcscmp(wchBodyPart,L"HEAD")==0) + { + pSkinOffset->ePart=eBodyOffset_Head; + } + else if(wcscmp(wchBodyPart,L"BODY")==0) + { + pSkinOffset->ePart=eBodyOffset_Body; + } + else if(wcscmp(wchBodyPart,L"ARM0")==0) + { + pSkinOffset->ePart=eBodyOffset_Arm0; + } + else if(wcscmp(wchBodyPart,L"ARM1")==0) + { + pSkinOffset->ePart=eBodyOffset_Arm1; + } + else if(wcscmp(wchBodyPart,L"LEG0")==0) + { + pSkinOffset->ePart=eBodyOffset_Leg0; + } + else if(wcscmp(wchBodyPart,L"LEG1")==0) + { + pSkinOffset->ePart=eBodyOffset_Leg1; + } + else if(wcscmp(wchBodyPart,L"HEADWEAR")==0) + { + pSkinOffset->ePart=eBodyOffset_Headwear; + } + else if(wcscmp(wchBodyPart,L"JACKET")==0) + { + pSkinOffset->ePart=eBodyOffset_Jacket; + } + else if(wcscmp(wchBodyPart,L"SLEEVE0")==0) + { + pSkinOffset->ePart=eBodyOffset_Sleeve0; + } + else if(wcscmp(wchBodyPart,L"SLEEVE1")==0) + { + pSkinOffset->ePart=eBodyOffset_Sleeve1; + } + else if(wcscmp(wchBodyPart,L"PANTS0")==0) + { + pSkinOffset->ePart=eBodyOffset_Pants0; + } + else if(wcscmp(wchBodyPart,L"PANTS1")==0) + { + pSkinOffset->ePart=eBodyOffset_Pants1; + } + else if(wcscmp(wchBodyPart,L"HELMET")==0) + { + pSkinOffset->ePart=eBodyOffset_Helmet; + } + else if(wcscmp(wchBodyPart,L"WAIST")==0) + { + pSkinOffset->ePart=eBodyOffset_Waist; + } + else if(wcscmp(wchBodyPart,L"LEGGING0")==0) + { + pSkinOffset->ePart=eBodyOffset_Legging0; + } + else if(wcscmp(wchBodyPart,L"LEGGING1")==0) + { + pSkinOffset->ePart=eBodyOffset_Legging1; + } + else if(wcscmp(wchBodyPart,L"SOCK0")==0) + { + pSkinOffset->ePart=eBodyOffset_Sock0; + } + else if(wcscmp(wchBodyPart,L"SOCK1")==0) + { + pSkinOffset->ePart=eBodyOffset_Sock1; + } + else if(wcscmp(wchBodyPart,L"BOOT0")==0) + { + pSkinOffset->ePart=eBodyOffset_Boot0; + } + else if(wcscmp(wchBodyPart,L"BOOT1")==0) + { + pSkinOffset->ePart=eBodyOffset_Boot1; + } + else if(wcscmp(wchBodyPart,L"ARMARMOR1")==0) + { + pSkinOffset->ePart=eBodyOffset_ArmArmor1; + } + else if(wcscmp(wchBodyPart,L"ARMARMOR0")==0) + { + pSkinOffset->ePart=eBodyOffset_ArmArmor0; + } + else if(wcscmp(wchBodyPart,L"BODYARMOR")==0) + { + pSkinOffset->ePart=eBodyOffset_BodyArmor; + } + else if(wcscmp(wchBodyPart,L"BELT")==0) + { + pSkinOffset->ePart=eBodyOffset_Belt; + } + else if(wcscmp(wchBodyPart,L"TOOL0")==0) + { + pSkinOffset->ePart=eBodyOffset_Tool0; + } + else if(wcscmp(wchBodyPart,L"TOOL1")==0) + { + pSkinOffset->ePart=eBodyOffset_Tool1; + } + + // add this to the skin's vector of offsets + m_Offsets.push_back(pSkinOffset); + } + break; case DLCManager::e_DLCParamType_Anim: #ifdef __PS3__ // 4J Stu - The Xbox version used swscanf_s which isn't available in GCC. @@ -189,6 +397,15 @@ vector *DLCSkinFile::getAdditionalBoxes() return &m_AdditionalBoxes; } +int DLCSkinFile::getOffsetsCount() +{ + return static_cast(m_Offsets.size()); +} +vector *DLCSkinFile::getOffsets() +{ + return &m_Offsets; +} + wstring DLCSkinFile::getParameterAsString(DLCManager::EDLCParameterType type) { switch(type) diff --git a/Minecraft.Client/Common/DLC/DLCSkinFile.h b/Minecraft.Client/Common/DLC/DLCSkinFile.h index eb9f70be..810e883f 100644 --- a/Minecraft.Client/Common/DLC/DLCSkinFile.h +++ b/Minecraft.Client/Common/DLC/DLCSkinFile.h @@ -13,6 +13,7 @@ private: unsigned int m_uiAnimOverrideBitmask; bool m_bIsFree; vector m_AdditionalBoxes; + vector m_Offsets; _SkinAdjustments m_skinAdjustments; public: @@ -26,6 +27,8 @@ public: bool getParameterAsBool(DLCManager::EDLCParameterType type) override; vector *getAdditionalBoxes(); int getAdditionalBoxesCount(); + vector *getOffsets(); + int getOffsetsCount(); unsigned int getAnimOverrideBitmask() { return m_uiAnimOverrideBitmask;} bool isFree() {return m_bIsFree;} }; \ No newline at end of file diff --git a/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp b/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp index 7e8d6910..6b0d9b97 100644 --- a/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp +++ b/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp @@ -13,6 +13,9 @@ #include #endif +#include +#include + CPlatformNetworkManagerStub *g_pPlatformNetworkManager; @@ -910,14 +913,13 @@ void CPlatformNetworkManagerStub::SearchForGames() if (std::fread(&nameLen, sizeof(uint16_t), 1, file) != 1) break; if (nameLen > 256) break; - char nameBuf[257] = {}; - if (nameLen > 0) - { - if (std::fread(nameBuf, 1, nameLen, file) != nameLen) break; + wstring wName = L""; + for (int l = 0; l < nameLen; l++) { + uint16_t _char = 0; + if (std::fread(&_char, 1, 1, file) != 1) break; + wName += _char; } - wstring wName = convStringToWstring(nameBuf); - FriendSessionInfo* info = new FriendSessionInfo(); size_t nLen = wName.length(); info->displayLabel = new wchar_t[nLen + 1]; diff --git a/Minecraft.Client/Common/UI/UIControl_PlayerSkinPreview.cpp b/Minecraft.Client/Common/UI/UIControl_PlayerSkinPreview.cpp index 3081d01d..631ee84b 100644 --- a/Minecraft.Client/Common/UI/UIControl_PlayerSkinPreview.cpp +++ b/Minecraft.Client/Common/UI/UIControl_PlayerSkinPreview.cpp @@ -8,7 +8,6 @@ #include "../../ModelPart.h" #include "../../Options.h" #include "../../../Minecraft.World/net.minecraft.world.entity.player.h" -#include "Skins.h" #include "UIControl_PlayerSkinPreview.h" #include @@ -108,6 +107,7 @@ UIControl_PlayerSkinPreview::UIControl_PlayerSkinPreview() m_framesAnimatingRotation = 0; m_bAnimatingToFacing = false; m_pvAdditionalModelParts=nullptr; + m_pvSkinOffsets=nullptr; m_uiAnimOverrideBitmask=0L; } @@ -184,6 +184,7 @@ void UIControl_PlayerSkinPreview::SetTexture(const wstring &url, TEXTURE_NAME ba } m_pvAdditionalModelParts=app.GetAdditionalModelParts(app.getSkinIdFromPath(m_customTextureUrl)); + m_pvSkinOffsets=app.GetSkinOffsets(app.getSkinIdFromPath(m_customTextureUrl)); } void UIControl_PlayerSkinPreview::SetFacing(ESkinPreviewFacing facing, bool bAnimate /*= false*/) @@ -309,24 +310,8 @@ void UIControl_PlayerSkinPreview::render(EntityRenderer *renderer, double x, dou glPushMatrix(); glDisable(GL_CULL_FACE); - HumanoidModel *model = static_cast(renderer->getModel()); - Textures *textures = Minecraft::GetInstance()->textures; - int skinId = textures->loadMemTexture(m_customTextureUrl, m_backupTexture) - 37; - - if (slim[skinId] == true) - { - if (textures->getHeight(m_customTextureUrl, m_backupTexture) == 64) - model = static_cast(renderer->getNewModelSlim()); - else - model = static_cast(renderer->getModelSlim()); - } - else - { - if (textures->getHeight(m_customTextureUrl, m_backupTexture) == 64) - model = static_cast(renderer->getNewModel()); - else - model = static_cast(renderer->getModel()); - } + Textures *t = Minecraft::GetInstance()->textures; + HumanoidModel *model = static_cast(renderer->getModel(Player::GetModelTypeFromTextureId(t->loadMemTexture(m_customTextureUrl, m_backupTexture)-36)+Player::GetModelTypeFromAnimBitmask(m_uiAnimOverrideBitmask))); //getAttackAnim(mob, a); //if (armor != nullptr) armor->attackTime = model->attackTime; @@ -438,7 +423,7 @@ void UIControl_PlayerSkinPreview::render(EntityRenderer *renderer, double x, dou glEnable(GL_ALPHA_TEST); //model->prepareMobModel(mob, wp, ws, a); - model->render(nullptr, wp, ws, bob, headRot - bodyRot, headRotx, _scale, true); + model->renderUI(wp, ws, bob, headRot - bodyRot, headRotx, _scale, true, m_pvSkinOffsets); /*for (int i = 0; i < MAX_ARMOR_LAYERS; i++) { if (prepareArmor(mob, i, a)) diff --git a/Minecraft.Client/Common/UI/UIControl_PlayerSkinPreview.h b/Minecraft.Client/Common/UI/UIControl_PlayerSkinPreview.h index 93d04925..4533716f 100644 --- a/Minecraft.Client/Common/UI/UIControl_PlayerSkinPreview.h +++ b/Minecraft.Client/Common/UI/UIControl_PlayerSkinPreview.h @@ -53,6 +53,7 @@ private: ESkinPreviewAnimations m_currentAnimation; //vector *m_pvAdditionalBoxes; vector *m_pvAdditionalModelParts; + vector *m_pvSkinOffsets; public: enum ESkinPreviewFacing { diff --git a/Minecraft.Client/Common/UI/UIScene_ContainerMenu.cpp b/Minecraft.Client/Common/UI/UIScene_ContainerMenu.cpp index a74690e3..9b28a808 100644 --- a/Minecraft.Client/Common/UI/UIScene_ContainerMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_ContainerMenu.cpp @@ -19,7 +19,10 @@ UIScene_ContainerMenu::UIScene_ContainerMenu(int iPad, void *_initData, UILayer // Setup all the Iggy references we need for this scene initialiseMovie(); - m_labelChest.init(initData->container->getName()); + IggyValueSetBooleanRS(m_labelChest.getIggyValuePath(), 0, "m_bUseHtmlText", true); + + wstring title = app.EscapeHTMLString(initData->container->getName()); + m_labelChest.init(app.FormatColoredString(title)); ContainerMenu* menu = new ContainerMenu( initData->inventory, initData->container ); diff --git a/Minecraft.Client/Common/UI/UIScene_HUD.cpp b/Minecraft.Client/Common/UI/UIScene_HUD.cpp index ac159fc1..0102ea75 100644 --- a/Minecraft.Client/Common/UI/UIScene_HUD.cpp +++ b/Minecraft.Client/Common/UI/UIScene_HUD.cpp @@ -21,6 +21,28 @@ UIScene_HUD::UIScene_HUD(int iPad, void *initData, UILayer *parentLayer) : UISce SetDragonLabel( app.GetString( IDS_BOSS_ENDERDRAGON_HEALTH ) ); SetSelectedLabel(L""); + //enable colors for selected item text + { + IggyValuePath classPath; + IggyValuePathMakeNameRef(&classPath, m_rootPath, "SelectedLabel"); + + IggyValuePath labelPath; + IggyValuePathMakeNameRef(&labelPath, &classPath, "Label"); + + IggyValueSetBooleanRS(&labelPath, 0, "m_bUseHtmlText", true); + } + + //enable colors for boss bar + { + IggyValuePath classPath; + IggyValuePathMakeNameRef(&classPath, m_rootPath, "m_DragonHealthBar"); + + IggyValuePath labelPath; + IggyValuePathMakeNameRef(&labelPath, &classPath, "m_DragonHealthLabel"); + + IggyValueSetBooleanRS(&labelPath, 0, "m_bUseHtmlText", true); + } + for(unsigned int i = 0; i < CHAT_LINES_COUNT; ++i) { m_labelChatText[i].init(L""); @@ -263,6 +285,28 @@ void UIScene_HUD::handleReload() SetDragonLabel(BossMobGuiInfo::name[idx]); SetSelectedLabel(L""); + //enable colors for selected item text + { + IggyValuePath classPath; + IggyValuePathMakeNameRef(&classPath, m_rootPath, "SelectedLabel"); + + IggyValuePath labelPath; + IggyValuePathMakeNameRef(&labelPath, &classPath, "Label"); + + IggyValueSetBooleanRS(&labelPath, 0, "m_bUseHtmlText", true); + } + + //enable colors for boss bar + { + IggyValuePath classPath; + IggyValuePathMakeNameRef(&classPath, m_rootPath, "m_DragonHealthBar"); + + IggyValuePath labelPath; + IggyValuePathMakeNameRef(&labelPath, &classPath, "m_DragonHealthLabel"); + + IggyValueSetBooleanRS(&labelPath, 0, "m_bUseHtmlText", true); + } + for(unsigned int i = 0; i < CHAT_LINES_COUNT; ++i) { m_labelChatText[i].init(L""); @@ -569,11 +613,17 @@ void UIScene_HUD::SetDragonHealth(float health) void UIScene_HUD::SetDragonLabel(const wstring &label) { + wstring itemName = L""; + if (!label.empty()) { + itemName = app.EscapeHTMLString(label); + itemName = app.FormatColoredString(itemName); + } + IggyDataValue result; IggyDataValue value[1]; IggyStringUTF16 stringVal; - stringVal.string = (IggyUTF16*)label.c_str(); - stringVal.length = label.length(); + stringVal.string = (IggyUTF16*)itemName.c_str(); + stringVal.length = itemName.length(); value[0].type = IGGY_DATATYPE_string_UTF16; value[0].string16 = stringVal; IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSetDragonLabel , 1 , value ); @@ -599,11 +649,17 @@ void UIScene_HUD::SetSelectedLabel(const wstring &label) // 4J Stu - Timing here is kept the same as on Xbox360, even though we do it differently now and do the fade out in Flash rather than directly setting opacity if(!label.empty()) m_uiSelectedItemOpacityCountDown = SharedConstants::TICKS_PER_SECOND * 3; + wstring itemName = L""; + if (!label.empty()) { + itemName = app.EscapeHTMLString(label); + itemName = app.FormatColoredString(itemName); + } + IggyDataValue result; IggyDataValue value[1]; IggyStringUTF16 stringVal; - stringVal.string = (IggyUTF16*)label.c_str(); - stringVal.length = label.length(); + stringVal.string = (IggyUTF16*)itemName.c_str(); + stringVal.length = itemName.length(); value[0].type = IGGY_DATATYPE_string_UTF16; value[0].string16 = stringVal; IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSetSelectedLabel , 1 , value ); diff --git a/Minecraft.Client/Common/UI/UIScene_JoinMenu.cpp b/Minecraft.Client/Common/UI/UIScene_JoinMenu.cpp index e2daddf5..92ab7e58 100644 --- a/Minecraft.Client/Common/UI/UIScene_JoinMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_JoinMenu.cpp @@ -375,7 +375,7 @@ void UIScene_JoinMenu::updateServerDescription() { wstring testText = L"\nNothing yet..."; IggyStringUTF16 iggyStr; wstring formattedText = app.EscapeHTMLString(testText); - formattedText = app.FormatChatMessage(formattedText); + formattedText = app.FormatColoredString(formattedText); iggyStr.string = (IggyUTF16*)formattedText.c_str(); iggyStr.length = (unsigned int)formattedText.length(); diff --git a/Minecraft.Client/Common/UI/UIScene_LoadCreateJoinMenu.cpp b/Minecraft.Client/Common/UI/UIScene_LoadCreateJoinMenu.cpp index fd54b3b6..1f1d59fe 100644 --- a/Minecraft.Client/Common/UI/UIScene_LoadCreateJoinMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_LoadCreateJoinMenu.cpp @@ -4660,7 +4660,7 @@ void UIScene_LoadCreateJoinMenu::RebuildJoinGamesListVisual(bool syncFocus) m_buttonListGames.getItemCount() - 1, L"lceheadwer.png", L"lceheadwer"); - + RefreshServerListHtmlPatch(); #endif if (m_currentSessions == nullptr || m_currentSessions->empty()) @@ -4741,7 +4741,10 @@ void UIScene_LoadCreateJoinMenu::RebuildJoinGamesListVisual(bool syncFocus) } } - m_buttonListGames.addItem(sessionInfo->displayLabel, modeIconName, tpIconName); + wstring htmlLabel = app.EscapeHTMLString(sessionInfo->displayLabel); + htmlLabel = app.FormatColoredString(htmlLabel); + + m_buttonListGames.addItem(htmlLabel, modeIconName, tpIconName); if (memcmp(&selectedSessionId, &sessionInfo->sessionId, sizeof(SessionID)) == 0) @@ -4763,6 +4766,8 @@ void UIScene_LoadCreateJoinMenu::RebuildJoinGamesListVisual(bool syncFocus) } + RefreshServerListHtmlPatch(); + if(syncFocus) m_buttonListGames.updateChildFocus(m_buttonListGames.getCurrentSelection()); @@ -9124,6 +9129,21 @@ int UIScene_LoadCreateJoinMenu::AddServerKeyboardCallback(LPVOID lpParam, bool b } +void UIScene_LoadCreateJoinMenu::RefreshServerListHtmlPatch() { + S32 arrayItems = 0; + IggyValueGetArrayLengthRS(m_buttonListGames.getIggyValuePath(), 0, "m_aItems", &arrayItems); + + IggyValuePath listPath; + IggyValuePathMakeNameRef(&listPath, m_buttonListGames.getIggyValuePath(), "m_aItems"); + + for (int i = 0; i < arrayItems; i++) { + IggyValuePath listItem; + IggyValuePathMakeArrayRef(&listItem, &listPath, i); + + IggyValueSetBooleanRS(&listItem, 0, "m_bUseHtmlText", true); + } +} + void UIScene_LoadCreateJoinMenu::AppendServerToFile(const wstring& ip, const wstring& port, const wstring& name) diff --git a/Minecraft.Client/Common/UI/UIScene_LoadCreateJoinMenu.h b/Minecraft.Client/Common/UI/UIScene_LoadCreateJoinMenu.h index 28ca3e4c..54a8199f 100644 --- a/Minecraft.Client/Common/UI/UIScene_LoadCreateJoinMenu.h +++ b/Minecraft.Client/Common/UI/UIScene_LoadCreateJoinMenu.h @@ -270,6 +270,8 @@ private: void BeginAddServer(); void AppendServerToFile(const wstring& ip, const wstring& port, const wstring& name); static int AddServerKeyboardCallback(LPVOID lpParam, bool bRes); + + void RefreshServerListHtmlPatch(); #endif #if defined(__PS3__) || defined(__PSVITA__) || defined(__ORBIS__) diff --git a/Minecraft.Client/Common/UI/UIScene_SkinSelectMenu.cpp b/Minecraft.Client/Common/UI/UIScene_SkinSelectMenu.cpp index 7143f28e..6b2f762c 100644 --- a/Minecraft.Client/Common/UI/UIScene_SkinSelectMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_SkinSelectMenu.cpp @@ -25,16 +25,16 @@ const WCHAR *UIScene_SkinSelectMenu::wchDefaultNamesA[]= L"Prisoner Steve", L"Cyclist Steve", L"Boxer Steve", - L"Developer Steve", L"Alex", - L"Tuxedo Alex", - L"Boxer Alex", - L"Prisoner Alex", L"Tennis Alex", - L"Cyclist Alex", + L"Tuxedo Alex", L"Athlete Alex", L"Swedish Alex", + L"Prisoner Alex", + L"Cyclist Alex", + L"Boxer Alex", L"Developer Alex", + L"Developer Steve", }; UIScene_SkinSelectMenu::UIScene_SkinSelectMenu(int iPad, void *initData, UILayer *parentLayer) : UIScene(iPad, parentLayer) @@ -60,6 +60,7 @@ UIScene_SkinSelectMenu::UIScene_SkinSelectMenu(int iPad, void *initData, UILayer m_selectedSkinPath = L""; m_selectedCapePath = L""; m_vAdditionalSkinBoxes = nullptr; + m_vSkinOffsets = nullptr; m_bSlidingSkins = false; m_bAnimatingMove = false; @@ -654,6 +655,7 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged() m_selectedSkinPath = skinFile->getPath(); m_selectedCapePath = skinFile->getParameterAsString(DLCManager::e_DLCParamType_Cape); m_vAdditionalSkinBoxes = skinFile->getAdditionalBoxes(); + m_vSkinOffsets = skinFile->getOffsets(); skinName = skinFile->getParameterAsString( DLCManager::e_DLCParamType_DisplayName ); skinOrigin = skinFile->getParameterAsString( DLCManager::e_DLCParamType_ThemeName ); @@ -676,6 +678,7 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged() m_selectedSkinPath = L""; m_selectedCapePath = L""; m_vAdditionalSkinBoxes = nullptr; + m_vSkinOffsets = nullptr; switch(m_packIndex) { @@ -720,6 +723,7 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged() m_selectedSkinPath = skinFile->getPath(); m_selectedCapePath = skinFile->getParameterAsString(DLCManager::e_DLCParamType_Cape); m_vAdditionalSkinBoxes = skinFile->getAdditionalBoxes(); + m_vSkinOffsets = skinFile->getOffsets(); skinName = skinFile->getParameterAsString( DLCManager::e_DLCParamType_DisplayName ); skinOrigin = skinFile->getParameterAsString( DLCManager::e_DLCParamType_ThemeName ); @@ -792,6 +796,17 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged() pAdditionalModelParts = app.SetAdditionalSkinBoxes(skinFile->getSkinID(),m_vAdditionalSkinBoxes); } } + + if(m_vSkinOffsets && m_vSkinOffsets->size()!=0) + { + // add the skin Offsets to the humanoid model, but only if we've not done this already + + vector *pSkinOffsets = app.GetSkinOffsets(skinFile->getSkinID()); + if(pSkinOffsets==nullptr) + { + pSkinOffsets = app.SetSkinOffsets(skinFile->getSkinID(),m_vSkinOffsets); + } + } if(skinFile!=nullptr) { @@ -810,6 +825,7 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged() wstring otherSkinPath = L""; wstring otherCapePath = L""; vector *othervAdditionalSkinBoxes=nullptr; + vector *othervSkinOffsets=nullptr; wchar_t chars[256]; // turn off all displays @@ -864,6 +880,7 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged() otherSkinPath = skinFile->getPath(); otherCapePath = skinFile->getParameterAsString(DLCManager::e_DLCParamType_Cape); othervAdditionalSkinBoxes = skinFile->getAdditionalBoxes(); + othervSkinOffsets = skinFile->getOffsets(); backupTexture = TN_MOB_CHAR; } else @@ -871,6 +888,7 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged() otherSkinPath = L""; otherCapePath = L""; othervAdditionalSkinBoxes=nullptr; + othervSkinOffsets=nullptr; switch(m_packIndex) { case SKIN_SELECT_PACK_DEFAULT: @@ -893,7 +911,8 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged() otherSkinPath = skinFile->getPath(); otherCapePath = skinFile->getParameterAsString(DLCManager::e_DLCParamType_Cape); othervAdditionalSkinBoxes = skinFile->getAdditionalBoxes(); - backupTexture = TN_MOB_CHAR; + othervSkinOffsets = skinFile->getOffsets(); + backupTexture = TN_MOB_CHAR; } } else @@ -919,6 +938,14 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged() pAdditionalModelParts = app.SetAdditionalSkinBoxes(skinFile->getSkinID(),othervAdditionalSkinBoxes); } } + if(othervSkinOffsets && othervSkinOffsets->size()!=0) + { + vector *pSkinOffsets = app.GetSkinOffsets(skinFile->getSkinID()); + if(pSkinOffsets==nullptr) + { + pSkinOffsets = app.SetSkinOffsets(skinFile->getSkinID(),othervSkinOffsets); + } + } // 4J-PB - anim override needs set before SetTexture if(skinFile!=nullptr) { @@ -948,6 +975,7 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged() otherSkinPath = skinFile->getPath(); otherCapePath = skinFile->getParameterAsString(DLCManager::e_DLCParamType_Cape); othervAdditionalSkinBoxes = skinFile->getAdditionalBoxes(); + othervSkinOffsets = skinFile->getOffsets(); backupTexture = TN_MOB_CHAR; } else @@ -955,6 +983,7 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged() otherSkinPath = L""; otherCapePath = L""; othervAdditionalSkinBoxes=nullptr; + othervSkinOffsets=nullptr; switch(m_packIndex) { case SKIN_SELECT_PACK_DEFAULT: @@ -977,7 +1006,8 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged() otherSkinPath = skinFile->getPath(); otherCapePath = skinFile->getParameterAsString(DLCManager::e_DLCParamType_Cape); othervAdditionalSkinBoxes = skinFile->getAdditionalBoxes(); - backupTexture = TN_MOB_CHAR; + othervSkinOffsets = skinFile->getOffsets(); + backupTexture = TN_MOB_CHAR; } } else @@ -1003,6 +1033,14 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged() pAdditionalModelParts = app.SetAdditionalSkinBoxes(skinFile->getSkinID(),othervAdditionalSkinBoxes); } } + if(othervSkinOffsets && othervSkinOffsets->size()!=0) + { + vector *pSkinOffsets = app.GetSkinOffsets(skinFile->getSkinID()); + if(pSkinOffsets==nullptr) + { + pSkinOffsets = app.SetSkinOffsets(skinFile->getSkinID(),othervSkinOffsets); + } + } // 4J-PB - anim override needs set before SetTexture if(skinFile) { @@ -1086,34 +1124,34 @@ TEXTURE_NAME UIScene_SkinSelectMenu::getTextureId(int skinIndex) texture = TN_MOB_CHAR7; break; case eDefaultSkins_Skin8: - texture = TN_MOB_CHAR8; + texture = TN_MOB_ALEX; break; case eDefaultSkins_Skin9: - texture = TN_MOB_CHAR9; + texture = TN_MOB_ALEX1; break; case eDefaultSkins_Skin10: - texture = TN_MOB_CHAR10; + texture = TN_MOB_ALEX2; break; case eDefaultSkins_Skin11: - texture = TN_MOB_CHAR11; + texture = TN_MOB_ALEX3; break; case eDefaultSkins_Skin12: - texture = TN_MOB_CHAR12; + texture = TN_MOB_ALEX4; break; case eDefaultSkins_Skin13: - texture = TN_MOB_CHAR13; + texture = TN_MOB_ALEX5; break; case eDefaultSkins_Skin14: - texture = TN_MOB_CHAR14; + texture = TN_MOB_ALEX6; break; case eDefaultSkins_Skin15: - texture = TN_MOB_CHAR15; + texture = TN_MOB_ALEX7; break; case eDefaultSkins_Skin16: - texture = TN_MOB_CHAR16; + texture = TN_MOB_DEVALEX; break; case eDefaultSkins_Skin17: - texture = TN_MOB_CHAR17; + texture = TN_MOB_DEVSTEVE; break; }; diff --git a/Minecraft.Client/Common/UI/UIScene_SkinSelectMenu.h b/Minecraft.Client/Common/UI/UIScene_SkinSelectMenu.h index b854eefe..79f33e6c 100644 --- a/Minecraft.Client/Common/UI/UIScene_SkinSelectMenu.h +++ b/Minecraft.Client/Common/UI/UIScene_SkinSelectMenu.h @@ -90,6 +90,7 @@ private: DWORD m_originalSkinId; wstring m_currentSkinPath, m_selectedSkinPath, m_selectedCapePath; vector *m_vAdditionalSkinBoxes; + vector *m_vSkinOffsets; bool m_bSlidingSkins, m_bAnimatingMove; ESkinSelectNavigation m_currentNavigation; diff --git a/Minecraft.Client/Common/res/1_2_2/mob/char17.png b/Minecraft.Client/Common/res/1_2_2/mob/DevAlex.png similarity index 100% rename from Minecraft.Client/Common/res/1_2_2/mob/char17.png rename to Minecraft.Client/Common/res/1_2_2/mob/DevAlex.png diff --git a/Minecraft.Client/Common/res/1_2_2/mob/char8.png b/Minecraft.Client/Common/res/1_2_2/mob/DevSteve.png similarity index 100% rename from Minecraft.Client/Common/res/1_2_2/mob/char8.png rename to Minecraft.Client/Common/res/1_2_2/mob/DevSteve.png diff --git a/Minecraft.Client/Common/res/1_2_2/mob/alex.png b/Minecraft.Client/Common/res/1_2_2/mob/alex.png new file mode 100644 index 00000000..b643fe2d Binary files /dev/null and b/Minecraft.Client/Common/res/1_2_2/mob/alex.png differ diff --git a/Minecraft.Client/Common/res/1_2_2/mob/char13.png b/Minecraft.Client/Common/res/1_2_2/mob/alex1.png similarity index 100% rename from Minecraft.Client/Common/res/1_2_2/mob/char13.png rename to Minecraft.Client/Common/res/1_2_2/mob/alex1.png diff --git a/Minecraft.Client/Common/res/1_2_2/mob/char10.png b/Minecraft.Client/Common/res/1_2_2/mob/alex2.png similarity index 100% rename from Minecraft.Client/Common/res/1_2_2/mob/char10.png rename to Minecraft.Client/Common/res/1_2_2/mob/alex2.png diff --git a/Minecraft.Client/Common/res/1_2_2/mob/char15.png b/Minecraft.Client/Common/res/1_2_2/mob/alex3.png similarity index 100% rename from Minecraft.Client/Common/res/1_2_2/mob/char15.png rename to Minecraft.Client/Common/res/1_2_2/mob/alex3.png diff --git a/Minecraft.Client/Common/res/1_2_2/mob/char16.png b/Minecraft.Client/Common/res/1_2_2/mob/alex4.png similarity index 100% rename from Minecraft.Client/Common/res/1_2_2/mob/char16.png rename to Minecraft.Client/Common/res/1_2_2/mob/alex4.png diff --git a/Minecraft.Client/Common/res/1_2_2/mob/char12.png b/Minecraft.Client/Common/res/1_2_2/mob/alex5.png similarity index 100% rename from Minecraft.Client/Common/res/1_2_2/mob/char12.png rename to Minecraft.Client/Common/res/1_2_2/mob/alex5.png diff --git a/Minecraft.Client/Common/res/1_2_2/mob/char14.png b/Minecraft.Client/Common/res/1_2_2/mob/alex6.png similarity index 100% rename from Minecraft.Client/Common/res/1_2_2/mob/char14.png rename to Minecraft.Client/Common/res/1_2_2/mob/alex6.png diff --git a/Minecraft.Client/Common/res/1_2_2/mob/char11.png b/Minecraft.Client/Common/res/1_2_2/mob/alex7.png similarity index 100% rename from Minecraft.Client/Common/res/1_2_2/mob/char11.png rename to Minecraft.Client/Common/res/1_2_2/mob/alex7.png diff --git a/Minecraft.Client/Common/res/1_2_2/mob/char.png b/Minecraft.Client/Common/res/1_2_2/mob/char.png index e05dbe69..7cfa08a8 100644 Binary files a/Minecraft.Client/Common/res/1_2_2/mob/char.png and b/Minecraft.Client/Common/res/1_2_2/mob/char.png differ diff --git a/Minecraft.Client/Common/res/1_2_2/mob/char1.png b/Minecraft.Client/Common/res/1_2_2/mob/char1.png index 32257c5b..41576e63 100644 Binary files a/Minecraft.Client/Common/res/1_2_2/mob/char1.png and b/Minecraft.Client/Common/res/1_2_2/mob/char1.png differ diff --git a/Minecraft.Client/Common/res/1_2_2/mob/char2.png b/Minecraft.Client/Common/res/1_2_2/mob/char2.png index 9c320cbc..b921f856 100644 Binary files a/Minecraft.Client/Common/res/1_2_2/mob/char2.png and b/Minecraft.Client/Common/res/1_2_2/mob/char2.png differ diff --git a/Minecraft.Client/Common/res/1_2_2/mob/char3.png b/Minecraft.Client/Common/res/1_2_2/mob/char3.png index d45682fc..c7a39868 100644 Binary files a/Minecraft.Client/Common/res/1_2_2/mob/char3.png and b/Minecraft.Client/Common/res/1_2_2/mob/char3.png differ diff --git a/Minecraft.Client/Common/res/1_2_2/mob/char4.png b/Minecraft.Client/Common/res/1_2_2/mob/char4.png index 00dad3d5..25dcfec4 100644 Binary files a/Minecraft.Client/Common/res/1_2_2/mob/char4.png and b/Minecraft.Client/Common/res/1_2_2/mob/char4.png differ diff --git a/Minecraft.Client/Common/res/1_2_2/mob/char5.png b/Minecraft.Client/Common/res/1_2_2/mob/char5.png index cef7742e..4cc80ac1 100644 Binary files a/Minecraft.Client/Common/res/1_2_2/mob/char5.png and b/Minecraft.Client/Common/res/1_2_2/mob/char5.png differ diff --git a/Minecraft.Client/Common/res/1_2_2/mob/char6.png b/Minecraft.Client/Common/res/1_2_2/mob/char6.png index d28abf78..74a71c4f 100644 Binary files a/Minecraft.Client/Common/res/1_2_2/mob/char6.png and b/Minecraft.Client/Common/res/1_2_2/mob/char6.png differ diff --git a/Minecraft.Client/Common/res/1_2_2/mob/char7.png b/Minecraft.Client/Common/res/1_2_2/mob/char7.png index 974403c2..216cc6d1 100644 Binary files a/Minecraft.Client/Common/res/1_2_2/mob/char7.png and b/Minecraft.Client/Common/res/1_2_2/mob/char7.png differ diff --git a/Minecraft.Client/Common/res/1_2_2/mob/char9.png b/Minecraft.Client/Common/res/1_2_2/mob/char9.png deleted file mode 100644 index da205681..00000000 Binary files a/Minecraft.Client/Common/res/1_2_2/mob/char9.png and /dev/null differ diff --git a/Minecraft.Client/Common/res/mob/char17.png b/Minecraft.Client/Common/res/mob/DevAlex.png similarity index 100% rename from Minecraft.Client/Common/res/mob/char17.png rename to Minecraft.Client/Common/res/mob/DevAlex.png diff --git a/Minecraft.Client/Common/res/mob/char8.png b/Minecraft.Client/Common/res/mob/DevSteve.png similarity index 100% rename from Minecraft.Client/Common/res/mob/char8.png rename to Minecraft.Client/Common/res/mob/DevSteve.png diff --git a/Minecraft.Client/Common/res/mob/alex.png b/Minecraft.Client/Common/res/mob/alex.png new file mode 100644 index 00000000..b643fe2d Binary files /dev/null and b/Minecraft.Client/Common/res/mob/alex.png differ diff --git a/Minecraft.Client/Common/res/mob/char13.png b/Minecraft.Client/Common/res/mob/alex1.png similarity index 100% rename from Minecraft.Client/Common/res/mob/char13.png rename to Minecraft.Client/Common/res/mob/alex1.png diff --git a/Minecraft.Client/Common/res/mob/char10.png b/Minecraft.Client/Common/res/mob/alex2.png similarity index 100% rename from Minecraft.Client/Common/res/mob/char10.png rename to Minecraft.Client/Common/res/mob/alex2.png diff --git a/Minecraft.Client/Common/res/mob/char15.png b/Minecraft.Client/Common/res/mob/alex3.png similarity index 100% rename from Minecraft.Client/Common/res/mob/char15.png rename to Minecraft.Client/Common/res/mob/alex3.png diff --git a/Minecraft.Client/Common/res/mob/char16.png b/Minecraft.Client/Common/res/mob/alex4.png similarity index 100% rename from Minecraft.Client/Common/res/mob/char16.png rename to Minecraft.Client/Common/res/mob/alex4.png diff --git a/Minecraft.Client/Common/res/mob/char12.png b/Minecraft.Client/Common/res/mob/alex5.png similarity index 100% rename from Minecraft.Client/Common/res/mob/char12.png rename to Minecraft.Client/Common/res/mob/alex5.png diff --git a/Minecraft.Client/Common/res/mob/char14.png b/Minecraft.Client/Common/res/mob/alex6.png similarity index 100% rename from Minecraft.Client/Common/res/mob/char14.png rename to Minecraft.Client/Common/res/mob/alex6.png diff --git a/Minecraft.Client/Common/res/mob/char11.png b/Minecraft.Client/Common/res/mob/alex7.png similarity index 100% rename from Minecraft.Client/Common/res/mob/char11.png rename to Minecraft.Client/Common/res/mob/alex7.png diff --git a/Minecraft.Client/Common/res/mob/char.png b/Minecraft.Client/Common/res/mob/char.png index e05dbe69..7cfa08a8 100644 Binary files a/Minecraft.Client/Common/res/mob/char.png and b/Minecraft.Client/Common/res/mob/char.png differ diff --git a/Minecraft.Client/Common/res/mob/char1.png b/Minecraft.Client/Common/res/mob/char1.png index 32257c5b..41576e63 100644 Binary files a/Minecraft.Client/Common/res/mob/char1.png and b/Minecraft.Client/Common/res/mob/char1.png differ diff --git a/Minecraft.Client/Common/res/mob/char2.png b/Minecraft.Client/Common/res/mob/char2.png index 9c320cbc..b921f856 100644 Binary files a/Minecraft.Client/Common/res/mob/char2.png and b/Minecraft.Client/Common/res/mob/char2.png differ diff --git a/Minecraft.Client/Common/res/mob/char3.png b/Minecraft.Client/Common/res/mob/char3.png index d45682fc..c7a39868 100644 Binary files a/Minecraft.Client/Common/res/mob/char3.png and b/Minecraft.Client/Common/res/mob/char3.png differ diff --git a/Minecraft.Client/Common/res/mob/char4.png b/Minecraft.Client/Common/res/mob/char4.png index 00dad3d5..25dcfec4 100644 Binary files a/Minecraft.Client/Common/res/mob/char4.png and b/Minecraft.Client/Common/res/mob/char4.png differ diff --git a/Minecraft.Client/Common/res/mob/char5.png b/Minecraft.Client/Common/res/mob/char5.png index cef7742e..4cc80ac1 100644 Binary files a/Minecraft.Client/Common/res/mob/char5.png and b/Minecraft.Client/Common/res/mob/char5.png differ diff --git a/Minecraft.Client/Common/res/mob/char6.png b/Minecraft.Client/Common/res/mob/char6.png index d28abf78..74a71c4f 100644 Binary files a/Minecraft.Client/Common/res/mob/char6.png and b/Minecraft.Client/Common/res/mob/char6.png differ diff --git a/Minecraft.Client/Common/res/mob/char7.png b/Minecraft.Client/Common/res/mob/char7.png index 974403c2..216cc6d1 100644 Binary files a/Minecraft.Client/Common/res/mob/char7.png and b/Minecraft.Client/Common/res/mob/char7.png differ diff --git a/Minecraft.Client/Common/res/mob/char9.png b/Minecraft.Client/Common/res/mob/char9.png deleted file mode 100644 index da205681..00000000 Binary files a/Minecraft.Client/Common/res/mob/char9.png and /dev/null differ diff --git a/Minecraft.Client/EntityRenderer.cpp b/Minecraft.Client/EntityRenderer.cpp index c292448e..4900d5c0 100644 --- a/Minecraft.Client/EntityRenderer.cpp +++ b/Minecraft.Client/EntityRenderer.cpp @@ -19,9 +19,8 @@ ResourceLocation EntityRenderer::SHADOW_LOCATION = ResourceLocation(TN__CLAMP__M EntityRenderer::EntityRenderer() { model = nullptr; + modelWide = nullptr; modelSlim = nullptr; - newModel = nullptr; - newModelSlim = nullptr; tileRenderer = new TileRenderer(); shadowRadius = 0; shadowStrength = 1.0f; @@ -409,6 +408,13 @@ void EntityRenderer::registerTerrainTextures(IconRegister *iconRegister) { } +Model *EntityRenderer::getModel(int modelType) +{ + if (modelType == 2) return modelSlim; + else if (modelType == 1) return modelWide; + else return model; +} + ResourceLocation *EntityRenderer::getTextureLocation(shared_ptr mob) { diff --git a/Minecraft.Client/EntityRenderer.h b/Minecraft.Client/EntityRenderer.h index 6cdb1d86..c91f807c 100644 --- a/Minecraft.Client/EntityRenderer.h +++ b/Minecraft.Client/EntityRenderer.h @@ -31,9 +31,8 @@ private: protected: Model *model; // TODO 4J: Check why exactly this is here, it seems to get shadowed by classes inheriting from this by their own + Model *modelWide; Model *modelSlim; - Model *newModel; - Model *newModelSlim; protected: TileRenderer *tileRenderer; // 4J - changed to protected so derived classes can use instead of shadowing their own @@ -71,10 +70,7 @@ public: public: // 4J Added - virtual Model *getModel() { return model; } - virtual Model *getModelSlim() { return modelSlim; } - virtual Model *getNewModel() { return newModel; } - virtual Model *getNewModelSlim() { return newModelSlim; } + virtual Model *getModel(int modelType = 0); virtual void SetItemFrame(bool bSet) {} virtual bool shouldRender(shared_ptr entity, float camX, float camY, float camZ) { return true; } diff --git a/Minecraft.Client/GameRenderer.cpp b/Minecraft.Client/GameRenderer.cpp index 1d99aa6b..891c595f 100644 --- a/Minecraft.Client/GameRenderer.cpp +++ b/Minecraft.Client/GameRenderer.cpp @@ -214,8 +214,7 @@ void GameRenderer::tick(bool first) // 4J - add bFirst { shared_ptr yBobPlayer = dynamic_pointer_cast(mc->cameraTargetPlayer); float target = 0.0f; - if (yBobPlayer != nullptr && !yBobPlayer->onGround - && !(yBobPlayer->abilities.mayfly && yBobPlayer->abilities.flying)) + if (yBobPlayer != nullptr && yBobPlayer->isElytraFlying()) { target = (float)(atan(-yBobPlayer->yd * 0.2) * 15.0); diff --git a/Minecraft.Client/HumanoidModel.cpp b/Minecraft.Client/HumanoidModel.cpp index c363f528..bd362789 100644 --- a/Minecraft.Client/HumanoidModel.cpp +++ b/Minecraft.Client/HumanoidModel.cpp @@ -1,14 +1,16 @@ #include "stdafx.h" #include "HumanoidModel.h" #include "../Minecraft.World/Mth.h" -#include "../Minecraft.World/Entity.h" +#include "../Minecraft.World/Player.h" #include "ModelPart.h" +#include "Cube.h" // 4J added ModelPart * HumanoidModel::AddOrRetrievePart(SKIN_BOX *pBox) { ModelPart *pAttachTo=nullptr; + float scale=0; switch(pBox->ePart) { @@ -32,21 +34,65 @@ ModelPart * HumanoidModel::AddOrRetrievePart(SKIN_BOX *pBox) break; case eBodyPart_Jacket: pAttachTo=jacket; + scale=0.25; break; case eBodyPart_Sleeve0: pAttachTo=sleeve0; + scale=0.25; break; case eBodyPart_Sleeve1: pAttachTo=sleeve1; + scale=0.25; break; case eBodyPart_Pants0: pAttachTo=pants0; + scale=0.25; break; case eBodyPart_Pants1: pAttachTo=pants1; + scale=0.25; + break; + case eBodyPart_Headwear: + pAttachTo=hair; + break; + case eBodyPart_Waist: + pAttachTo=waist; + break; + case eBodyPart_Belt: + pAttachTo=belt; + break; + case eBodyPart_BodyArmor: + pAttachTo=bodyArmor; + break; + case eBodyPart_ArmArmor0: + pAttachTo=armArmor0; + break; + case eBodyPart_ArmArmor1: + pAttachTo=armArmor1; + break; + case eBodyPart_Legging0: + pAttachTo=legging0; + break; + case eBodyPart_Legging1: + pAttachTo=legging1; + break; + case eBodyPart_Sock0: + pAttachTo=sock0; + break; + case eBodyPart_Sock1: + pAttachTo=sock1; + break; + case eBodyPart_Boot0: + pAttachTo=boot0; + break; + case eBodyPart_Boot1: + pAttachTo=boot1; break; } + // check if this box has a declared scale then add it + if (pBox->fS != 0) scale = pBox->fS; + // first check this box doesn't already exist ModelPart *pNewBox = pAttachTo->retrieveChild(pBox); @@ -64,26 +110,42 @@ ModelPart * HumanoidModel::AddOrRetrievePart(SKIN_BOX *pBox) pNewBox = new ModelPart(this, static_cast(pBox->fU), static_cast(pBox->fV)); pNewBox->visible=false; - pNewBox->addHumanoidBox(pBox->fX, pBox->fY, pBox->fZ, pBox->fW, pBox->fH, pBox->fD, 0); + if (pBox->fM > 0) pNewBox->bMirror = true; // check if this box has the mirror flag + pNewBox->hideWithArmor = (unsigned int)pBox->fA; // add the "hide when armor is worn" bit flags + pNewBox->addHumanoidBox(pBox->fX, pBox->fY, pBox->fZ, pBox->fW, pBox->fH, pBox->fD, scale); // 4J-PB - don't compile here, since the lighting isn't set up. It'll be compiled on first use. - //pNewBox->compile(1.0f/16.0f); + //pNewBox->compile(1.0f/16.0f); pAttachTo->addChild(pNewBox); } return pNewBox; } -void HumanoidModel::_init(float g, float yOffset, int texWidth, int texHeight, bool slimHands, bool mirror, bool force32) +void HumanoidModel::_init(float g, float yOffset, int texWidth, int texHeight, bool slim, bool isArmor) { this->texWidth = texWidth; this->texHeight = texHeight; + m_is64x64 = texHeight == 64; + jacket = nullptr; sleeve0 = nullptr; sleeve1 = nullptr; pants0 = nullptr; pants1 = nullptr; + waist = nullptr; + belt = nullptr; + bodyArmor = nullptr; + armArmor0 = nullptr; + armArmor1 = nullptr; + legging0 = nullptr; + legging1 = nullptr; + sock0 = nullptr; + sock1 = nullptr; + boot0 = nullptr; + boot1 = nullptr; + m_fYOffset=yOffset; cloak = new ModelPart(this, 0, 0); cloak->addHumanoidBox(-5, -0, -1, 10, 16, 1, g); // Cloak @@ -97,8 +159,6 @@ void HumanoidModel::_init(float g, float yOffset, int texWidth, int texHeight, b elytraLeft->addHumanoidBox(0.0f, 0.0f, 0.0f, 10, 20, 2, 0.0f); elytraLeft->setPos(-5.0f, 0.0f + yOffset, 0.0f); // Wing Right - - ear = new ModelPart(this, 24, 0); ear->addHumanoidBox(-3, -6, -1, 6, 6, 1, g); // Ear @@ -110,18 +170,11 @@ void HumanoidModel::_init(float g, float yOffset, int texWidth, int texHeight, b hair->addHumanoidBox(-4, -8, -4, 8, 8, 8, g + 0.5f); // Head hair->setPos(0, 0 + yOffset, 0); - if ((texWidth == 64 && texHeight == 64) && !force32) - { - jacket = new ModelPart(this, 16, 32); - jacket->addHumanoidBox(-4, 0, -2, 8, 12, 4, g + 0.5); - jacket->setPos(0, 0 + yOffset, 0); - } - body = new ModelPart(this, 16, 16); body->addHumanoidBox(-4, 0, -2, 8, 12, 4, g); // Body body->setPos(0, 0 + yOffset, 0); - if ((texWidth == 64 && texHeight == 64) && !force32) + if (m_is64x64) { arm0 = new ModelPart(this, 24 + 16, 16); arm1 = new ModelPart(this, 16 + 16, 48); @@ -129,60 +182,96 @@ void HumanoidModel::_init(float g, float yOffset, int texWidth, int texHeight, b sleeve0 = new ModelPart(this, 24 + 16, 32); sleeve1 = new ModelPart(this, 32 + 16, 48); - if (slimHands == false) + if (!slim) { - sleeve0->addHumanoidBox(-3, -2, -2, 4, 12, 4, g + 0.5); - sleeve1->addHumanoidBox(-1, -2, -2, 4, 12, 4, g + 0.5); + sleeve0->addHumanoidBox(-3, -2, -2, 4, 12, 4, g + 0.25f); // Sleeve0 + sleeve1->addHumanoidBox(-1, -2, -2, 4, 12, 4, g + 0.25f); // Sleeve1 } - else if (slimHands == true) + else if (slim) { - sleeve0->addHumanoidBox(-2, -2, -2, 3, 12, 4, g + 0.5); - sleeve1->addHumanoidBox(-1, -2, -2, 3, 12, 4, g + 0.5); + sleeve0->addHumanoidBox(-2, -2, -2, 3, 12, 4, g + 0.25f); // Sleeve0 Slim + sleeve1->addHumanoidBox(-1, -2, -2, 3, 12, 4, g + 0.25f); // Sleeve1 Slim } + jacket = new ModelPart(this, 16, 32); + jacket->addHumanoidBox(-4, 0, -2, 8, 12, 4, g + 0.25f); + jacket->setPos(0, 0 + yOffset, 0); + sleeve0->setPos(-5, 2 + yOffset, 0); sleeve1->setPos(5, 2 + yOffset, 0); + + waist = new ModelPart(this, 0, 0); + waist->addHumanoidBox(0, 0, 0, 0, 0, 0, g); // Waist + waist->setPos(0, 0 + yOffset, 0); + belt = new ModelPart(this, 0, 0); + belt->addHumanoidBox(0, 0, 0, 0, 0, 0, g); // Belt + belt->setPos(0, 0 + yOffset, 0); + bodyArmor = new ModelPart(this, 0, 0); + bodyArmor->addHumanoidBox(0, 0, 0, 0, 0, 0, g); // BodyArmor + bodyArmor->setPos(0, 0 + yOffset, 0); + armArmor0 = new ModelPart(this, 0, 0); + armArmor0->addHumanoidBox(0, 0, 0, 0, 0, 0, g); // ArmArmor0 + armArmor0->setPos(-5, 2 + yOffset, 0); + armArmor1 = new ModelPart(this, 0, 0); + armArmor1->addHumanoidBox(0, 0, 0, 0, 0, 0, g); // ArmArmor1 + armArmor1->setPos(5, 2 + yOffset, 0); + legging0 = new ModelPart(this, 0, 0); + legging0->addHumanoidBox(0, 0, 0, 0, 0, 0, g); // Legging0 + legging0->setPos(-1.9, 12 + yOffset, 0); + legging1 = new ModelPart(this, 0, 0); + legging1->addHumanoidBox(0, 0, 0, 0, 0, 0, g); // Legging1 + legging1->setPos(1.9, 12 + yOffset, 0); + sock0 = new ModelPart(this, 0, 0); + sock0->addHumanoidBox(0, 0, 0, 0, 0, 0, g); // Sock0 + sock0->setPos(-1.9, 12 + yOffset, 0); + sock1 = new ModelPart(this, 0, 0); + sock1->addHumanoidBox(0, 0, 0, 0, 0, 0, g); // Sock1 + sock1->setPos(1.9, 12 + yOffset, 0); + boot0 = new ModelPart(this, 0, 0); + boot0->addHumanoidBox(0, 0, 0, 0, 0, 0, g); // Boot0 + boot0->setPos(-1.9, 12 + yOffset, 0); + boot1 = new ModelPart(this, 0, 0); + boot1->addHumanoidBox(0, 0, 0, 0, 0, 0, g); // Boot1 + boot1->setPos(1.9, 12 + yOffset, 0); } - else if ((texWidth == 64 && texHeight == 32) || force32) + else if (!m_is64x64) { arm0 = new ModelPart(this, 24 + 16, 16); arm1 = new ModelPart(this, 24 + 16, 16); - } - - if (slimHands == false) - { - arm0->addHumanoidBox(-3, -2, -2, 4, 12, 4, g); - arm1->addHumanoidBox(-1, -2, -2, 4, 12, 4, g); - } - else if (slimHands == true) - { - arm0->addHumanoidBox(-2, -2, -2, 3, 12, 4, g); - arm1->addHumanoidBox(-1, -2, -2, 3, 12, 4, g); - } - - arm0->setPos(-5, 2 + yOffset, 0); - arm1->setPos(5, 2 + yOffset, 0); - - if (mirror == true) arm1->bMirror = true; + } - if ((texWidth == 64 && texHeight == 64) && !force32) + if (!slim) + { + arm0->addHumanoidBox(-3, -2, -2, 4, 12, 4, g); // Arm0 + arm1->addHumanoidBox(-1, -2, -2, 4, 12, 4, g); // Arm1 + } + else if (slim) + { + arm0->addHumanoidBox(-2, -2, -2, 3, 12, 4, g); // Arm0 Slim + arm1->addHumanoidBox(-1, -2, -2, 3, 12, 4, g); // Arm1 Slim + } + + arm0->setPos(-5, 2 + yOffset, 0); + arm1->setPos(5, 2 + yOffset, 0); + + leg0 = new ModelPart(this, 0, 16); + if (m_is64x64) { - leg0 = new ModelPart(this, 0, 16); leg1 = new ModelPart(this, 16, 48); pants0 = new ModelPart(this, 0, 32); - pants0->addHumanoidBox(-2, 0, -2, 4, 12, 4, g + 0.5); + pants0->addHumanoidBox(-2, 0, -2, 4, 12, 4, g + 0.25f); // Pants0 pants0->setPos(-1.9, 12 + yOffset, 0); pants1 = new ModelPart(this, 0, 48); - pants1->addHumanoidBox(-2, 0, -2, 4, 12, 4, g + 0.5); + pants1->addHumanoidBox(-2, 0, -2, 4, 12, 4, g + 0.25f); // Pants1 pants1->setPos(1.9, 12 + yOffset, 0); } - else if ((texWidth == 64 && texHeight == 32) || force32) + else if (!m_is64x64) { - leg0 = new ModelPart(this, 0, 16); leg1 = new ModelPart(this, 0, 16); + leg1->bMirror = true; } leg0->addHumanoidBox(-2, 0, -2, 4, 12, 4, g); // Leg0 @@ -191,9 +280,6 @@ void HumanoidModel::_init(float g, float yOffset, int texWidth, int texHeight, b leg1->addHumanoidBox(-2, 0, -2, 4, 12, 4, g); // Leg1 leg1->setPos(1.9, 12 + yOffset, 0); - if (mirror == true) - leg1->bMirror = true; - // 4J added - compile now to avoid random performance hit first time cubes are rendered // 4J Stu - Not just performance, but alpha+depth tests don't work right unless we compile here cloak->compile(1.0f/16.0f); @@ -208,16 +294,25 @@ void HumanoidModel::_init(float g, float yOffset, int texWidth, int texHeight, b leg1->compile(1.0f/16.0f); hair->compile(1.0f/16.0f); - if (jacket != 0) + if (m_is64x64) + { jacket->compile(1.0f/16.0f); - if (sleeve0 != 0) sleeve0->compile(1.0f/16.0f); - if (sleeve1 != 0) sleeve1->compile(1.0f/16.0f); - if (pants0 != 0) pants0->compile(1.0f/16.0f); - if (pants1 != 0) pants1->compile(1.0f/16.0f); + waist->compile(1.0f/16.0f); + belt->compile(1.0f/16.0f); + bodyArmor->compile(1.0f/16.0f); + armArmor0->compile(1.0f/16.0f); + armArmor1->compile(1.0f/16.0f); + legging0->compile(1.0f/16.0f); + legging1->compile(1.0f/16.0f); + sock0->compile(1.0f/16.0f); + sock1->compile(1.0f/16.0f); + boot0->compile(1.0f/16.0f); + boot1->compile(1.0f/16.0f); + } holdingLeftHand=0; holdingRightHand=0; @@ -226,7 +321,7 @@ void HumanoidModel::_init(float g, float yOffset, int texWidth, int texHeight, b bowAndArrow=false; elytraFlying = false; elytraCrouching = false; - + m_isArmor = isArmor; // 4J added eating = false; @@ -238,39 +333,435 @@ void HumanoidModel::_init(float g, float yOffset, int texWidth, int texHeight, b HumanoidModel::HumanoidModel() : Model() { - _init(0, 0, 64, 32, false, true, false); + _init(0, 0, 64, 32, false, false); } HumanoidModel::HumanoidModel(float g) : Model() { - _init(g, 0, 64, 32, false, true, false); + _init(g, 0, 64, 32, false, false); +} + +HumanoidModel::HumanoidModel(float g, bool isArmor) : Model() +{ + _init(g, 0, 64, 32, false, isArmor); } HumanoidModel::HumanoidModel(float g, float yOffset, int texWidth, int texHeight) : Model() { - _init(g,yOffset,texWidth,texHeight, false, true, false); + _init(g, yOffset, texWidth, texHeight, false, false); } -HumanoidModel::HumanoidModel(float g, float yOffset, int texWidth, int texHeight, bool slimHands) : Model() +HumanoidModel::HumanoidModel(float g, float yOffset, int texWidth, int texHeight, bool slim) : Model() { - _init(g,yOffset,texWidth,texHeight, slimHands, true, false); -} - -HumanoidModel::HumanoidModel(float g, float yOffset, int texWidth, int texHeight, bool slimHands, bool mirror) : Model() -{ - _init(g,yOffset,texWidth,texHeight, slimHands, mirror, false); -} - -HumanoidModel::HumanoidModel(float g, float yOffset, int texWidth, int texHeight, bool slimHands, bool mirror, bool force32) : Model() -{ - _init(g,yOffset,texWidth,texHeight, slimHands, mirror, force32); + _init(g, yOffset, texWidth, texHeight, slim, false); } void HumanoidModel::render(shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled) -{ +{ + float headOffsets[3] = {0}; + float bodyOffsets[3] = {0}; + float arm0Offsets[3] = {0}; + float arm1Offsets[3] = {0}; + float leg0Offsets[3] = {0}; + float leg1Offsets[3] = {0}; + if(entity != nullptr) { m_uiAnimOverrideBitmask=entity->getAnimOverrideBitmask(); + + // Reset offsets so they don't leak onto other skins - Langtanium + head->translateX = 0; + head->translateY = 0; + head->translateZ = 0; + hair->translateX = 0; + hair->translateY = 0; + hair->translateZ = 0; + body->translateX = 0; + body->translateY = 0; + body->translateZ = 0; + arm0->translateX = 0; + arm0->translateY = 0; + arm0->translateZ = 0; + arm1->translateX = 0; + arm1->translateY = 0; + arm1->translateZ = 0; + leg0->translateX = 0; + leg0->translateY = 0; + leg0->translateZ = 0; + leg1->translateX = 0; + leg1->translateY = 0; + leg1->translateZ = 0; + if (m_is64x64) + { + jacket->translateX = 0; + jacket->translateY = 0; + jacket->translateZ = 0; + sleeve0->translateX = 0; + sleeve0->translateY = 0; + sleeve0->translateZ = 0; + sleeve1->translateX = 0; + sleeve1->translateY = 0; + sleeve1->translateZ = 0; + pants0->translateX = 0; + pants0->translateY = 0; + pants0->translateZ = 0; + pants1->translateX = 0; + pants1->translateY = 0; + pants1->translateZ = 0; + bodyArmor->translateX = 0; + bodyArmor->translateY = 0; + bodyArmor->translateZ = 0; + waist->translateX = 0; + waist->translateY = 0; + waist->translateZ = 0; + belt->translateX = 0; + belt->translateY = 0; + belt->translateZ = 0; + armArmor0->translateX = 0; + armArmor0->translateY = 0; + armArmor0->translateZ = 0; + armArmor1->translateX = 0; + armArmor1->translateY = 0; + armArmor1->translateZ = 0; + legging0->translateX = 0; + legging0->translateY = 0; + legging0->translateZ = 0; + legging1->translateX = 0; + legging1->translateY = 0; + legging1->translateZ = 0; + sock0->translateX = 0; + sock0->translateY = 0; + sock0->translateZ = 0; + sock1->translateX = 0; + sock1->translateY = 0; + sock1->translateZ = 0; + boot0->translateX = 0; + boot0->translateY = 0; + boot0->translateZ = 0; + boot1->translateX = 0; + boot1->translateY = 0; + boot1->translateZ = 0; + } + + shared_ptr player = dynamic_pointer_cast(entity); + vector* pSkinOffsets = nullptr; + if (player != nullptr) + pSkinOffsets = player->GetSkinOffsets(); + if (pSkinOffsets != nullptr) + { + for( SKIN_OFFSET *pSkinOffset : *pSkinOffsets ) + { + switch (pSkinOffset->ePart) + { + case eBodyOffset_Head: + if (pSkinOffset->fD == 1 && head->translateX == 0) + { + head->translateX = pSkinOffset->fO / 16.0f; + hair->translateX = pSkinOffset->fO / 16.0f; + headOffsets[0] = pSkinOffset->fO / 16.0f; + } + else if (pSkinOffset->fD == 2 && head->translateY == 0) + { + head->translateY = pSkinOffset->fO / 16.0f; + hair->translateY = pSkinOffset->fO / 16.0f; + headOffsets[1] = pSkinOffset->fO / 16.0f; + } + else if (pSkinOffset->fD == 3 && head->translateZ == 0) + { + head->translateZ = pSkinOffset->fO / 16.0f; + hair->translateZ = pSkinOffset->fO / 16.0f; + headOffsets[2] = pSkinOffset->fO / 16.0f; + } + break; + case eBodyOffset_Body: + if (pSkinOffset->fD == 1 && body->translateX == 0) + { + body->translateX = pSkinOffset->fO / 16.0f; + if (m_is64x64) + { + jacket->translateX = pSkinOffset->fO / 16.0f; + bodyArmor->translateX = pSkinOffset->fO / 16.0f; + waist->translateX = pSkinOffset->fO / 16.0f; + belt->translateX = pSkinOffset->fO / 16.0f; + } + bodyOffsets[0] = pSkinOffset->fO / 16.0f; + } + else if (pSkinOffset->fD == 2 && body->translateY == 0) + { + body->translateY = pSkinOffset->fO / 16.0f; + if (m_is64x64) + { + jacket->translateY = pSkinOffset->fO / 16.0f; + bodyArmor->translateY = pSkinOffset->fO / 16.0f; + waist->translateY = pSkinOffset->fO / 16.0f; + belt->translateY = pSkinOffset->fO / 16.0f; + } + bodyOffsets[1] = pSkinOffset->fO / 16.0f; + } + else if (pSkinOffset->fD == 3 && body->translateZ == 0) + { + body->translateZ = pSkinOffset->fO / 16.0f; + if (m_is64x64) + { + jacket->translateZ = pSkinOffset->fO / 16.0f; + bodyArmor->translateZ = pSkinOffset->fO / 16.0f; + waist->translateZ = pSkinOffset->fO / 16.0f; + belt->translateZ = pSkinOffset->fO / 16.0f; + } + bodyOffsets[2] = pSkinOffset->fO / 16.0f; + } + break; + case eBodyOffset_Arm0: + if (pSkinOffset->fD == 1 && arm0->translateX == 0) + { + arm0->translateX = pSkinOffset->fO / 16.0f; + if (m_is64x64) + { + sleeve0->translateX = pSkinOffset->fO / 16.0f; + armArmor0->translateX = pSkinOffset->fO / 16.0f; + } + arm0Offsets[0] = pSkinOffset->fO / 16.0f; + } + else if (pSkinOffset->fD == 2 && arm0->translateY == 0) + { + arm0->translateY = pSkinOffset->fO / 16.0f; + if (m_is64x64) + { + sleeve0->translateY = pSkinOffset->fO / 16.0f; + armArmor0->translateY = pSkinOffset->fO / 16.0f; + } + arm0Offsets[1] = pSkinOffset->fO / 16.0f; + } + else if (pSkinOffset->fD == 3 && arm0->translateZ == 0) + { + arm0->translateZ = pSkinOffset->fO / 16.0f; + if (m_is64x64) + { + sleeve0->translateZ = pSkinOffset->fO / 16.0f; + armArmor0->translateZ = pSkinOffset->fO / 16.0f; + } + arm0Offsets[2] = pSkinOffset->fO / 16.0f; + } + break; + case eBodyOffset_Arm1: + if (pSkinOffset->fD == 1 && arm1->translateX == 0) + { + arm1->translateX = pSkinOffset->fO / 16.0f; + if (m_is64x64) + { + sleeve1->translateX = pSkinOffset->fO / 16.0f; + armArmor1->translateX = pSkinOffset->fO / 16.0f; + } + arm1Offsets[0] = pSkinOffset->fO / 16.0f; + } + else if (pSkinOffset->fD == 2 && arm1->translateY == 0) + { + arm1->translateY = pSkinOffset->fO / 16.0f; + if (m_is64x64) + { + sleeve1->translateY = pSkinOffset->fO / 16.0f; + armArmor1->translateY = pSkinOffset->fO / 16.0f; + } + arm1Offsets[1] = pSkinOffset->fO / 16.0f; + } + else if (pSkinOffset->fD == 3 && arm1->translateZ == 0) + { + arm1->translateZ = pSkinOffset->fO / 16.0f; + if (m_is64x64) + { + sleeve1->translateZ = pSkinOffset->fO / 16.0f; + armArmor1->translateZ = pSkinOffset->fO / 16.0f; + } + arm1Offsets[2] = pSkinOffset->fO / 16.0f; + } + break; + case eBodyOffset_Leg0: + if (pSkinOffset->fD == 1 && leg0->translateX == 0) + { + leg0->translateX = pSkinOffset->fO / 16.0f; + if (m_is64x64) + { + pants0->translateX = pSkinOffset->fO / 16.0f; + legging0->translateX = pSkinOffset->fO / 16.0f; + sock0->translateX = pSkinOffset->fO / 16.0f; + boot0->translateX = pSkinOffset->fO / 16.0f; + } + leg0Offsets[0] = pSkinOffset->fO / 16.0f; + } + else if (pSkinOffset->fD == 2 && leg0->translateY == 0) + { + leg0->translateY = pSkinOffset->fO / 16.0f; + if (m_is64x64) + { + pants0->translateY = pSkinOffset->fO / 16.0f; + legging0->translateY = pSkinOffset->fO / 16.0f; + sock0->translateY = pSkinOffset->fO / 16.0f; + boot0->translateY = pSkinOffset->fO / 16.0f; + } + leg0Offsets[1] = pSkinOffset->fO / 16.0f; + } + else if (pSkinOffset->fD == 3 && leg0->translateZ == 0) + { + leg0->translateZ = pSkinOffset->fO / 16.0f; + if (m_is64x64) + { + pants0->translateZ = pSkinOffset->fO / 16.0f; + legging0->translateZ = pSkinOffset->fO / 16.0f; + sock0->translateZ = pSkinOffset->fO / 16.0f; + boot0->translateZ = pSkinOffset->fO / 16.0f; + } + leg0Offsets[2] = pSkinOffset->fO / 16.0f; + } + break; + case eBodyOffset_Leg1: + if (pSkinOffset->fD == 1 && leg1->translateX == 0) + { + leg1->translateX = pSkinOffset->fO / 16.0f; + if (m_is64x64) + { + pants1->translateX = pSkinOffset->fO / 16.0f; + legging1->translateX = pSkinOffset->fO / 16.0f; + sock1->translateX = pSkinOffset->fO / 16.0f; + boot1->translateX = pSkinOffset->fO / 16.0f; + } + leg1Offsets[0] = pSkinOffset->fO / 16.0f; + } + else if (pSkinOffset->fD == 2 && leg1->translateY == 0) + { + leg1->translateY = pSkinOffset->fO / 16.0f; + if (m_is64x64) + { + pants1->translateY = pSkinOffset->fO / 16.0f; + legging1->translateY = pSkinOffset->fO / 16.0f; + sock1->translateY = pSkinOffset->fO / 16.0f; + boot1->translateY = pSkinOffset->fO / 16.0f; + } + leg1Offsets[1] = pSkinOffset->fO / 16.0f; + } + else if (pSkinOffset->fD == 3 && leg1->translateZ == 0) + { + leg1->translateZ = pSkinOffset->fO / 16.0f; + if (m_is64x64) + { + pants1->translateZ = pSkinOffset->fO / 16.0f; + legging1->translateZ = pSkinOffset->fO / 16.0f; + sock1->translateZ = pSkinOffset->fO / 16.0f; + boot1->translateZ = pSkinOffset->fO / 16.0f; + } + leg1Offsets[2] = pSkinOffset->fO / 16.0f; + } + break; + case eBodyOffset_Helmet: + if (m_isArmor) + { + if (pSkinOffset->fD == 1 && head->translateX == headOffsets[0]) + { + head->translateX += pSkinOffset->fO / 16.0f; + hair->translateX += pSkinOffset->fO / 16.0f; + } + else if (pSkinOffset->fD == 2 && head->translateY == headOffsets[1]) + { + head->translateY += pSkinOffset->fO / 16.0f; + hair->translateY += pSkinOffset->fO / 16.0f; + } + else if (pSkinOffset->fD == 3 && head->translateZ == headOffsets[2]) + { + head->translateZ += pSkinOffset->fO / 16.0f; + hair->translateZ += pSkinOffset->fO / 16.0f; + } + } + break; + case eBodyOffset_BodyArmor: + if (m_isArmor && !body->isArmorPart2) + { + if (pSkinOffset->fD == 1 && body->translateX == bodyOffsets[0]) + body->translateX += pSkinOffset->fO / 16.0f; + else if (pSkinOffset->fD == 2 && body->translateY == bodyOffsets[1]) + body->translateY += pSkinOffset->fO / 16.0f; + else if (pSkinOffset->fD == 3 && body->translateZ == bodyOffsets[2]) + body->translateZ += pSkinOffset->fO / 16.0f; + } + break; + case eBodyOffset_ArmArmor0: + if (m_isArmor) + { + if (pSkinOffset->fD == 1 && arm0->translateX == arm0Offsets[0]) + arm0->translateX += pSkinOffset->fO / 16.0f; + else if (pSkinOffset->fD == 2 && arm0->translateY == arm0Offsets[1]) + arm0->translateY += pSkinOffset->fO / 16.0f; + else if (pSkinOffset->fD == 3 && arm0->translateZ == arm0Offsets[2]) + arm0->translateZ += pSkinOffset->fO / 16.0f; + } + break; + case eBodyOffset_ArmArmor1: + if (m_isArmor) + { + if (pSkinOffset->fD == 1 && arm1->translateX == arm1Offsets[0]) + arm1->translateX += pSkinOffset->fO / 16.0f; + else if (pSkinOffset->fD == 2 && arm1->translateY == arm1Offsets[1]) + arm1->translateY += pSkinOffset->fO / 16.0f; + else if (pSkinOffset->fD == 3 && arm1->translateZ == arm1Offsets[2]) + arm1->translateZ += pSkinOffset->fO / 16.0f; + } + break; + case eBodyOffset_Waist: + if (m_isArmor && body->isArmorPart2) + { + if (pSkinOffset->fD == 1 && body->translateX == bodyOffsets[0]) + body->translateX += pSkinOffset->fO / 16.0f; + else if (pSkinOffset->fD == 2 && body->translateY == bodyOffsets[1]) + body->translateY += pSkinOffset->fO / 16.0f; + else if (pSkinOffset->fD == 3 && body->translateZ == bodyOffsets[2]) + body->translateZ += pSkinOffset->fO / 16.0f; + } + break; + case eBodyOffset_Legging0: + if (m_isArmor && leg0->isArmorPart2) + { + if (pSkinOffset->fD == 1 && leg0->translateX == leg0Offsets[0]) + leg0->translateX += pSkinOffset->fO / 16.0f; + else if (pSkinOffset->fD == 2 && leg0->translateY == leg0Offsets[1]) + leg0->translateY += pSkinOffset->fO / 16.0f; + else if (pSkinOffset->fD == 3 && leg0->translateZ == leg0Offsets[2]) + leg0->translateZ += pSkinOffset->fO / 16.0f; + } + break; + case eBodyOffset_Legging1: + if (m_isArmor && leg1->isArmorPart2) + { + if (pSkinOffset->fD == 1 && leg1->translateX == leg1Offsets[0]) + leg1->translateX += pSkinOffset->fO / 16.0f; + else if (pSkinOffset->fD == 2 && leg1->translateY == leg1Offsets[1]) + leg1->translateY += pSkinOffset->fO / 16.0f; + else if (pSkinOffset->fD == 3 && leg1->translateZ == leg1Offsets[2]) + leg1->translateZ += pSkinOffset->fO / 16.0f; + } + break; + case eBodyOffset_Boot0: + if (m_isArmor && !leg0->isArmorPart2) + { + if (pSkinOffset->fD == 1 && leg0->translateX == leg0Offsets[0]) + leg0->translateX += pSkinOffset->fO / 16.0f; + else if (pSkinOffset->fD == 2 && leg0->translateY == leg0Offsets[1]) + leg0->translateY += pSkinOffset->fO / 16.0f; + else if (pSkinOffset->fD == 3 && leg0->translateZ == leg0Offsets[2]) + leg0->translateZ += pSkinOffset->fO / 16.0f; + } + break; + case eBodyOffset_Boot1: + if (m_isArmor && !leg1->isArmorPart2) + { + if (pSkinOffset->fD == 1 && leg1->translateX == leg1Offsets[0]) + leg1->translateX += pSkinOffset->fO / 16.0f; + else if (pSkinOffset->fD == 2 && leg1->translateY == leg1Offsets[1]) + leg1->translateY += pSkinOffset->fO / 16.0f; + else if (pSkinOffset->fD == 3 && leg1->translateZ == leg1Offsets[2]) + leg1->translateZ += pSkinOffset->fO / 16.0f; + } + break; + } + } + } } setupAnim(time, r, bob, yRot, xRot, scale, entity, m_uiAnimOverrideBitmask); @@ -293,39 +784,342 @@ void HumanoidModel::render(shared_ptr entity, float time, float r, float leg1->render(scale, usecompiled); hair->render(scale, usecompiled); - if (jacket) + if (m_is64x64) + { jacket->render(scale, usecompiled); - if (sleeve0) sleeve0->render(scale, usecompiled); - if (sleeve1) sleeve1->render(scale, usecompiled); - if (pants0) pants0->render(scale, usecompiled); - if (pants1) pants1->render(scale, usecompiled); + } glPopMatrix(); } else { - head->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<0); - body->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<0); - arm0->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<0); - arm1->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<0); - leg0->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<0); - leg1->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<0); + head->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<0&&(!(m_uiAnimOverrideBitmask&(1<0||!m_isArmor)); + body->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<0&&(!(m_uiAnimOverrideBitmask&(1<0||!m_isArmor)); + arm0->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<0&&(!(m_uiAnimOverrideBitmask&(1<0||!m_isArmor)); + arm1->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<0&&(!(m_uiAnimOverrideBitmask&(1<0||!m_isArmor)); + leg0->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<0&&(!(m_uiAnimOverrideBitmask&(1<0||!m_isArmor)); + leg1->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<0&&(!(m_uiAnimOverrideBitmask&(1<0||!m_isArmor)); hair->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<0); - - if (jacket) + if (m_is64x64) + { jacket->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<0); - if (sleeve0) sleeve0->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<0); - if (sleeve1) sleeve1->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<0); - if (pants0) pants0->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<0); - if (pants1) pants1->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<0); + waist->render(scale, usecompiled); + belt->render(scale, usecompiled); + bodyArmor->render(scale, usecompiled); + armArmor0->render(scale, usecompiled); + armArmor1->render(scale, usecompiled); + legging0->render(scale, usecompiled); + legging1->render(scale, usecompiled); + sock0->render(scale, usecompiled); + sock1->render(scale, usecompiled); + boot0->render(scale, usecompiled); + boot1->render(scale, usecompiled); + } + } +} + +// This code is similar to what's above, but allows skin offsets to work in the skin select menu - Langtanium +void HumanoidModel::renderUI(float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled, vector *skinOffsets) +{ + // Reset offsets so they don't leak onto other skins - Langtanium + head->translateX = 0; + head->translateY = 0; + head->translateZ = 0; + hair->translateX = 0; + hair->translateY = 0; + hair->translateZ = 0; + body->translateX = 0; + body->translateY = 0; + body->translateZ = 0; + arm0->translateX = 0; + arm0->translateY = 0; + arm0->translateZ = 0; + arm1->translateX = 0; + arm1->translateY = 0; + arm1->translateZ = 0; + leg0->translateX = 0; + leg0->translateY = 0; + leg0->translateZ = 0; + leg1->translateX = 0; + leg1->translateY = 0; + leg1->translateZ = 0; + if (m_is64x64) + { + jacket->translateX = 0; + jacket->translateY = 0; + jacket->translateZ = 0; + sleeve0->translateX = 0; + sleeve0->translateY = 0; + sleeve0->translateZ = 0; + sleeve1->translateX = 0; + sleeve1->translateY = 0; + sleeve1->translateZ = 0; + pants0->translateX = 0; + pants0->translateY = 0; + pants0->translateZ = 0; + pants1->translateX = 0; + pants1->translateY = 0; + pants1->translateZ = 0; + bodyArmor->translateX = 0; + bodyArmor->translateY = 0; + bodyArmor->translateZ = 0; + waist->translateX = 0; + waist->translateY = 0; + waist->translateZ = 0; + belt->translateX = 0; + belt->translateY = 0; + belt->translateZ = 0; + armArmor0->translateX = 0; + armArmor0->translateY = 0; + armArmor0->translateZ = 0; + armArmor1->translateX = 0; + armArmor1->translateY = 0; + armArmor1->translateZ = 0; + legging0->translateX = 0; + legging0->translateY = 0; + legging0->translateZ = 0; + legging1->translateX = 0; + legging1->translateY = 0; + legging1->translateZ = 0; + sock0->translateX = 0; + sock0->translateY = 0; + sock0->translateZ = 0; + sock1->translateX = 0; + sock1->translateY = 0; + sock1->translateZ = 0; + boot0->translateX = 0; + boot0->translateY = 0; + boot0->translateZ = 0; + boot1->translateX = 0; + boot1->translateY = 0; + boot1->translateZ = 0; + } + + if (skinOffsets != nullptr) + { + for( SKIN_OFFSET *pSkinOffset : *skinOffsets ) + { + switch (pSkinOffset->ePart) + { + case eBodyOffset_Head: + if (pSkinOffset->fD == 1 && head->translateX == 0) + { + head->translateX = pSkinOffset->fO / 16.0f; + hair->translateX = pSkinOffset->fO / 16.0f; + } + else if (pSkinOffset->fD == 2 && head->translateY == 0) + { + head->translateY = pSkinOffset->fO / 16.0f; + hair->translateY = pSkinOffset->fO / 16.0f; + } + else if (pSkinOffset->fD == 3 && head->translateZ == 0) + { + head->translateZ = pSkinOffset->fO / 16.0f; + hair->translateZ = pSkinOffset->fO / 16.0f; + } + break; + case eBodyOffset_Body: + if (pSkinOffset->fD == 1 && body->translateX == 0) + { + body->translateX = pSkinOffset->fO / 16.0f; + if (m_is64x64) + { + jacket->translateX = pSkinOffset->fO / 16.0f; + bodyArmor->translateX = pSkinOffset->fO / 16.0f; + waist->translateX = pSkinOffset->fO / 16.0f; + belt->translateX = pSkinOffset->fO / 16.0f; + } + } + else if (pSkinOffset->fD == 2 && body->translateY == 0) + { + body->translateY = pSkinOffset->fO / 16.0f; + if (m_is64x64) + { + jacket->translateY = pSkinOffset->fO / 16.0f; + bodyArmor->translateY = pSkinOffset->fO / 16.0f; + waist->translateY = pSkinOffset->fO / 16.0f; + belt->translateY = pSkinOffset->fO / 16.0f; + } + } + else if (pSkinOffset->fD == 3 && body->translateZ == 0) + { + body->translateZ = pSkinOffset->fO / 16.0f; + if (m_is64x64) + { + jacket->translateZ = pSkinOffset->fO / 16.0f; + bodyArmor->translateZ = pSkinOffset->fO / 16.0f; + waist->translateZ = pSkinOffset->fO / 16.0f; + belt->translateZ = pSkinOffset->fO / 16.0f; + } + } + break; + case eBodyOffset_Arm0: + if (pSkinOffset->fD == 1 && arm0->translateX == 0) + { + arm0->translateX = pSkinOffset->fO / 16.0f; + if (m_is64x64) + { + sleeve0->translateX = pSkinOffset->fO / 16.0f; + armArmor0->translateX = pSkinOffset->fO / 16.0f; + } + } + else if (pSkinOffset->fD == 2 && arm0->translateY == 0) + { + arm0->translateY = pSkinOffset->fO / 16.0f; + if (m_is64x64) + { + sleeve0->translateY = pSkinOffset->fO / 16.0f; + armArmor0->translateY = pSkinOffset->fO / 16.0f; + } + } + else if (pSkinOffset->fD == 3 && arm0->translateZ == 0) + { + arm0->translateZ = pSkinOffset->fO / 16.0f; + if (m_is64x64) + { + sleeve0->translateZ = pSkinOffset->fO / 16.0f; + armArmor0->translateZ = pSkinOffset->fO / 16.0f; + } + } + break; + case eBodyOffset_Arm1: + if (pSkinOffset->fD == 1 && arm1->translateX == 0) + { + arm1->translateX = pSkinOffset->fO / 16.0f; + if (m_is64x64) + { + sleeve1->translateX = pSkinOffset->fO / 16.0f; + armArmor1->translateX = pSkinOffset->fO / 16.0f; + } + } + else if (pSkinOffset->fD == 2 && arm1->translateY == 0) + { + arm1->translateY = pSkinOffset->fO / 16.0f; + if (m_is64x64) + { + sleeve1->translateY = pSkinOffset->fO / 16.0f; + armArmor1->translateY = pSkinOffset->fO / 16.0f; + } + } + else if (pSkinOffset->fD == 3 && arm1->translateZ == 0) + { + arm1->translateZ = pSkinOffset->fO / 16.0f; + if (m_is64x64) + { + sleeve1->translateZ = pSkinOffset->fO / 16.0f; + armArmor1->translateZ = pSkinOffset->fO / 16.0f; + } + } + break; + case eBodyOffset_Leg0: + if (pSkinOffset->fD == 1 && leg0->translateX == 0) + { + leg0->translateX = pSkinOffset->fO / 16.0f; + if (m_is64x64) + { + pants0->translateX = pSkinOffset->fO / 16.0f; + legging0->translateX = pSkinOffset->fO / 16.0f; + sock0->translateX = pSkinOffset->fO / 16.0f; + boot0->translateX = pSkinOffset->fO / 16.0f; + } + } + else if (pSkinOffset->fD == 2 && leg0->translateY == 0) + { + leg0->translateY = pSkinOffset->fO / 16.0f; + if (m_is64x64) + { + pants0->translateY = pSkinOffset->fO / 16.0f; + legging0->translateY = pSkinOffset->fO / 16.0f; + sock0->translateY = pSkinOffset->fO / 16.0f; + boot0->translateY = pSkinOffset->fO / 16.0f; + } + } + else if (pSkinOffset->fD == 3 && leg0->translateZ == 0) + { + leg0->translateZ = pSkinOffset->fO / 16.0f; + if (m_is64x64) + { + pants0->translateZ = pSkinOffset->fO / 16.0f; + legging0->translateZ = pSkinOffset->fO / 16.0f; + sock0->translateZ = pSkinOffset->fO / 16.0f; + boot0->translateZ = pSkinOffset->fO / 16.0f; + } + } + break; + case eBodyOffset_Leg1: + if (pSkinOffset->fD == 1 && leg1->translateX == 0) + { + leg1->translateX = pSkinOffset->fO / 16.0f; + if (m_is64x64) + { + pants1->translateX = pSkinOffset->fO / 16.0f; + legging1->translateX = pSkinOffset->fO / 16.0f; + sock1->translateX = pSkinOffset->fO / 16.0f; + boot1->translateX = pSkinOffset->fO / 16.0f; + } + } + else if (pSkinOffset->fD == 2 && leg1->translateY == 0) + { + leg1->translateY = pSkinOffset->fO / 16.0f; + if (m_is64x64) + { + pants1->translateY = pSkinOffset->fO / 16.0f; + legging1->translateY = pSkinOffset->fO / 16.0f; + sock1->translateY = pSkinOffset->fO / 16.0f; + boot1->translateY = pSkinOffset->fO / 16.0f; + } + } + else if (pSkinOffset->fD == 3 && leg1->translateZ == 0) + { + leg1->translateZ = pSkinOffset->fO / 16.0f; + if (m_is64x64) + { + pants1->translateZ = pSkinOffset->fO / 16.0f; + legging1->translateZ = pSkinOffset->fO / 16.0f; + sock1->translateZ = pSkinOffset->fO / 16.0f; + boot1->translateZ = pSkinOffset->fO / 16.0f; + } + } + break; + } + } + } + + setupAnim(time, r, bob, yRot, xRot, scale, nullptr, m_uiAnimOverrideBitmask); + + head->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<0&&(!(m_uiAnimOverrideBitmask&(1<0||!m_isArmor)); + body->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<0&&(!(m_uiAnimOverrideBitmask&(1<0||!m_isArmor)); + arm0->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<0&&(!(m_uiAnimOverrideBitmask&(1<0||!m_isArmor)); + arm1->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<0&&(!(m_uiAnimOverrideBitmask&(1<0||!m_isArmor)); + leg0->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<0&&(!(m_uiAnimOverrideBitmask&(1<0||!m_isArmor)); + leg1->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<0&&(!(m_uiAnimOverrideBitmask&(1<0||!m_isArmor)); + hair->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<0); + if (m_is64x64) + { + jacket->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<0); + sleeve0->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<0); + sleeve1->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<0); + pants0->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<0); + pants1->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<0); + waist->render(scale, usecompiled); + belt->render(scale, usecompiled); + bodyArmor->render(scale, usecompiled); + armArmor0->render(scale, usecompiled); + armArmor1->render(scale, usecompiled); + legging0->render(scale, usecompiled); + legging1->render(scale, usecompiled); + sock0->render(scale, usecompiled); + sock1->render(scale, usecompiled); + boot0->render(scale, usecompiled); + boot1->render(scale, usecompiled); } } @@ -340,9 +1134,6 @@ void HumanoidModel::setupAnim(float time, float r, float bob, float yRot, float hair->xRot = head->xRot; body->z = 0.0f; - if (jacket) - jacket->z = 0.0f; - // Does the skin have an override for anim? if(uiBitmaskOverrideAnim&(1<xRot=0.0f; arm0->zRot = 0.0f; arm1->zRot = 0.0f; - - if (sleeve0) - { - sleeve0->xRot=0.0f; - sleeve0->zRot=0.0f; - } - - if (sleeve1) - { - sleeve1->xRot=0.0f; - sleeve1->zRot=0.0f; - } } else if(uiBitmaskOverrideAnim&(1<xRot=-HALF_PI; arm0->zRot = 0.0f; arm1->zRot = 0.0f; - - if (sleeve0) - { - sleeve0->xRot=-HALF_PI; - sleeve0->zRot=0.0f; - } - - if (sleeve1) - { - sleeve1->xRot=-HALF_PI; - sleeve1->zRot=0.0f; - } } else if(uiBitmaskOverrideAnim&(1<xRot = (Mth::cos(time * 0.6662f + PI) * 2.0f) * r * 0.5f; arm0->zRot = 0.0f; arm1->zRot = 0.0f; - - if (sleeve0) - { - sleeve0->xRot=(Mth::cos(time * 0.6662f + PI) * 2.0f) * r * 0.5f; - sleeve0->zRot=0.0f; - } - - if (sleeve1) - { - sleeve1->xRot=(Mth::cos(time * 0.6662f + PI) * 2.0f) * r * 0.5f; - sleeve1->zRot=0.0f; - } } // 4J-PB - Weeping Angel - does't look good holding something in the arm that's up else if((uiBitmaskOverrideAnim&(1<zRot = -0.3f; arm1->xRot = ( Mth::cos(time * 0.6662f) * 2.0f) * r * 0.5f; arm1->zRot = 0.0f; - - if (sleeve0) - { - sleeve0->xRot=-PI; - sleeve0->zRot=-0.3f; - } - - if (sleeve1) - { - sleeve1->xRot=( Mth::cos(time * 0.6662f) * 2.0f) * r * 0.5f; - sleeve1->zRot=0.0f; - } } else { @@ -428,18 +1171,6 @@ void HumanoidModel::setupAnim(float time, float r, float bob, float yRot, float arm1->xRot = ( Mth::cos(time * 0.6662f) * 2.0f) * r * 0.5f; arm0->zRot = 0.0f; arm1->zRot = 0.0f; - - if (sleeve0) - { - sleeve0->xRot=(Mth::cos(time * 0.6662f + PI) * 2.0f) * r * 0.5f; - sleeve0->zRot=0.0f; - } - - if (sleeve1) - { - sleeve1->xRot=( Mth::cos(time * 0.6662f) * 2.0f) * r * 0.5f; - sleeve1->zRot=0.0f; - } } // arm0.zRot = ((float) (util.Mth.cos(time * 0.2312f) + 1) * 1) * r; @@ -450,12 +1181,6 @@ void HumanoidModel::setupAnim(float time, float r, float bob, float yRot, float leg0->yRot = 0.0f; leg1->yRot = 0.0f; - if (pants0) - pants0->yRot=0.0f; - - if (pants1) - pants1->yRot=0.0f; - if (riding) { if ((uiBitmaskOverrideAnim&(1<xRot = -HALF_PI * 0.8f; leg0->yRot = HALF_PI * 0.2f; leg1->yRot = -HALF_PI * 0.2f; - - if (sleeve0) - sleeve0->xRot+=-HALF_PI * 0.4f; - - if (sleeve1) - sleeve1->xRot+=-HALF_PI * 0.4f; - - if (pants0) - { - pants0->xRot=-HALF_PI * 0.8f; - pants0->yRot=HALF_PI * 0.2f; - } - - if (pants1) - { - pants1->xRot=-HALF_PI * 0.8f; - pants1->yRot=-HALF_PI * 0.2f; - } } else { @@ -491,18 +1198,6 @@ void HumanoidModel::setupAnim(float time, float r, float bob, float yRot, float arm1->xRot += -HALF_PI * 0.4f; leg0->xRot = -HALF_PI * 0.4f; leg1->xRot = -HALF_PI * 0.4f; - - if (sleeve0) - sleeve0->xRot+=-HALF_PI * 0.4f; - - if (sleeve1) - sleeve1->xRot+=-HALF_PI * 0.4f; - - if (pants0) - pants0->xRot=-HALF_PI * 0.4f; - - if (pants1) - pants1->xRot=-HALF_PI * 0.4f; } } else if(idle && !sneaking ) @@ -511,18 +1206,6 @@ void HumanoidModel::setupAnim(float time, float r, float bob, float yRot, float leg1->xRot = -HALF_PI; leg0->yRot = HALF_PI * 0.2f; leg1->yRot = -HALF_PI * 0.2f; - - if (pants0) - { - pants0->xRot=-HALF_PI; - pants0->yRot=HALF_PI * 0.2f; - } - - if (pants1) - { - pants1->xRot=-HALF_PI; - pants1->yRot=-HALF_PI * 0.2f; - } } else if(uiBitmaskOverrideAnim&(1<xRot=0.0f; leg1->zRot=0.0f; leg0->yRot = 0.0f; - leg1->yRot = 0.0f; - - if (pants0) - { - pants0->xRot=0.0f; - pants0->zRot=0.0f; - pants0->yRot=0.0f; - } - - if (pants1) - { - pants1->xRot=0.0f; - pants1->zRot=0.0f; - pants1->yRot=0.0f; - } + leg1->yRot = 0.0f; } else if(uiBitmaskOverrideAnim&(1<xRot = ( Mth::cos(time * 0.6662f) * 1.4f) * r; leg1->xRot = ( Mth::cos(time * 0.6662f) * 1.4f) * r; - - if (pants0) - pants0->xRot=( Mth::cos(time * 0.6662f) * 1.4f) * r; - - if (pants1) - pants1->xRot=( Mth::cos(time * 0.6662f) * 1.4f) * r; } else { leg0->xRot = ( Mth::cos(time * 0.6662f) * 1.4f) * r; leg1->xRot = ( Mth::cos(time * 0.6662f + PI) * 1.4f) * r; - - if (pants0) - pants0->xRot=( Mth::cos(time * 0.6662f) * 1.4f) * r; - - if (pants1) - pants1->xRot=( Mth::cos(time * 0.6662f + PI) * 1.4f) * r; } if (holdingLeftHand != 0) { arm1->xRot = arm1->xRot * 0.5f - HALF_PI * 0.2f * holdingLeftHand; - - if (sleeve1) - sleeve1->xRot=sleeve1->xRot * 0.5f - HALF_PI * 0.2f * holdingLeftHand; } if (holdingRightHand != 0) { arm0->xRot = arm0->xRot * 0.5f - HALF_PI * 0.2f * holdingRightHand; - - if (sleeve0) - sleeve0->xRot=sleeve0->xRot * 0.5f - HALF_PI * 0.2f * holdingRightHand; } arm0->yRot = 0.0f; arm1->yRot = 0.0f; - if (sleeve0) - sleeve0->yRot=0.0f; - if (sleeve1) - sleeve1->yRot=0.0f; - if (attackTime > -9990.0f) { float swing = attackTime; @@ -605,20 +1251,6 @@ void HumanoidModel::setupAnim(float time, float r, float bob, float yRot, float arm1->yRot += body->yRot; arm1->xRot += body->yRot; - if (sleeve0) - { - sleeve0->z=Mth::sin(body->yRot) * 5.0f; - sleeve0->x=-Mth::cos(body->yRot) * 5.0f; - sleeve0->yRot+=body->yRot; - } - if (sleeve1) - { - sleeve1->z=-Mth::sin(body->yRot) * 5.0f; - sleeve1->x=Mth::cos(body->yRot) * 5.0f; - sleeve1->yRot+=body->yRot; - sleeve1->xRot+=body->yRot; - } - swing = 1.0f - attackTime; swing *= swing; swing *= swing; @@ -626,27 +1258,15 @@ void HumanoidModel::setupAnim(float time, float r, float bob, float yRot, float float aa = Mth::sin(swing * PI); float bb = Mth::sin(attackTime * PI) * -(head->xRot - 0.7f) * 0.75f; arm0->xRot -= aa * 1.2f + bb; // 4J - changed 1.2 -> 1.2f - arm0->yRot += body->yRot * 2.0f; - - if (sleeve0) - { - sleeve0->xRot -= aa * 1.2f + bb; - sleeve0->yRot += body->yRot * 2.0f; - } + arm0->yRot += body->yRot * 2.0f; if((uiBitmaskOverrideAnim&(1<zRot -= Mth::sin(attackTime * PI) * -0.4f; - - if (sleeve0) - sleeve0->zRot -= Mth::sin(attackTime * PI) * -0.4f; } else { arm0->zRot = Mth::sin(attackTime * PI) * -0.4f; - - if (sleeve0) - sleeve0->zRot = Mth::sin(attackTime * PI) * -0.4f; } } @@ -662,13 +1282,6 @@ void HumanoidModel::setupAnim(float time, float r, float bob, float yRot, float arm0->xRot = - Mth::abs(Mth::cos(eating_t / 4.0f * PI) * 0.1f) * (eating_swing > 0.2 ? 1.0f : 0.0f) * 2.0f; // This factor is the chomping bit (conditional factor is so that he doesn't eat whilst the food is being pulled away at the end) arm0->yRot -= iss * 0.5f; // This factor and the following to the general arm movement through the life of the swing arm0->xRot -= iss * 1.2f; - - if (sleeve0) - { - sleeve0->xRot = -Mth::abs(Mth::cos(eating_t / 4.0f * PI) * 0.1f) * (eating_swing > 0.2 ? 1.0f : 0.0f) * 2.0f; - sleeve0->yRot -= iss * 0.5f; - sleeve0->xRot -= iss * 1.2f; - } } if (sneaking) @@ -692,39 +1305,6 @@ void HumanoidModel::setupAnim(float time, float r, float bob, float yRot, float hair->y = +1.0f; ear->y = +1.0f; cloak->y = 0.0f; - - if (jacket) - { - jacket->xRot = -0.5f; - jacket->z = 2.0f; - jacket->y = 0.0f; - } - - if (sleeve0) - { - sleeve0->xRot += 0.4f; - sleeve0->y = 2.0f; - } - - if (sleeve1) - { - sleeve1->xRot += 0.4f; - sleeve1->y = 2.0f; - } - - if (pants0) - { - pants0->xRot -= 0.0f; - pants0->z = -4.0f; - pants0->y = +9.0f; - } - - if (pants1) - { - pants1->xRot -= 0.0f; - pants1->z = -4.0f; - pants1->y = +9.0f; - } } else { @@ -744,38 +1324,6 @@ void HumanoidModel::setupAnim(float time, float r, float bob, float yRot, float hair->y = +1.0f; ear->y = +1.0f; cloak->y = 0.0f; - - if (jacket) - { - jacket->xRot = 0.5f; - jacket->y = 0.0f; - } - - if (sleeve0) - { - sleeve0->xRot += 0.4f; - sleeve0->y = 2.0f; - } - - if (sleeve1) - { - sleeve1->xRot += 0.4f; - sleeve1->y = 2.0f; - } - - if (pants0) - { - pants0->xRot -= 0.0f; - pants0->z = +4.0f; - pants0->y = +9.0f; - } - - if (pants1) - { - pants1->xRot -= 0.0f; - pants1->z = +4.0f; - pants1->y = +9.0f; - } } } else @@ -784,15 +1332,6 @@ void HumanoidModel::setupAnim(float time, float r, float bob, float yRot, float leg0->z = 0.1f; leg1->z = 0.1f; - if (jacket) - jacket->xRot = 0.0f; - - if (pants0) - pants0->z = 0.1f; - - if (pants1) - pants1->z = 0.1f; - if(!riding && idle) { leg0->y = 22.0f; @@ -804,17 +1343,6 @@ void HumanoidModel::setupAnim(float time, float r, float bob, float yRot, float hair->y = 10.0f; ear->y = 11.0f; cloak->y = 10.0f; - - if (jacket) - jacket->y = 10.0f; - if (sleeve0) - sleeve0->y = 12.0f; - if (sleeve1) - sleeve1->y = 12.0f; - if (pants0) - pants0->y = 22.0f; - if (pants1) - pants1->y = 22.0f; } else { @@ -827,17 +1355,6 @@ void HumanoidModel::setupAnim(float time, float r, float bob, float yRot, float hair->y = 0.0f; ear->y = 1.0f; cloak->y = 0.0f; - - if (jacket) - jacket->y = 0.0f; - if (sleeve0) - sleeve0->y = 2.0f; - if (sleeve1) - sleeve1->y = 2.0f; - if (pants0) - pants0->y = 12.0f; - if (pants1) - pants1->y = 12.0f; } } @@ -846,18 +1363,6 @@ void HumanoidModel::setupAnim(float time, float r, float bob, float yRot, float arm0->xRot += ((Mth::sin(bob * 0.067f)) * 0.05f); arm1->xRot -= ((Mth::sin(bob * 0.067f)) * 0.05f); - if (sleeve0) - { - sleeve0->xRot += ((Mth::sin(bob * 0.067f)) * 0.05f); - sleeve0->zRot += ((Mth::cos(bob * 0.09f)) * 0.05f + 0.05f); - } - - if (sleeve1) - { - sleeve1->xRot -= ((Mth::sin(bob * 0.067f)) * 0.05f); - sleeve1->zRot -= ((Mth::cos(bob * 0.09f)) * 0.05f + 0.05f); - } - if (bowAndArrow) { float attack2 = 0.0f; @@ -875,79 +1380,189 @@ void HumanoidModel::setupAnim(float time, float r, float bob, float yRot, float arm1->zRot -= ((float) (Mth::cos(bob * 0.09f)) * 0.05f + 0.05f); arm0->xRot += ((float) (Mth::sin(bob * 0.067f)) * 0.05f); arm1->xRot -= ((float) (Mth::sin(bob * 0.067f)) * 0.05f); + } - if (sleeve0) + if (elytraFlying) + { + if (elytraCrouching) { - sleeve0->zRot = 0.0f; - sleeve0->yRot = -(0.1f - attack2 * 0.6f) + head->yRot; - sleeve0->xRot = -HALF_PI + head->xRot; - sleeve0->xRot -= attack2 * 1.2f - attack * 0.4f; - sleeve0->zRot += ((float) (Mth::cos(bob * 0.09f)) * 0.05f + 0.05f); - sleeve0->xRot += ((float) (Mth::sin(bob * 0.067f)) * 0.05f); + arm0->xRot = PI; arm0->yRot = 0.0f; arm0->zRot = 0.0f; arm0->y = 2.0f; + arm1->xRot = 0.0f; arm1->yRot = 0.0f; arm1->zRot = 0.0f; arm1->y = 2.0f; + leg0->xRot = 0.0f; leg0->yRot = 0.0f; leg0->zRot = 0.0f; + leg1->xRot = 0.0f; leg1->yRot = 0.0f; leg1->zRot = 0.0f; + } + else + { + float elytraTime = (float)(entity->tickCount) * 0.3f; + float spd2 = (float)(entity->xd * entity->xd + entity->yd * entity->yd + entity->zd * entity->zd); + float fDamp = spd2 / 0.2f; + fDamp = fDamp * fDamp * fDamp; + if (fDamp < 1.0f) fDamp = 1.0f; + + float armAmp = 2.0f * r * 0.5f / fDamp; + float legAmp = 1.4f * r / fDamp; + + arm0->xRot = Mth::cos(elytraTime + PI) * armAmp; + arm0->yRot = 0.0f; arm0->zRot = 0.0f; arm0->y = 2.0f; + + arm1->xRot = Mth::cos(elytraTime) * armAmp; + arm1->yRot = 0.0f; arm1->zRot = 0.0f; arm1->y = 2.0f; + + leg0->xRot = Mth::cos(elytraTime) * legAmp; + leg0->yRot = 0.0f; leg0->zRot = 0.0f; + leg1->xRot = Mth::cos(elytraTime + PI) * legAmp; + leg1->yRot = 0.0f; leg1->zRot = 0.0f; } - if (sleeve1) - { - sleeve1->zRot = 0.0f; - sleeve1->yRot = +(0.1f - attack2 * 0.6f) + head->yRot + 0.4f; - sleeve1->xRot = -HALF_PI + head->xRot; - sleeve1->xRot -= attack2 * 1.2f - attack * 0.4f; - sleeve1->zRot -= ((float) (Mth::cos(bob * 0.09f)) * 0.05f + 0.05f); - sleeve1->xRot -= ((float) (Mth::sin(bob * 0.067f)) * 0.05f); - } + body->xRot = 0.0f; + body->z = 0.0f; + + + head->xRot = -(float)(PI / 4.0f); + hair->xRot = head->xRot; + } + + if (jacket != 0) + { + jacket->x = body->x; + jacket->y = body->y; + jacket->z = body->z; + jacket->xRot = body->xRot; + jacket->yRot = body->yRot; + } + if (sleeve0 != 0) + { + sleeve0->x = arm0->x; + sleeve0->y = arm0->y; + sleeve0->z = arm0->z; + sleeve0->xRot = arm0->xRot; + sleeve0->yRot = arm0->yRot; + sleeve0->zRot = arm0->zRot; + } + if (sleeve1 != 0) + { + sleeve1->x = arm1->x; + sleeve1->y = arm1->y; + sleeve1->z = arm1->z; + sleeve1->xRot = arm1->xRot; + sleeve1->yRot = arm1->yRot; + sleeve1->zRot = arm1->zRot; + } + if (pants0 != 0) + { + pants0->x = leg0->x; + pants0->y = leg0->y; + pants0->z = leg0->z; + pants0->xRot = leg0->xRot; + pants0->yRot = leg0->yRot; + pants0->zRot = leg0->zRot; + } + if (pants1 != 0) + { + pants1->x = leg1->x; + pants1->y = leg1->y; + pants1->z = leg1->z; + pants1->xRot = leg1->xRot; + pants1->yRot = leg1->yRot; + pants1->zRot = leg1->zRot; + } + if (waist != 0) + { + waist->x = body->x; + waist->y = body->y; + waist->z = body->z; + waist->xRot = body->xRot; + waist->yRot = body->yRot; + } + if (belt != 0) + { + belt->x = body->x; + belt->y = body->y; + belt->z = body->z; + belt->xRot = body->xRot; + belt->yRot = body->yRot; + } + if (bodyArmor != 0) + { + bodyArmor->x = body->x; + bodyArmor->y = body->y; + bodyArmor->z = body->z; + bodyArmor->xRot = body->xRot; + bodyArmor->yRot = body->yRot; + } + if (armArmor0 != 0) + { + armArmor0->x = arm0->x; + armArmor0->y = arm0->y; + armArmor0->z = arm0->z; + armArmor0->xRot = arm0->xRot; + armArmor0->yRot = arm0->yRot; + armArmor0->zRot = arm0->zRot; + } + if (armArmor1 != 0) + { + armArmor1->x = arm1->x; + armArmor1->y = arm1->y; + armArmor1->z = arm1->z; + armArmor1->xRot = arm1->xRot; + armArmor1->yRot = arm1->yRot; + armArmor1->zRot = arm1->zRot; + } + if (legging0 != 0) + { + legging0->x = leg0->x; + legging0->y = leg0->y; + legging0->z = leg0->z; + legging0->xRot = leg0->xRot; + legging0->yRot = leg0->yRot; + legging0->zRot = leg0->zRot; + } + if (legging1 != 0) + { + legging1->x = leg1->x; + legging1->y = leg1->y; + legging1->z = leg1->z; + legging1->xRot = leg1->xRot; + legging1->yRot = leg1->yRot; + legging1->zRot = leg1->zRot; + } + if (sock0 != 0) + { + sock0->x = leg0->x; + sock0->y = leg0->y; + sock0->z = leg0->z; + sock0->xRot = leg0->xRot; + sock0->yRot = leg0->yRot; + sock0->zRot = leg0->zRot; + } + if (sock1 != 0) + { + sock1->x = leg1->x; + sock1->y = leg1->y; + sock1->z = leg1->z; + sock1->xRot = leg1->xRot; + sock1->yRot = leg1->yRot; + sock1->zRot = leg1->zRot; + } + if (boot0 != 0) + { + boot0->x = leg0->x; + boot0->y = leg0->y; + boot0->z = leg0->z; + boot0->xRot = leg0->xRot; + boot0->yRot = leg0->yRot; + boot0->zRot = leg0->zRot; + } + if (boot1 != 0) + { + boot1->x = leg1->x; + boot1->y = leg1->y; + boot1->z = leg1->z; + boot1->xRot = leg1->xRot; + boot1->yRot = leg1->yRot; + boot1->zRot = leg1->zRot; } } - - if (elytraFlying) - { - if (elytraCrouching) - { - arm0->xRot = PI; arm0->yRot = 0.0f; arm0->zRot = 0.0f; arm0->y = 2.0f; - if (sleeve0) { sleeve0->xRot = PI; sleeve0->yRot = 0.0f; sleeve0->zRot = 0.0f; sleeve0->y = 2.0f; } - - arm1->xRot = 0.0f; arm1->yRot = 0.0f; arm1->zRot = 0.0f; arm1->y = 2.0f; - if (sleeve1) { sleeve1->xRot = 0.0f; sleeve1->yRot = 0.0f; sleeve1->zRot = 0.0f; sleeve1->y = 2.0f; } - - leg0->xRot = 0.0f; leg0->yRot = 0.0f; leg0->zRot = 0.0f; - leg1->xRot = 0.0f; leg1->yRot = 0.0f; leg1->zRot = 0.0f; - if (pants0) { pants0->xRot = 0.0f; pants0->yRot = 0.0f; pants0->zRot = 0.0f; } - if (pants1) { pants1->xRot = 0.0f; pants1->yRot = 0.0f; pants1->zRot = 0.0f; } - } - else - { - float elytraTime = (float)(entity->tickCount) * 0.3f; - float spd2 = (float)(entity->xd * entity->xd + entity->yd * entity->yd + entity->zd * entity->zd); - float fDamp = spd2 / 0.2f; - fDamp = fDamp * fDamp * fDamp; - if (fDamp < 1.0f) fDamp = 1.0f; - - float armAmp = 2.0f * r * 0.5f / fDamp; - float legAmp = 1.4f * r / fDamp; - - arm0->xRot = Mth::cos(elytraTime + PI) * armAmp; - arm0->yRot = 0.0f; arm0->zRot = 0.0f; arm0->y = 2.0f; - if (sleeve0) { sleeve0->xRot = arm0->xRot; sleeve0->yRot = 0.0f; sleeve0->zRot = 0.0f; sleeve0->y = 2.0f; } - - arm1->xRot = Mth::cos(elytraTime) * armAmp; - arm1->yRot = 0.0f; arm1->zRot = 0.0f; arm1->y = 2.0f; - if (sleeve1) { sleeve1->xRot = arm1->xRot; sleeve1->yRot = 0.0f; sleeve1->zRot = 0.0f; sleeve1->y = 2.0f; } - - leg0->xRot = Mth::cos(elytraTime) * legAmp; - leg0->yRot = 0.0f; leg0->zRot = 0.0f; - leg1->xRot = Mth::cos(elytraTime + PI) * legAmp; - leg1->yRot = 0.0f; leg1->zRot = 0.0f; - if (pants0) { pants0->xRot = leg0->xRot; pants0->yRot = 0.0f; pants0->zRot = 0.0f; } - if (pants1) { pants1->xRot = leg1->xRot; pants1->yRot = 0.0f; pants1->zRot = 0.0f; } - } - - body->xRot = 0.0f; - body->z = 0.0f; - - - head->xRot = -(float)(PI / 4.0f); - hair->xRot = head->xRot; - } - } void HumanoidModel::renderHair(float scale,bool usecompiled) diff --git a/Minecraft.Client/HumanoidModel.h b/Minecraft.Client/HumanoidModel.h index 4c7f95f5..8980be15 100644 --- a/Minecraft.Client/HumanoidModel.h +++ b/Minecraft.Client/HumanoidModel.h @@ -1,9 +1,11 @@ #pragma once #include "Model.h" +#include "SkinOffset.h" class HumanoidModel : public Model { public: ModelPart* head, * hair, * body, * jacket, * arm0, * sleeve0, * arm1, * sleeve1, * leg0, * pants0, * leg1, * pants1, * ear, * cloak; + ModelPart* waist, * belt, * bodyArmor, * armArmor0, * armArmor1, * legging0, * legging1, * sock0, * sock1, * boot0, * boot1; ModelPart* elytraLeft, * elytraRight; int holdingLeftHand; int holdingRightHand; @@ -15,6 +17,8 @@ public: float eating_swing; bool elytraFlying; bool elytraCrouching; + bool m_isArmor; + bool m_is64x64; unsigned int m_uiAnimOverrideBitmask; float m_fYOffset; enum animbits @@ -37,11 +41,20 @@ public: eAnim_DisableRenderLeg1, eAnim_DisableRenderHair, eAnim_SmallModel, - eAnim_DisableRenderJacket, - eAnim_DisableRenderSleeve0, - eAnim_DisableRenderSleeve1, - eAnim_DisableRenderPants0, - eAnim_DisableRenderPants1 + eAnim_WideModel, + eAnim_SlimModel, + eAnim_DisableRenderSleeve1, + eAnim_DisableRenderSleeve0, + eAnim_DisableRenderPants1, + eAnim_DisableRenderPants0, + eAnim_DisableRenderJacket, + eAnim_RenderArmorHead, + eAnim_RenderArmorArm0, + eAnim_RenderArmorArm1, + eAnim_RenderArmorTorso, + eAnim_RenderArmorLeg0, + eAnim_RenderArmorLeg1, + eAnim_Dinnerbone }; @@ -59,22 +72,17 @@ public: (1 << HumanoidModel::eAnim_DisableRenderPants0) | (1 << HumanoidModel::eAnim_DisableRenderPants1); - void _init(float g, float yOffset, int texWidth, int texHeight, - bool slimHands, bool mirror, bool force32); + void _init(float g, float yOffset, int texWidth, int texHeight, bool slim, bool isArmor); HumanoidModel(); HumanoidModel(float g); + HumanoidModel(float g, bool isArmor); HumanoidModel(float g, float yOffset, int texWidth, int texHeight); - HumanoidModel(float g, float yOffset, int texWidth, int texHeight, bool slimHands); - HumanoidModel(float g, float yOffset, int texWidth, int texHeight, bool slimHands, bool mirror); - HumanoidModel(float g, float yOffset, int texWidth, int texHeight, bool slimHands, bool mirror, bool force32); - - virtual void render(shared_ptr entity, float time, float r, float bob, - float yRot, float xRot, float scale, bool usecompiled); - virtual void setupAnim(float time, float r, float bob, float yRot, float xRot, - float scale, shared_ptr entity, - unsigned int uiBitmaskOverrideAnim = 0); + HumanoidModel(float g, float yOffset, int texWidth, int texHeight, bool slim); + virtual void render(shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled); + virtual void renderUI(float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled, vector *skinOffsets); + virtual void setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, shared_ptr entity, unsigned int uiBitmaskOverrideAnim = 0); void renderHair(float scale, bool usecompiled); void renderEars(float scale, bool usecompiled); void renderCloak(float scale, bool usecompiled); diff --git a/Minecraft.Client/ItemInHandRenderer.cpp b/Minecraft.Client/ItemInHandRenderer.cpp index d7740072..8bd5ca99 100644 --- a/Minecraft.Client/ItemInHandRenderer.cpp +++ b/Minecraft.Client/ItemInHandRenderer.cpp @@ -404,8 +404,8 @@ void ItemInHandRenderer::renderItem3D(Tesselator *t, float u0, float v0, float u void ItemInHandRenderer::render(float a) { - float h = oHeight + (height - oHeight) * a; - shared_ptr player = minecraft->player; + float h = oHeight + (height - oHeight) * a; + shared_ptr player = minecraft->player; if (player == nullptr) { @@ -907,8 +907,8 @@ void ItemInHandRenderer::renderFire(float a) unsigned int col = Minecraft::GetInstance()->getColourTable()->getColor( eMinecraftColour_Fire_Overlay ); float aCol = ( (col>>24)&0xFF )/255.0f; float rCol = ( (col>>16)&0xFF )/255.0f; - float gCol = ( (col>>8)&0xFF )/255.0; - float bCol = ( col&0xFF )/255.0; + float gCol = ( (col>>8)&0xFF )/255.0f; + float bCol = ( col&0xFF )/255.0f; glColor4f(rCol, gCol, bCol, aCol); glEnable(GL_BLEND); diff --git a/Minecraft.Client/LivingEntityRenderer.cpp b/Minecraft.Client/LivingEntityRenderer.cpp index eac8ac0d..dc57af19 100644 --- a/Minecraft.Client/LivingEntityRenderer.cpp +++ b/Minecraft.Client/LivingEntityRenderer.cpp @@ -8,29 +8,23 @@ #include "../Minecraft.World/Arrow.h" #include "../Minecraft.World/Mth.h" #include "../Minecraft.World/Player.h" -#include "Skins.h" - ResourceLocation LivingEntityRenderer::ENCHANT_GLINT_LOCATION = ResourceLocation(TN__BLUR__MISC_GLINT); int LivingEntityRenderer::MAX_ARMOR_LAYERS = 4; -LivingEntityRenderer::LivingEntityRenderer(Model *model, float shadow, bool slimHands, bool createNewVar) +LivingEntityRenderer::LivingEntityRenderer(Model *model, float shadow, bool isPlayer) { this->model = model; - if (slimHands == true) - this->modelSlim = new HumanoidModel(0, 0, 64, 32, true); - - if (createNewVar) + if (isPlayer) { - this->newModel = new HumanoidModel(0, 0, 64, 64, false, false); - - if (slimHands == true) - this->newModelSlim = new HumanoidModel(0, 0, 64, 64, true, false); + this->modelWide = new HumanoidModel(0, 0, 64, 64); + this->modelSlim = new HumanoidModel(0, 0, 64, 64, true); } shadowRadius = shadow; armor = nullptr; + resModel = model; } void LivingEntityRenderer::setArmor(Model *armor) @@ -38,6 +32,11 @@ void LivingEntityRenderer::setArmor(Model *armor) this->armor = armor; } +void LivingEntityRenderer::setPlayerModelType(Model *humanoidModel) +{ + resModel = humanoidModel; +} + float LivingEntityRenderer::rotlerp(float from, float to, float a) { float diff = to - from; @@ -56,8 +55,6 @@ void LivingEntityRenderer::render(shared_ptr _mob, double x, double y, d } shared_ptr mob = dynamic_pointer_cast(_mob); - shared_ptr player = dynamic_pointer_cast(_mob); - Model *resModel = static_cast(model); if (mob == nullptr) { @@ -67,30 +64,6 @@ void LivingEntityRenderer::render(shared_ptr _mob, double x, double y, d glPushMatrix(); glDisable(GL_CULL_FACE); - if (player != nullptr) - { - Textures *textures = Minecraft::GetInstance()->textures; - int skinId = player->getPlayerDefaultSkin() - 1; - int defaultSkin = player->getPlayerDefaultSkin() + 35; - - if (slim[skinId] == true) - { - if (textures->getHeight(player->customTextureUrl, defaultSkin) == 64) - resModel = static_cast(newModelSlim); - else - resModel = static_cast(modelSlim); - } - else - { - if (textures->getHeight(player->customTextureUrl, defaultSkin) == 64) - resModel = static_cast(newModel); - else - resModel = static_cast(model); - } - } - else - resModel = static_cast(model); - resModel->attackTime = getAttackAnim(mob, a); if (armor != nullptr) armor->attackTime = resModel->attackTime; resModel->riding = mob->isRiding(); @@ -283,33 +256,6 @@ void LivingEntityRenderer::render(shared_ptr _mob, double x, double y, d void LivingEntityRenderer::renderModel(shared_ptr mob, float wp, float ws, float bob, float headRotMinusBodyRot, float headRotx, float scale) { - shared_ptr player = dynamic_pointer_cast(mob); - Model *resModel = static_cast(model); - - if (player != nullptr) - { - Textures *textures = Minecraft::GetInstance()->textures; - int skinId = player->getPlayerDefaultSkin() - 1; - int defaultSkin = player->getPlayerDefaultSkin() + 35; - - if (slim[skinId] == true) - { - if (textures->getHeight(player->customTextureUrl, defaultSkin) == 64) - resModel = static_cast(newModelSlim); - else - resModel = static_cast(modelSlim); - } - else - { - if (textures->getHeight(player->customTextureUrl, defaultSkin) == 64) - resModel = static_cast(newModel); - else - resModel = static_cast(model); - } - } - else - resModel = static_cast(model); - bindTexture(mob); if (!mob->isInvisible()) { @@ -353,7 +299,7 @@ void LivingEntityRenderer::setupRotations(shared_ptr mob, float bo else { wstring name = mob->getAName(); - if (name == L"Dinnerbone" || name == L"Grumm") + if (name == L"Dinnerbone" || name == L"Grumm" || mob->getAnimOverrideBitmask() & (1 << HumanoidModel::eAnim_Dinnerbone)) { if ( !mob->instanceof(eTYPE_PLAYER) || !dynamic_pointer_cast(mob)->isCapeHidden() ) { @@ -381,33 +327,6 @@ void LivingEntityRenderer::additionalRendering(shared_ptr mob, flo void LivingEntityRenderer::renderArrows(shared_ptr mob, float a) { - shared_ptr player = dynamic_pointer_cast(mob); - Model *resModel = static_cast(model); - - if (player != nullptr) - { - Textures *textures = Minecraft::GetInstance()->textures; - int skinId = player->getPlayerDefaultSkin() - 1; - int defaultSkin = player->getPlayerDefaultSkin() + 35; - - if (slim[skinId] == true) - { - if (textures->getHeight(player->customTextureUrl, defaultSkin) == 64) - resModel = static_cast(newModelSlim); - else - resModel = static_cast(modelSlim); - } - else - { - if (textures->getHeight(player->customTextureUrl, defaultSkin) == 64) - resModel = static_cast(newModel); - else - resModel = static_cast(model); - } - } - else - resModel = static_cast(model); - int arrowCount = mob->getArrowCount(); if (arrowCount > 0) diff --git a/Minecraft.Client/LivingEntityRenderer.h b/Minecraft.Client/LivingEntityRenderer.h index ba2aa330..5c564e37 100644 --- a/Minecraft.Client/LivingEntityRenderer.h +++ b/Minecraft.Client/LivingEntityRenderer.h @@ -17,11 +17,13 @@ class LivingEntityRenderer : public EntityRenderer protected: //Model *model; // 4J Stu - This shadows the one in EntityRenderer Model *armor; + Model *resModel; public: - LivingEntityRenderer(Model *model, float shadow, bool slimHands = 0, bool createNewVar = 0); + LivingEntityRenderer(Model *model, float shadow, bool isPlayer = false); virtual void render(shared_ptr mob, double x, double y, double z, float rot, float a); virtual void setArmor(Model *armor); + virtual void setPlayerModelType(Model *humanoidModel); private: float rotlerp(float from, float to, float a); diff --git a/Minecraft.Client/ModelPart.cpp b/Minecraft.Client/ModelPart.cpp index 07d3bc17..6a85df5c 100644 --- a/Minecraft.Client/ModelPart.cpp +++ b/Minecraft.Client/ModelPart.cpp @@ -14,6 +14,8 @@ void ModelPart::_init() bMirror = false; visible = true; neverRender = false; + hideWithArmor = 0L; + isArmorPart2 = false; x=y=z = 0.0f; xRot=yRot=zRot = 0.0f; translateX = translateY = translateZ = 0.0f; diff --git a/Minecraft.Client/ModelPart.h b/Minecraft.Client/ModelPart.h index 61e26ab9..0633e443 100644 --- a/Minecraft.Client/ModelPart.h +++ b/Minecraft.Client/ModelPart.h @@ -17,6 +17,8 @@ public: bool bMirror; bool visible; bool neverRender; + unsigned int hideWithArmor; + bool isArmorPart2; vector cubes; vector children; static const float RAD; diff --git a/Minecraft.Client/PlayerConnection.cpp b/Minecraft.Client/PlayerConnection.cpp index 79c3e185..327738e1 100644 --- a/Minecraft.Client/PlayerConnection.cpp +++ b/Minecraft.Client/PlayerConnection.cpp @@ -1651,9 +1651,10 @@ void PlayerConnection::handleTextureAndGeometry(shared_ptr *pvSkinBoxes = app.GetAdditionalSkinBoxes(packet->dwSkinID); + vector *pvSkinOffsets = app.GetSkinOffsets(packet->dwSkinID); unsigned int uiAnimOverrideBitmask= app.GetAnimOverrideBitmask(packet->dwSkinID); - send(std::make_shared(packet->textureName, pbData, dwTextureBytes, pvSkinBoxes, uiAnimOverrideBitmask)); + send(std::make_shared(packet->textureName, pbData, dwTextureBytes, pvSkinBoxes, pvSkinOffsets, uiAnimOverrideBitmask)); } } else @@ -1676,6 +1677,13 @@ void PlayerConnection::handleTextureAndGeometry(shared_ptrdwSkinID,packet->dwBoxC); #endif app.SetAdditionalSkinBoxes(packet->dwSkinID,packet->BoxDataA,packet->dwBoxC); + }// add the offsets to the app list + if(packet->dwOffsetC!=0) + { +#ifndef _CONTENT_PACKAGE + wprintf(L"Adding skin offsets for skin id %X, offset count %d\n",packet->dwSkinID,packet->dwOffsetC); +#endif + app.SetSkinOffsets(packet->dwSkinID,packet->OffsetDataA,packet->dwOffsetC); } // Add the anim override app.SetAnimOverrideBitmask(packet->dwSkinID,packet->uiAnimOverrideBitmask); @@ -1726,9 +1734,10 @@ void PlayerConnection::handleTextureAndGeometryReceived(const wstring &textureNa // get the data from the app DWORD dwSkinID = app.getSkinIdFromPath(textureName); vector *pvSkinBoxes = app.GetAdditionalSkinBoxes(dwSkinID); + vector *pvSkinOffsets = app.GetSkinOffsets(dwSkinID); unsigned int uiAnimOverrideBitmask= app.GetAnimOverrideBitmask(dwSkinID); - send(std::make_shared(textureName, pbData, dwTextureBytes, pvSkinBoxes, uiAnimOverrideBitmask)); + send(std::make_shared(textureName, pbData, dwTextureBytes, pvSkinBoxes, pvSkinOffsets, uiAnimOverrideBitmask)); } m_texturesRequested.erase(it); } diff --git a/Minecraft.Client/PlayerRenderer.cpp b/Minecraft.Client/PlayerRenderer.cpp index 8ff3bf85..dfd041fd 100644 --- a/Minecraft.Client/PlayerRenderer.cpp +++ b/Minecraft.Client/PlayerRenderer.cpp @@ -16,7 +16,6 @@ #include "../Minecraft.World/StringHelpers.h" #include "SkeletonHeadModel.h" #include "Textures.h" -#include "Skins.h" ResourceLocation PlayerRenderer::SKELETON_LOCATION = ResourceLocation(TN_MOB_SKELETON); ResourceLocation PlayerRenderer::WITHER_SKELETON_LOCATION = ResourceLocation(TN_MOB_WITHER_SKELETON); @@ -64,16 +63,26 @@ static unsigned int nametagColorForIndex(int index) ResourceLocation PlayerRenderer::DEFAULT_LOCATION = ResourceLocation(TN_MOB_CHAR); -PlayerRenderer::PlayerRenderer() : LivingEntityRenderer(new HumanoidModel(0), 0.5f, true, true) +PlayerRenderer::PlayerRenderer() : LivingEntityRenderer(new HumanoidModel(0), 0.5f, true) { humanoidModel = static_cast(model); + humanoidModelWide = static_cast(modelWide); humanoidModelSlim = static_cast(modelSlim); - newHumanoidModel = static_cast(newModel); - newHumanoidModelSlim = static_cast(newModelSlim); + resModel = humanoidModel; - armorParts1 = new HumanoidModel(1.0f); - armorParts2 = new HumanoidModel(0.5f); - armorParts3 = new HumanoidModel(0.5f); + armorParts1 = new HumanoidModel(1.0f, true); + armorParts2 = new HumanoidModel(0.5f, true); + armorParts3 = new HumanoidModel(0.5f, true); +} + +void PlayerRenderer::setModelType(shared_ptr player) +{ + if (Player::GetModelTypeFromTextureId(player->getCustomSkin()) == 2 || Player::GetModelTypeFromAnimBitmask(player->getAnimOverrideBitmask()) == 2) + resModel = humanoidModelSlim; + else if (Player::GetModelTypeFromTextureId(player->getCustomSkin()) == 1 || Player::GetModelTypeFromAnimBitmask(player->getAnimOverrideBitmask()) == 1) + resModel = humanoidModelWide; + else + resModel = humanoidModel; } unsigned int PlayerRenderer::getNametagColour(int index) @@ -115,10 +124,14 @@ int PlayerRenderer::prepareArmor(shared_ptr _player, int layer, fl armor->leg0->visible = layer == 2 || layer == 3; armor->leg1->visible = layer == 2 || layer == 3; + armor->body->isArmorPart2 = layer == 2; + armor->leg0->isArmorPart2 = layer == 2; + armor->leg1->isArmorPart2 = layer == 2; + setArmor(armor); - if (armor != nullptr) armor->attackTime = model->attackTime; - if (armor != nullptr) armor->riding = model->riding; - if (armor != nullptr) armor->young = model->young; + if (armor != nullptr) armor->attackTime = resModel->attackTime; + if (armor != nullptr) armor->riding = resModel->riding; + if (armor != nullptr) armor->young = resModel->young; float brightness = SharedConstants::TEXTURE_LIGHTING ? 1 : player->getBrightness(a); if (armorItem->getMaterial() == ArmorItem::ArmorMaterial::CLOTH) @@ -221,38 +234,12 @@ void PlayerRenderer::render(shared_ptr _mob, double x, double y, double // 4J - dynamic cast required because we aren't using templates/generics in our version shared_ptr mob = dynamic_pointer_cast(_mob); - HumanoidModel* resModel = static_cast(model); if (mob == nullptr) return; if (mob->hasInvisiblePrivilege()) return; - if (mob != nullptr) - { - Textures* textures = Minecraft::GetInstance()->textures; - int skinId = mob->getPlayerDefaultSkin() - 1; - int defaultSkin = mob->getPlayerDefaultSkin() + 35; - - if (slim[skinId] == true) - { - if (textures->getHeight(mob->customTextureUrl, defaultSkin) == 64) - resModel = static_cast(newHumanoidModelSlim); - else - resModel = static_cast(humanoidModelSlim); - } - else - { - if (textures->getHeight(mob->customTextureUrl, defaultSkin) == 64) - resModel = static_cast(newHumanoidModel); - else - resModel = static_cast(humanoidModel); - } - } - else - resModel = static_cast(model); - - /*if (mob != nullptr && newHumanoidModelSlim != nullptr && (mob->getCustomSkin() >= 10 && mob->getCustomSkin() <= 18)) resModel = newHumanoidModelSlim; - else if (mob != nullptr && newHumanoidModel != nullptr && (mob->getCustomSkin() >= 2 && mob->getCustomSkin() <= 9)) resModel = newHumanoidModel; - else resModel = humanoidModel;*/ + setModelType(mob); + setPlayerModelType(resModel); shared_ptr item = mob->inventory->getSelected(); @@ -341,6 +328,12 @@ void PlayerRenderer::render(shared_ptr _mob, double x, double y, double armorParts2->idle = false; } + // Get armor in armor slot so we can hide the armor layer of the skin - Langtanium + shared_ptr itemHelmet = mob->inventory->getArmor(3); + shared_ptr itemChestplate = mob->inventory->getArmor(2); + shared_ptr itemLeggings = mob->inventory->getArmor(1); + shared_ptr itemBoots = mob->inventory->getArmor(0); + // 4J-PB - any additional parts to turn on for this player (skin dependent) vector* pAdditionalModelParts = mob->GetAdditionalModelParts(); //turn them on @@ -348,7 +341,16 @@ void PlayerRenderer::render(shared_ptr _mob, double x, double y, double { for (ModelPart* pModelPart : *pAdditionalModelParts) { - pModelPart->visible = true; + if (itemHelmet != nullptr && pModelPart->hideWithArmor & (1 << 0)) // Hide the skin boxes that have the "hide when helmet is worn" bit flag - Langtanium + pModelPart->visible = false; + else if (itemChestplate != nullptr && pModelPart->hideWithArmor & (1 << 1)) // Hide the skin boxes that have the "hide when chestplate is worn" bit flag - Langtanium + pModelPart->visible = false; + else if (itemLeggings != nullptr && pModelPart->hideWithArmor & (1 << 2)) // Hide the skin boxes that have the "hide when leggings are worn" bit flag - Langtanium + pModelPart->visible = false; + else if (itemBoots != nullptr && pModelPart->hideWithArmor & (1 << 3)) // Hide the skin boxes that have the "hide when boots are worn" bit flag - Langtanium + pModelPart->visible = false; + else + pModelPart->visible = true; } } @@ -379,35 +381,6 @@ void PlayerRenderer::additionalRendering(shared_ptr _mob, float a) // 4J - dynamic cast required because we aren't using templates/generics in our version shared_ptr mob = dynamic_pointer_cast(_mob); - HumanoidModel* resModel = static_cast(model); - - if (mob != nullptr) - { - Textures* textures = Minecraft::GetInstance()->textures; - int skinId = mob->getPlayerDefaultSkin() - 1; - int defaultSkin = mob->getPlayerDefaultSkin() + 35; - - if (slim[skinId] == true) - { - if (textures->getHeight(mob->customTextureUrl, defaultSkin) == 64) - resModel = static_cast(newHumanoidModelSlim); - else - resModel = static_cast(humanoidModelSlim); - } - else - { - if (textures->getHeight(mob->customTextureUrl, defaultSkin) == 64) - resModel = static_cast(newHumanoidModel); - else - resModel = static_cast(humanoidModel); - } - } - else - resModel = static_cast(model); - - /*if (mob != nullptr && newHumanoidModelSlim != nullptr && (mob->getCustomSkin() >= 10 && mob->getCustomSkin() <= 18)) resModel = newHumanoidModelSlim; - else if (mob != nullptr && newHumanoidModel != nullptr && (mob->getCustomSkin() >= 2 && mob->getCustomSkin() <= 9)) resModel = newHumanoidModel; - else resModel = humanoidModel;*/ shared_ptr headGear = mob->inventory->getArmor(3); if (headGear != nullptr) @@ -510,7 +483,7 @@ void PlayerRenderer::additionalRendering(shared_ptr _mob, float a) glRotatef(lean2 / 2, 0, 0, 1); glRotatef(-lean2 / 2, 0, 1, 0); glRotatef(180, 0, 1, 0); - resModel->renderCloak(1 / 16.0f, true); + humanoidModel->renderCloak(1 / 16.0f, true); glPopMatrix(); } @@ -741,35 +714,7 @@ void PlayerRenderer::scale(shared_ptr player, float a) void PlayerRenderer::renderHand() { shared_ptr player = dynamic_pointer_cast(Minecraft::GetInstance()->player); - HumanoidModel* resModel = static_cast(model); - - if (player != nullptr) - { - Textures* textures = Minecraft::GetInstance()->textures; - int skinId = player->getPlayerDefaultSkin() - 1; - int defaultSkin = player->getPlayerDefaultSkin() + 35; - - if (slim[skinId] == true) - { - if (textures->getHeight(player->customTextureUrl, defaultSkin) == 64) - resModel = static_cast(newHumanoidModelSlim); - else - resModel = static_cast(humanoidModelSlim); - } - else - { - if (textures->getHeight(player->customTextureUrl, defaultSkin) == 64) - resModel = static_cast(newHumanoidModel); - else - resModel = static_cast(humanoidModel); - } - } - else - resModel = static_cast(model); - - /*if (player != nullptr && newHumanoidModelSlim != nullptr && (player->getCustomSkin() >= 10 && player->getCustomSkin() <= 18)) resModel = newHumanoidModelSlim; - else if (player != nullptr && newHumanoidModel != nullptr && (player->getCustomSkin() >= 2 && player->getCustomSkin() <= 9)) resModel = newHumanoidModel; - else resModel = humanoidModel;*/ + setModelType(player); float brightness = 1; glColor3f(brightness, brightness, brightness); @@ -781,9 +726,12 @@ void PlayerRenderer::renderHand() // 4J-PB - does this skin have its arm0 disabled? (Dalek, etc) if ((resModel->m_uiAnimOverrideBitmask & (1 << HumanoidModel::eAnim_DisableRenderArm0)) == 0) resModel->arm0->render(1 / 16.0f, true); + // Does this skin have its sleeve0 disabled? + if ((resModel->m_uiAnimOverrideBitmask & (1 << HumanoidModel::eAnim_DisableRenderSleeve0)) == 0 && resModel->sleeve0 != nullptr) + resModel->sleeve0->render(1 / 16.0f, true); //Render custom skin boxes on viewmodel - Botch - vector* additionalModelParts = Minecraft::GetInstance()->player->GetAdditionalModelParts(); + vector* additionalModelParts = player->GetAdditionalModelParts(); if (!additionalModelParts) return; //If there are no custom boxes, return. This fixes bug where the game will crash if you select a skin with no additional boxes. vector armchildren = resModel->arm0->children; std::unordered_set additionalModelPartSet(additionalModelParts->begin(), additionalModelParts->end()); @@ -801,6 +749,25 @@ void PlayerRenderer::renderHand() } } } + //Render custom skin boxes on viewmodel for sleeve0 + if (resModel->sleeve0!=nullptr) + { + vector sleevechildren = resModel->sleeve0->children; + for (const auto& x : sleevechildren) { + if (x) { + if (additionalModelPartSet.find(x) != additionalModelPartSet.end()) { //This is to verify box is still actually on current skin + glPushMatrix(); + //We need to transform to match offset of arm/sleeve + glTranslatef(-5 * 0.0625f, 2 * 0.0625f, 0); + glRotatef(0.1 * (180.0f / PI), 0, 0, 1); + x->visible = true; + x->render(1.0f / 16.0f, true); + x->visible = false; + glPopMatrix(); + } + } + } + } } void PlayerRenderer::setupPosition(shared_ptr _mob, double x, double y, double z) @@ -857,7 +824,7 @@ void PlayerRenderer::setupRotations(shared_ptr _mob, float bob, fl } } - else + else { LivingEntityRenderer::setupRotations(mob, bob, bodyRot, a); } diff --git a/Minecraft.Client/PlayerRenderer.h b/Minecraft.Client/PlayerRenderer.h index 8accdc7f..fb655ec7 100644 --- a/Minecraft.Client/PlayerRenderer.h +++ b/Minecraft.Client/PlayerRenderer.h @@ -14,9 +14,9 @@ public: private: HumanoidModel *humanoidModel; + HumanoidModel *humanoidModelWide; HumanoidModel *humanoidModelSlim; - HumanoidModel *newHumanoidModel; - HumanoidModel *newHumanoidModelSlim; + HumanoidModel *resModel; HumanoidModel *armorParts1; HumanoidModel *armorParts2; @@ -38,6 +38,7 @@ private: static const wstring MATERIAL_NAMES[5]; protected: + virtual void setModelType(shared_ptr player); virtual int prepareArmor(shared_ptr _player, int layer, float a); virtual void prepareSecondPassArmor(shared_ptr mob, int layer, float a); diff --git a/Minecraft.Client/SkinBox.h b/Minecraft.Client/SkinBox.h index b4600f1d..d82a790d 100644 --- a/Minecraft.Client/SkinBox.h +++ b/Minecraft.Client/SkinBox.h @@ -9,16 +9,28 @@ enum eBodyPart eBodyPart_Arm1, eBodyPart_Leg0, eBodyPart_Leg1, + eBodyPart_Headwear, eBodyPart_Jacket, eBodyPart_Sleeve0, eBodyPart_Sleeve1, eBodyPart_Pants0, eBodyPart_Pants1, + eBodyPart_Waist, + eBodyPart_Legging0, + eBodyPart_Legging1, + eBodyPart_Sock0, + eBodyPart_Sock1, + eBodyPart_Boot0, + eBodyPart_Boot1, + eBodyPart_ArmArmor0, + eBodyPart_ArmArmor1, + eBodyPart_BodyArmor, + eBodyPart_Belt }; typedef struct { eBodyPart ePart; - float fX,fY,fZ,fW,fH,fD,fU,fV; + float fX,fY,fZ,fW,fH,fD,fU,fV,fA,fM,fS; } SKIN_BOX; diff --git a/Minecraft.Client/SkinOffset.h b/Minecraft.Client/SkinOffset.h new file mode 100644 index 00000000..79d39cac --- /dev/null +++ b/Minecraft.Client/SkinOffset.h @@ -0,0 +1,48 @@ +#pragma once + +enum eBodyOffset +{ + eBodyOffset_Unknown=0, + eBodyOffset_Head, + eBodyOffset_Body, + eBodyOffset_Arm0, + eBodyOffset_Arm1, + eBodyOffset_Leg0, + eBodyOffset_Leg1, + eBodyOffset_Headwear, + eBodyOffset_Jacket, + eBodyOffset_Sleeve0, + eBodyOffset_Sleeve1, + eBodyOffset_Pants0, + eBodyOffset_Pants1, + eBodyOffset_Helmet, + eBodyOffset_Waist, + eBodyOffset_Legging0, + eBodyOffset_Legging1, + eBodyOffset_Sock0, + eBodyOffset_Sock1, + eBodyOffset_Boot0, + eBodyOffset_Boot1, + eBodyOffset_ArmArmor1, + eBodyOffset_ArmArmor0, + eBodyOffset_BodyArmor, + eBodyOffset_Belt, + eBodyOffset_Tool0, + eBodyOffset_Tool1 + +}; + +enum eOffsetDirection +{ + eOffsetDirection_Unknown=0, + eOffsetDirection_X, + eOffsetDirection_Y, + eOffsetDirection_Z +}; + +typedef struct +{ + eBodyOffset ePart; + float fD, fO; +} +SKIN_OFFSET; diff --git a/Minecraft.Client/Skins.h b/Minecraft.Client/Skins.h deleted file mode 100644 index 7596fa7f..00000000 --- a/Minecraft.Client/Skins.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once -#include -using namespace std; - -class AABB; -class Recipy; -class Object; - -static std::map slim = { - { 0, false }, - { 1, false }, - { 2, false }, - { 3, false }, - { 4, false }, - { 5, false }, - { 6, false }, - { 7, false }, - { 8, false }, - { 9, true }, - { 10, true }, - { 11, true }, - { 12, true }, - { 13, true }, - { 14, true }, - { 15, true }, - { 16, true }, - { 17, true }, - { 18, true }, -}; \ No newline at end of file diff --git a/Minecraft.Client/Textures.cpp b/Minecraft.Client/Textures.cpp index d478deaf..d5205282 100644 --- a/Minecraft.Client/Textures.cpp +++ b/Minecraft.Client/Textures.cpp @@ -72,16 +72,16 @@ const wchar_t *Textures::preLoaded[TN_COUNT] = L"mob/char5", L"mob/char6", L"mob/char7", - L"mob/char8", - L"mob/char9", - L"mob/char10", - L"mob/char11", - L"mob/char12", - L"mob/char13", - L"mob/char14", - L"mob/char15", - L"mob/char16", - L"mob/char17", + L"mob/alex", + L"mob/alex1", + L"mob/alex2", + L"mob/alex3", + L"mob/alex4", + L"mob/alex5", + L"mob/alex6", + L"mob/alex7", + L"mob/DevAlex", + L"mob/DevSteve", L"terrain/moon", L"terrain/sun", L"armor/power", @@ -1727,16 +1727,16 @@ TEXTURE_NAME OriginalImages[] = TN_MOB_CHAR5, TN_MOB_CHAR6, TN_MOB_CHAR7, - TN_MOB_CHAR8, - TN_MOB_CHAR9, - TN_MOB_CHAR10, - TN_MOB_CHAR11, - TN_MOB_CHAR12, - TN_MOB_CHAR13, - TN_MOB_CHAR14, - TN_MOB_CHAR15, - TN_MOB_CHAR16, - TN_MOB_CHAR17, + TN_MOB_ALEX, + TN_MOB_ALEX1, + TN_MOB_ALEX2, + TN_MOB_ALEX3, + TN_MOB_ALEX4, + TN_MOB_ALEX5, + TN_MOB_ALEX6, + TN_MOB_ALEX7, + TN_MOB_DEVALEX, + TN_MOB_DEVSTEVE, TN_MISC_MAPBG, diff --git a/Minecraft.Client/Textures.h b/Minecraft.Client/Textures.h index 5f08fe57..48eec6a4 100644 --- a/Minecraft.Client/Textures.h +++ b/Minecraft.Client/Textures.h @@ -63,16 +63,16 @@ typedef enum _TEXTURE_NAME TN_MOB_CHAR5, TN_MOB_CHAR6, TN_MOB_CHAR7, - TN_MOB_CHAR8, - TN_MOB_CHAR9, - TN_MOB_CHAR10, - TN_MOB_CHAR11, - TN_MOB_CHAR12, - TN_MOB_CHAR13, - TN_MOB_CHAR14, - TN_MOB_CHAR15, - TN_MOB_CHAR16, - TN_MOB_CHAR17, + TN_MOB_ALEX, + TN_MOB_ALEX1, + TN_MOB_ALEX2, + TN_MOB_ALEX3, + TN_MOB_ALEX4, + TN_MOB_ALEX5, + TN_MOB_ALEX6, + TN_MOB_ALEX7, + TN_MOB_DEVALEX, + TN_MOB_DEVSTEVE, TN_TERRAIN_MOON, TN_TERRAIN_SUN, TN_POWERED_CREEPER, diff --git a/Minecraft.Client/TrackedEntity.cpp b/Minecraft.Client/TrackedEntity.cpp index 7a12ce9a..82965bbd 100644 --- a/Minecraft.Client/TrackedEntity.cpp +++ b/Minecraft.Client/TrackedEntity.cpp @@ -486,6 +486,9 @@ TrackedEntity::eVisibility TrackedEntity::isVisible(EntityTracker *tracker, shar // 4J Stu - We call update players when the entity has moved more than a certain amount at the start of it's tick // Before this call we set xpu, ypu and zpu to the entities new position, but xp,yp and zp are the old position until later in the tick. // Therefore we should use the new position for visibility checks + // nullptr check + if (!this || !tracker || !sp) return eVisibility_NotVisible; + if (sp == nullptr) return eVisibility_NotVisible; double xd = sp->x - xpu; //xp / 32; double zd = sp->z - zpu; //zp / 32; @@ -516,6 +519,7 @@ TrackedEntity::eVisibility TrackedEntity::isVisible(EntityTracker *tracker, shar if (!bVisible) #endif { + if (!e || !e->riding) return eVisibility_NotVisible; MinecraftServer *server = MinecraftServer::getInstance(); INetworkPlayer *thisPlayer = sp->connection->getNetworkPlayer(); if( thisPlayer ) @@ -524,6 +528,9 @@ TrackedEntity::eVisibility TrackedEntity::isVisible(EntityTracker *tracker, shar { // Consider extra players, but not if they are the entity we are tracking, or the player we've been passed as input, or in another dimension shared_ptr ep = server->getPlayers()->players[i]; + if (!ep) continue; + if (!ep->connection) continue; + if (!ep->connection->getNetworkPlayer()) continue; if( ep == sp ) continue; if( ep == e ) continue; if( ep->dimension != sp->dimension ) continue; diff --git a/Minecraft.Client/VillagerZombieModel.cpp b/Minecraft.Client/VillagerZombieModel.cpp index b8a607f3..707a5d63 100644 --- a/Minecraft.Client/VillagerZombieModel.cpp +++ b/Minecraft.Client/VillagerZombieModel.cpp @@ -25,12 +25,12 @@ void VillagerZombieModel::_init(float g, float yOffset, bool isArmor) head->compile(1.0f/16.0f); } -VillagerZombieModel::VillagerZombieModel() : HumanoidModel(0, 0, 64, 64, false, true, true) +VillagerZombieModel::VillagerZombieModel() : HumanoidModel(0, 0, 64, 64) { _init(0, 0, false); } -VillagerZombieModel::VillagerZombieModel(float g, float yOffset, bool isArmor) : HumanoidModel(g, 0, 64, isArmor ? 32 : 64 , false, true, isArmor ? true : false) +VillagerZombieModel::VillagerZombieModel(float g, float yOffset, bool isArmor) : HumanoidModel(g, 0, 64, isArmor ? 32 : 64) { _init(g, yOffset, isArmor); } diff --git a/Minecraft.World/BonusChestFeature.cpp b/Minecraft.World/BonusChestFeature.cpp index 86dc9725..50e74540 100644 --- a/Minecraft.World/BonusChestFeature.cpp +++ b/Minecraft.World/BonusChestFeature.cpp @@ -24,6 +24,12 @@ bool BonusChestFeature::place(Level *level, Random *random, int x, int y, int z) bool BonusChestFeature::place(Level *level, Random *random, int x, int y, int z, bool force) { + // check if level is corrupted first + if (level == nullptr || random == nullptr) + { + return false; + } + if (!level->isNew) return false; //Will only spawn a bonus chest if the world is new and has never been saved. if (level->isNew) { diff --git a/Minecraft.World/ItemInstance.cpp b/Minecraft.World/ItemInstance.cpp index 43d1cce9..16c2e308 100644 --- a/Minecraft.World/ItemInstance.cpp +++ b/Minecraft.World/ItemInstance.cpp @@ -736,9 +736,13 @@ vector *ItemInstance::getHoverText(shared_ptr player, bool a { vector *lines = new vector(); Item *item = Item::items[id]; - HtmlString title = HtmlString(getHoverName()); - if (hasCustomHoverName()) + wstring hoverName = getHoverName(); + HtmlString title = HtmlString(L""); + title.text = app.EscapeHTMLString(hoverName); + title.text = app.FormatColoredString(title.text); + + if (hasCustomHoverName() && !(hoverName[0] == L'\u00A7' && hoverName[1] == L'r')) { title.italics = true; } @@ -791,19 +795,12 @@ vector *ItemInstance::getHoverText(shared_ptr player, bool a { CompoundTag *display = tag->getCompound(L"display"); - //if (display->contains(L"color")) - //{ - // if (advanced) - // { - // wchar_t text [256]; - // swprintf(text, 256, L"Color: LOCALISE #%08X", display->getInt(L"color")); - // lines->push_back(HtmlString(text)); - // } - // else - // { - // lines->push_back(HtmlString(L"Dyed LOCALISE", eMinecraftColour_NOT_SET, true)); - // } - //} + if (display->contains(L"color") && advanced) + { + wchar_t text[256]; + swprintf(text, 256, L"Color: LOCALISE #%08X", display->getInt(L"color")); + lines->push_back(HtmlString(text)); + } if (display->contains(L"Lore")) { @@ -813,7 +810,10 @@ vector *ItemInstance::getHoverText(shared_ptr player, bool a for (int i = 0; i < lore->size(); i++) { //lines->push_back(ChatFormatting::DARK_PURPLE + "" + ChatFormatting::ITALIC + lore->get(i)->data); - lines->push_back(lore->get(i)->data); + HtmlString loreString = HtmlString(L""); + loreString.text = app.EscapeHTMLString(lore->get(i)->data); + loreString.text = app.EscapeHTMLString(loreString.text); + lines->push_back(loreString); } } } diff --git a/Minecraft.World/Player.cpp b/Minecraft.World/Player.cpp index a8e31d24..df1f8bd6 100644 --- a/Minecraft.World/Player.cpp +++ b/Minecraft.World/Player.cpp @@ -110,6 +110,10 @@ void Player::_init() m_bCheckedForModelParts=false; m_bCheckedDLCForModelParts=false; + m_ppSkinOffsets=nullptr; + m_bCheckedForSkinOffsets=false; + m_bCheckedDLCForSkinOffsets=false; + #if defined(__PS3__) || defined(__ORBIS__) m_ePlayerNameValidState=ePlayerNameValid_NotSet; #endif @@ -724,7 +728,9 @@ void Player::setCustomSkin(DWORD skinId) m_bCheckedDLCForModelParts=false; this->SetAdditionalModelParts(nullptr); - + m_bCheckedForSkinOffsets=false; + m_bCheckedDLCForSkinOffsets=false; + this->SetSkinOffsets(nullptr); } unsigned int Player::getSkinAnimOverrideBitmask(DWORD skinId) @@ -2903,25 +2909,25 @@ int Player::getTexture() case eDefaultSkins_Skin7: return TN_MOB_CHAR7; // 4J - was L"/mob/char7.png"; case eDefaultSkins_Skin8: - return TN_MOB_CHAR8; // 4J - was L"/mob/char8.png"; + return TN_MOB_ALEX; // 4J - was L"/mob/alex.png"; case eDefaultSkins_Skin9: - return TN_MOB_CHAR9; // 4J - was L"/mob/char9.png"; + return TN_MOB_ALEX1; // 4J - was L"/mob/alex1.png"; case eDefaultSkins_Skin10: - return TN_MOB_CHAR10; // 4J - was L"/mob/char10.png"; + return TN_MOB_ALEX2; // 4J - was L"/mob/alex2.png"; case eDefaultSkins_Skin11: - return TN_MOB_CHAR11; // 4J - was L"/mob/char11.png"; + return TN_MOB_ALEX3; // 4J - was L"/mob/alex3.png"; case eDefaultSkins_Skin12: - return TN_MOB_CHAR12; // 4J - was L"/mob/char12.png"; + return TN_MOB_ALEX4; // 4J - was L"/mob/alex4.png"; case eDefaultSkins_Skin13: - return TN_MOB_CHAR13; // 4J - was L"/mob/char13.png"; + return TN_MOB_ALEX5; // 4J - was L"/mob/alex5.png"; case eDefaultSkins_Skin14: - return TN_MOB_CHAR14; // 4J - was L"/mob/char14.png"; + return TN_MOB_ALEX6; // 4J - was L"/mob/alex6.png"; case eDefaultSkins_Skin15: - return TN_MOB_CHAR15; // 4J - was L"/mob/char15.png"; + return TN_MOB_ALEX7; // 4J - was L"/mob/alex7.png"; case eDefaultSkins_Skin16: - return TN_MOB_CHAR16; // 4J - was L"/mob/char16.png"; + return TN_MOB_DEVALEX; // 4J - was L"/mob/DevAlex.png"; case eDefaultSkins_Skin17: - return TN_MOB_CHAR17; // 4J - was L"/mob/char17.png"; + return TN_MOB_DEVSTEVE; // 4J - was L"/mob/DevSteve.png"; default: return TN_MOB_CHAR; // 4J - was L"/mob/char.png"; @@ -3389,11 +3395,71 @@ vector *Player::GetAdditionalModelParts() return m_ppAdditionalModelParts; } +vector *Player::GetSkinOffsets() +{ + if(m_ppSkinOffsets==nullptr && !m_bCheckedForSkinOffsets) + { + bool hasCustomTexture = !customTextureUrl.empty(); + bool customTextureIsDefaultSkin = customTextureUrl.substr(0,3).compare(L"def") == 0; + + // see if we can find the parts + m_ppSkinOffsets=app.GetSkinOffsets(m_dwSkinId); + + // If it's a default texture (which has no parts), we have the parts, or we already have the texture (in which case we should have parts if there are any) then we are done + if(!hasCustomTexture || customTextureIsDefaultSkin || m_ppSkinOffsets != nullptr || app.IsFileInMemoryTextures(customTextureUrl)) + { + m_bCheckedForSkinOffsets=true; + } + if(m_ppSkinOffsets == nullptr && !m_bCheckedDLCForSkinOffsets) + { + m_bCheckedDLCForSkinOffsets = true; + + // we don't have the data from the dlc skin yet + app.DebugPrintf("m_bCheckedForModelOffsets Couldn't get skin offsets for skin %X\n",m_dwSkinId); + + // do we have it from the DLC pack? + DLCSkinFile *pDLCSkinFile = app.m_dlcManager.getSkinFile(this->customTextureUrl); + + if(pDLCSkinFile!=nullptr) + { + DWORD dwOffsetC=pDLCSkinFile->getOffsetsCount(); + if(dwOffsetC!=0) + { + app.DebugPrintf("m_bCheckedForSkinOffsets Got skin offsets from DLCskin for skin %X\n",m_dwSkinId); + m_ppSkinOffsets=app.SetSkinOffsets(m_dwSkinId,pDLCSkinFile->getOffsets()); + } + + m_bCheckedForSkinOffsets=true; + } + } + } + return m_ppSkinOffsets; +} + +int Player::GetModelTypeFromAnimBitmask(unsigned int animBitmask) +{ + if (animBitmask&(1< 8 && textureId < 18) return 2; + else if (textureId == 18) return 1; + else return 0; +} + void Player::SetAdditionalModelParts(vector *ppAdditionalModelParts) { m_ppAdditionalModelParts=ppAdditionalModelParts; } +void Player::SetSkinOffsets(vector *ppSkinOffsets) +{ + m_ppSkinOffsets=ppSkinOffsets; +} + #if defined(__PS3__) || defined(__ORBIS__) Player::ePlayerNameValidState Player::GetPlayerNameValidState(void) diff --git a/Minecraft.World/Player.h b/Minecraft.World/Player.h index d6067be6..59979f9a 100644 --- a/Minecraft.World/Player.h +++ b/Minecraft.World/Player.h @@ -442,6 +442,8 @@ public: static DWORD getCapeIdFromPath(const wstring &cape); static wstring getCapePathFromId(DWORD capeId); static unsigned int getSkinAnimOverrideBitmask(DWORD skinId); + static int GetModelTypeFromAnimBitmask(unsigned int uiAnimOverrideBitmask); + static int GetModelTypeFromTextureId(int textureId); // 4J Added void setXuid(PlayerUID xuid); @@ -553,6 +555,8 @@ public: vector *GetAdditionalModelParts(); void SetAdditionalModelParts(vector *ppAdditionalModelParts); + vector *GetSkinOffsets(); + void SetSkinOffsets(vector *ppSkinOffsets); #if defined(__PS3__) || defined(__ORBIS__) enum ePlayerNameValidState @@ -569,6 +573,9 @@ private: vector *m_ppAdditionalModelParts; bool m_bCheckedForModelParts; bool m_bCheckedDLCForModelParts; + vector *m_ppSkinOffsets; + bool m_bCheckedForSkinOffsets; + bool m_bCheckedDLCForSkinOffsets; #if defined(__PS3__) || defined(__ORBIS__) ePlayerNameValidState m_ePlayerNameValidState; // 4J-PB - to ensure we have the characters for this name in our font, or display a player number instead diff --git a/Minecraft.World/TextureAndGeometryPacket.cpp b/Minecraft.World/TextureAndGeometryPacket.cpp index 1c920ee7..44309caa 100644 --- a/Minecraft.World/TextureAndGeometryPacket.cpp +++ b/Minecraft.World/TextureAndGeometryPacket.cpp @@ -12,7 +12,9 @@ TextureAndGeometryPacket::TextureAndGeometryPacket() this->dwTextureBytes = 0; this->pbData = nullptr; this->dwBoxC = 0; + this->dwOffsetC = 0; this->BoxDataA = nullptr; + this->OffsetDataA = nullptr; uiAnimOverrideBitmask=0; } @@ -43,7 +45,9 @@ TextureAndGeometryPacket::TextureAndGeometryPacket(const wstring &textureName, P this->pbData = pbData; this->dwTextureBytes = dwBytes; this->dwBoxC = 0; + this->dwOffsetC = 0; this->BoxDataA=nullptr; + this->OffsetDataA=nullptr; this->uiAnimOverrideBitmask=0; } @@ -62,6 +66,7 @@ TextureAndGeometryPacket::TextureAndGeometryPacket(const wstring &textureName, P this->dwTextureBytes = dwBytes; this->uiAnimOverrideBitmask = pDLCSkinFile->getAnimOverrideBitmask(); this->dwBoxC = pDLCSkinFile->getAdditionalBoxesCount(); + this->dwOffsetC = pDLCSkinFile->getOffsetsCount(); if(this->dwBoxC!=0) { this->BoxDataA= new SKIN_BOX [this->dwBoxC]; @@ -77,9 +82,24 @@ TextureAndGeometryPacket::TextureAndGeometryPacket(const wstring &textureName, P { this->BoxDataA=nullptr; } + if(this->dwOffsetC!=0) + { + this->OffsetDataA= new SKIN_OFFSET [this->dwOffsetC]; + vector *pSkinOffsets=pDLCSkinFile->getOffsets(); + int iCount=0; + + for(auto& pSkinOffset : *pSkinOffsets) + { + this->OffsetDataA[iCount++]=*pSkinOffset; + } + } + else + { + this->OffsetDataA=nullptr; + } } -TextureAndGeometryPacket::TextureAndGeometryPacket(const wstring &textureName, PBYTE pbData, DWORD dwBytes,vector *pvSkinBoxes, unsigned int uiAnimOverrideBitmask) +TextureAndGeometryPacket::TextureAndGeometryPacket(const wstring &textureName, PBYTE pbData, DWORD dwBytes, vector *pvSkinBoxes, vector *pvSkinOffsets, unsigned int uiAnimOverrideBitmask) { this->textureName = textureName; @@ -109,6 +129,22 @@ TextureAndGeometryPacket::TextureAndGeometryPacket(const wstring &textureName, P this->BoxDataA[iCount++]=*pSkinBox; } } + if(pvSkinOffsets==nullptr) + { + this->dwOffsetC=0; + this->OffsetDataA=nullptr; + } + else + { + this->dwOffsetC = static_cast(pvSkinOffsets->size()); + this->OffsetDataA= new SKIN_OFFSET [this->dwOffsetC]; + int iCount=0; + + for(auto& pSkinOffset : *pvSkinOffsets) + { + this->OffsetDataA[iCount++]=*pSkinOffset; + } + } } @@ -148,6 +184,7 @@ void TextureAndGeometryPacket::read(DataInputStream *dis) //throws IOException uiAnimOverrideBitmask = dis->readInt(); short rawBoxC = dis->readShort(); + short rawOffsetC = dis->readShort(); if (rawBoxC <= 0) { dwBoxC = 0; @@ -160,11 +197,27 @@ void TextureAndGeometryPacket::read(DataInputStream *dis) //throws IOException dwBoxC = 0; // sane limit for skin boxes } } + if (rawOffsetC <= 0) + { + dwOffsetC = 0; + } + else + { + dwOffsetC = (DWORD)(unsigned short)rawOffsetC; + if (dwOffsetC > 256) + { + dwOffsetC = 0; // sane limit for skin offsets + } + } if(dwBoxC>0) { this->BoxDataA= new SKIN_BOX [dwBoxC]; } + if(dwOffsetC>0) + { + this->OffsetDataA= new SKIN_OFFSET [dwOffsetC]; + } for(DWORD i=0;iBoxDataA[i].fD = dis->readFloat(); this->BoxDataA[i].fU = dis->readFloat(); this->BoxDataA[i].fV = dis->readFloat(); + this->BoxDataA[i].fA = dis->readFloat(); + this->BoxDataA[i].fM = dis->readFloat(); + this->BoxDataA[i].fS = dis->readFloat(); + } + for(DWORD i=0;iOffsetDataA[i].ePart = static_cast(dis->readShort()); + this->OffsetDataA[i].fD = dis->readFloat(); + this->OffsetDataA[i].fO = dis->readFloat(); } } -void TextureAndGeometryPacket::write(DataOutputStream *dos) //throws IOException +void __fastcall TextureAndGeometryPacket::write(DataOutputStream *dos) //throws IOException { dos->writeUTF(textureName); dos->writeInt(dwSkinID); @@ -203,6 +265,17 @@ void TextureAndGeometryPacket::write(DataOutputStream *dos) //throws IOException dos->writeFloat(this->BoxDataA[i].fD); dos->writeFloat(this->BoxDataA[i].fU); dos->writeFloat(this->BoxDataA[i].fV); + dos->writeFloat(this->BoxDataA[i].fA); + dos->writeFloat(this->BoxDataA[i].fM); + dos->writeFloat(this->BoxDataA[i].fS); + } + + dos->writeShort(static_cast(dwOffsetC)); + for(DWORD i=0;iwriteShort(static_cast(this->OffsetDataA[i].ePart)); + dos->writeFloat(this->OffsetDataA[i].fD); + dos->writeFloat(this->OffsetDataA[i].fO); } } diff --git a/Minecraft.World/TextureAndGeometryPacket.h b/Minecraft.World/TextureAndGeometryPacket.h index fa0a5837..245edd2a 100644 --- a/Minecraft.World/TextureAndGeometryPacket.h +++ b/Minecraft.World/TextureAndGeometryPacket.h @@ -4,6 +4,7 @@ using namespace std; #include "Packet.h" #include "../Minecraft.Client/Model.h" #include "../Minecraft.Client/SkinBox.h" +#include "../Minecraft.Client/SkinOffset.h" class DLCSkinFile; @@ -15,14 +16,16 @@ public: PBYTE pbData; DWORD dwTextureBytes; SKIN_BOX *BoxDataA; + SKIN_OFFSET *OffsetDataA; DWORD dwBoxC; + DWORD dwOffsetC; unsigned int uiAnimOverrideBitmask; TextureAndGeometryPacket(); ~TextureAndGeometryPacket(); TextureAndGeometryPacket(const wstring &textureName, PBYTE pbData, DWORD dwBytes); TextureAndGeometryPacket(const wstring &textureName, PBYTE pbData, DWORD dwBytes, DLCSkinFile *pDLCSkinFile); - TextureAndGeometryPacket(const wstring &textureName, PBYTE pbData, DWORD dwBytes, vector *pvSkinBoxes, unsigned int uiAnimOverrideBitmask); + TextureAndGeometryPacket(const wstring &textureName, PBYTE pbData, DWORD dwBytes, vector *pvSkinBoxes, vector *pvSkinOffsets, unsigned int uiAnimOverrideBitmask); virtual void handle(PacketListener *listener); virtual void read(DataInputStream *dis);