diff --git a/Minecraft.Client/Common/Audio/SoundNames.cpp b/Minecraft.Client/Common/Audio/SoundNames.cpp index 4f2373f7..e0564f27 100644 --- a/Minecraft.Client/Common/Audio/SoundNames.cpp +++ b/Minecraft.Client/Common/Audio/SoundNames.cpp @@ -229,9 +229,47 @@ const WCHAR *ConsoleSoundEngine::wchSoundNames[eSoundType_MAX]= L"mob.rabbit.bunnymurder", L"mob.rabbit.hop", - + L"item.armor.equip_leather1", + L"item.armor.equip_leather2", + L"item.armor.equip_leather3", + L"item.armor.equip_leather4", + L"item.armor.equip_leather5", + L"item.armor.equip_leather6", + L"item.armor.equip_chain1", + L"item.armor.equip_chain2", + L"item.armor.equip_chain3", + L"item.armor.equip_chain4", + L"item.armor.equip_chain5", + L"item.armor.equip_chain6", + L"item.armor.equip_iron1", + L"item.armor.equip_iron2", + L"item.armor.equip_iron3", + L"item.armor.equip_iron4", + L"item.armor.equip_iron5", + L"item.armor.equip_iron6", + + L"item.armor.equip_gold1", + L"item.armor.equip_gold2", + L"item.armor.equip_gold3", + L"item.armor.equip_gold4", + L"item.armor.equip_gold5", + L"item.armor.equip_gold6", + + L"item.armor.equip_diamond1", + L"item.armor.equip_diamond2", + L"item.armor.equip_diamond3", + L"item.armor.equip_diamond4", + L"item.armor.equip_diamond5", + L"item.armor.equip_diamond6", + + L"item.armor.equip_generic1", + L"item.armor.equip_generic2", + L"item.armor.equip_generic3", + L"item.armor.equip_generic4", + L"item.armor.equip_generic5", + L"item.armor.equip_generic6" }; diff --git a/Minecraft.Client/Common/Media/MediaWindows64.arc b/Minecraft.Client/Common/Media/MediaWindows64.arc index 8e2d937a..48a59f65 100644 Binary files a/Minecraft.Client/Common/Media/MediaWindows64.arc and b/Minecraft.Client/Common/Media/MediaWindows64.arc differ diff --git a/Minecraft.Client/Common/UI/IUIScene_AbstractContainerMenu.cpp b/Minecraft.Client/Common/UI/IUIScene_AbstractContainerMenu.cpp index a393a097..f50aab50 100644 --- a/Minecraft.Client/Common/UI/IUIScene_AbstractContainerMenu.cpp +++ b/Minecraft.Client/Common/UI/IUIScene_AbstractContainerMenu.cpp @@ -5,9 +5,13 @@ #include "UI.h" #include "../../../Minecraft.World/net.minecraft.world.inventory.h" #include "../../../Minecraft.World/net.minecraft.world.item.h" +#include "../../../Minecraft.World/net.minecraft.world.item.enchantment.h" #include "../../../Minecraft.World/net.minecraft.world.item.crafting.h" #include "../../../Minecraft.World/net.minecraft.world.level.tile.entity.h" #include "../../MultiPlayerLocalPlayer.h" +#include "../../ServerPlayer.h" +#include "../../MinecraftServer.h" +#include "../../PlayerList.h" #include "../../Minecraft.h" #include "../../Options.h" @@ -264,6 +268,47 @@ void IUIScene_AbstractContainerMenu::UpdateTooltips() } } +void IUIScene_AbstractContainerMenu::handleEnchantButton(int slot, int iPad) { + UIScene* t = ui.FindScene(eUIScene_EnchantingMenu); + MinecraftServer* aMinecraft = MinecraftServer::getInstance(); + EnchantmentMenu* menu = dynamic_cast(aMinecraft->getPlayers()->players[iPad]->containerMenu); + + if (menu->en == false && menu->cachedEnchantments[slot] != nullptr) { + EnchantmentInstance* a = menu->cachedEnchantments[slot]->at(0); + if (a != nullptr) { + int lapisCost = slot + 1; // slot 0 = 1 lapis, slot 1 = 2, slot 2 = 3 + + HtmlString title = HtmlString( + wstring(app.GetString(a->enchantment->enchantments[a->enchantment->id]->getDescriptionId())) + + L" " + + a->enchantment->enchantments[a->enchantment->id]->getLevelString(a->level) + + L"...?", + eHTMLColor_White + ); + + bool costEnough = aMinecraft->getPlayers()->players[iPad]->experienceLevel >= menu->costs[slot]; + bool enough = menu->getLapisCount() >= lapisCost; + eMinecraftColour col = enough ? eHTMLColor_7 : eHTMLColor_c; + eMinecraftColour colCost = costEnough ? eHTMLColor_7 : eHTMLColor_c; + + std::wstring message = costEnough + ? std::to_wstring(menu->costs[slot]) + L" Enchantment Levels" + : L"Level Requirement: " + std::to_wstring(menu->costs[slot]); + + vector* lines = new vector(); + lines->push_back(title); + if (!aMinecraft->getPlayers()->players[iPad]->abilities.instabuild) { + lines->push_back(HtmlString(L"")); // title1 blank line + if (costEnough) { + lines->push_back(HtmlString(std::to_wstring(lapisCost) + L" Lapis Lazuli", col)); + } + lines->push_back(HtmlString(message, colCost)); + } + SetPointerText(lines, false); + } + } + }; + void IUIScene_AbstractContainerMenu::onMouseTick() { Minecraft *pMinecraft = Minecraft::GetInstance(); @@ -826,6 +871,9 @@ void IUIScene_AbstractContainerMenu::onMouseTick() SetPointerText(nullptr, false); m_lastPointerLabelSlot = nullptr; } + if (eSectionUnderPointer == eSectionEnchantButton1) handleEnchantButton(0, iPad); + else if (eSectionUnderPointer == eSectionEnchantButton2) handleEnchantButton(1, iPad); + else if (eSectionUnderPointer == eSectionEnchantButton3) handleEnchantButton(2, iPad); EToolTipItem buttonA, buttonX, buttonY, buttonRT, buttonBack; buttonA = buttonX = buttonY = buttonRT = buttonBack = eToolTipNone; diff --git a/Minecraft.Client/Common/UI/IUIScene_AbstractContainerMenu.h b/Minecraft.Client/Common/UI/IUIScene_AbstractContainerMenu.h index 6710e18f..8fb5d5c5 100644 --- a/Minecraft.Client/Common/UI/IUIScene_AbstractContainerMenu.h +++ b/Minecraft.Client/Common/UI/IUIScene_AbstractContainerMenu.h @@ -66,6 +66,7 @@ protected: eSectionEnchantUsing, eSectionEnchantInventory, eSectionEnchantSlot, + eSectionLapisSlot, eSectionEnchantButton1, eSectionEnchantButton2, eSectionEnchantButton3, @@ -216,6 +217,7 @@ protected: virtual void PlatformInitialize(int iPad, int startIndex) = 0; virtual void InitDataAssociations(int iPad, AbstractContainerMenu *menu, int startIndex = 0) = 0; + void handleEnchantButton(int slot, int iPad); void onMouseTick(); bool handleKeyDown(int iPad, int iAction, bool bRepeat); virtual bool handleValidKeyPress(int iUserIndex, int buttonNum, BOOL quickKeyHeld); diff --git a/Minecraft.Client/Common/UI/IUIScene_CreativeMenu.cpp b/Minecraft.Client/Common/UI/IUIScene_CreativeMenu.cpp index 6e2ad2b3..ce90b26f 100644 --- a/Minecraft.Client/Common/UI/IUIScene_CreativeMenu.cpp +++ b/Minecraft.Client/Common/UI/IUIScene_CreativeMenu.cpp @@ -426,6 +426,10 @@ void IUIScene_CreativeMenu::staticCtor() ITEM_AUX(Item::spawnEgg_Id, 62); // Magma Cube ITEM_AUX(Item::spawnEgg_Id, 65); // Bat ITEM_AUX(Item::spawnEgg_Id, 66); // Witch + + ITEM_AUX(Item::spawnEgg_Id, 67); // Endermite + ITEM_AUX(Item::spawnEgg_Id, 68); // Guardian + ITEM_AUX(Item::spawnEgg_Id, 4); // Elder Guardian ITEM_AUX(Item::spawnEgg_Id, 90); // Pig ITEM_AUX(Item::spawnEgg_Id, 91); // Sheep ITEM_AUX(Item::spawnEgg_Id, 92); // Cow @@ -435,7 +439,6 @@ void IUIScene_CreativeMenu::staticCtor() ITEM_AUX(Item::spawnEgg_Id, 96); // Mooshroom ITEM_AUX(Item::spawnEgg_Id, 98); // Ozelot ITEM_AUX(Item::spawnEgg_Id, 100); // Horse - ITEM_AUX(Item::spawnEgg_Id, 67); // Endermite ITEM_AUX(Item::spawnEgg_Id, 100 | ((EntityHorse::TYPE_DONKEY + 1) << 12) ); // Donkey ITEM_AUX(Item::spawnEgg_Id, 100 | ((EntityHorse::TYPE_MULE + 1) << 12)); // Mule diff --git a/Minecraft.Client/Common/UI/IUIScene_EnchantingMenu.cpp b/Minecraft.Client/Common/UI/IUIScene_EnchantingMenu.cpp index 5f1e8ced..242fb83f 100644 --- a/Minecraft.Client/Common/UI/IUIScene_EnchantingMenu.cpp +++ b/Minecraft.Client/Common/UI/IUIScene_EnchantingMenu.cpp @@ -2,7 +2,10 @@ #include "../../../Minecraft.World/net.minecraft.world.inventory.h" #include "../../Minecraft.h" #include "../../MultiPlayerLocalPlayer.h" +#include "../../PlayerList.h" +#include "../../ServerPlayer.h" #include "IUIScene_EnchantingMenu.h" +#include IUIScene_AbstractContainerMenu::ESceneSection IUIScene_EnchantingMenu::GetSectionAndSlotInDirection( IUIScene_AbstractContainerMenu::ESceneSection eSection, ETapState eTapDirection, int *piTargetX, int *piTargetY ) { @@ -140,9 +143,10 @@ void IUIScene_EnchantingMenu::handleOtherClicked(int iPad, ESceneSection eSectio break; }; Minecraft *pMinecraft = Minecraft::GetInstance(); - if (index >= 0 && m_menu->clickMenuButton(dynamic_pointer_cast(pMinecraft->localplayers[iPad]), index)) + MinecraftServer *aMinecraft = MinecraftServer::getInstance(); + if (index >= 0 && dynamic_cast(aMinecraft->getPlayers()->players[iPad]->containerMenu)->clickMenuButton(dynamic_pointer_cast(aMinecraft->getPlayers()->players[iPad]), index)) { - pMinecraft->localgameModes[iPad]->handleInventoryButtonClick(m_menu->containerId, index); + pMinecraft->localgameModes[iPad]->handleInventoryButtonClick(dynamic_cast(aMinecraft->getPlayers()->players[iPad]->containerMenu)->containerId, index); } } @@ -154,11 +158,14 @@ int IUIScene_EnchantingMenu::getSectionStartOffset(ESceneSection eSection) case eSectionEnchantSlot: offset = 0; break; - case eSectionEnchantInventory: + case eSectionLapisSlot: offset = 1; break; + case eSectionEnchantInventory: + offset = 2; + break; case eSectionEnchantUsing: - offset = 1 + 27; + offset = 2 + 27; break; default: assert( false ); @@ -174,6 +181,7 @@ bool IUIScene_EnchantingMenu::IsSectionSlotList( ESceneSection eSection ) case eSectionEnchantInventory: case eSectionEnchantUsing: case eSectionEnchantSlot: + case eSectionLapisSlot: return true; } return false; diff --git a/Minecraft.Client/Common/UI/UIControl_EnchantmentButton.cpp b/Minecraft.Client/Common/UI/UIControl_EnchantmentButton.cpp index 46dc4289..1e90de62 100644 --- a/Minecraft.Client/Common/UI/UIControl_EnchantmentButton.cpp +++ b/Minecraft.Client/Common/UI/UIControl_EnchantmentButton.cpp @@ -26,6 +26,8 @@ bool UIControl_EnchantmentButton::setupControl(UIScene *scene, IggyValuePath *pa //Button specific initialisers m_funcChangeState = registerFastName(L"ChangeState"); + m_CLevel = registerFastName(L"m_iCurrentLevel"); + m_CLevelU = registerFastName(L"SetEnchantmentLevel"); return success; } @@ -33,6 +35,18 @@ bool UIControl_EnchantmentButton::setupControl(UIScene *scene, IggyValuePath *pa void UIControl_EnchantmentButton::init(int index) { m_index = index; + //IggyValueSetF64RS(getIggyValuePath(), m_CLevel, nullptr, index + 1); +} + +void UIControl_EnchantmentButton::setLevel() +{ + IggyValueSetF64RS(getIggyValuePath(), m_CLevel, nullptr, m_index + 1); + + IggyDataValue value[1]; + value[0].type = IGGY_DATATYPE_number; + value[0].number = m_index + 1; + IggyDataValue result; + IggyResult out = IggyPlayerCallMethodRS(m_parentScene->getMovie(), &result, getIggyValuePath(), m_CLevelU, 1, value); } @@ -176,6 +190,8 @@ void UIControl_EnchantmentButton::updateState() setLabel(L""); } + IggyValueSetF64RS(getIggyValuePath(), m_CLevel, nullptr, m_BValue); + if(state != m_lastState) { IggyDataValue result; diff --git a/Minecraft.Client/Common/UI/UIControl_EnchantmentButton.h b/Minecraft.Client/Common/UI/UIControl_EnchantmentButton.h index f7a703b3..f236435b 100644 --- a/Minecraft.Client/Common/UI/UIControl_EnchantmentButton.h +++ b/Minecraft.Client/Common/UI/UIControl_EnchantmentButton.h @@ -20,6 +20,8 @@ private: bool m_bHasFocus; IggyName m_funcChangeState; + IggyName m_CLevel; + IggyName m_CLevelU; unsigned int m_textColour, m_textFocusColour, m_textDisabledColour; @@ -27,6 +29,7 @@ private: { public: static EnchantmentNames instance; + private: Random random; @@ -40,12 +43,13 @@ private: public: UIControl_EnchantmentButton(); - + int m_BValue = 1; virtual bool setupControl(UIScene *scene, IggyValuePath *parent, const string &controlName); virtual void tick(); void init(int index); + void setLevel(); virtual void ReInit(); void render(IggyCustomDrawCallbackRegion *region); diff --git a/Minecraft.Client/Common/UI/UIScene_EnchantingMenu.cpp b/Minecraft.Client/Common/UI/UIScene_EnchantingMenu.cpp index 91d0d38f..ced8b5fe 100644 --- a/Minecraft.Client/Common/UI/UIScene_EnchantingMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_EnchantingMenu.cpp @@ -10,10 +10,18 @@ UIScene_EnchantingMenu::UIScene_EnchantingMenu(int iPad, void *_initData, UILaye // Setup all the Iggy references we need for this scene initialiseMovie(); + m_enchantButton[0].m_BValue = 1.0f; + m_enchantButton[1].m_BValue = 2.0f; + m_enchantButton[2].m_BValue = 3.0f; + m_enchantButton[0].init(0); m_enchantButton[1].init(1); m_enchantButton[2].init(2); + + + + EnchantingScreenInput *initData = static_cast(_initData); m_labelEnchant.init( initData->name.empty() ? app.GetString(IDS_ENCHANT) : initData->name ); @@ -26,15 +34,21 @@ UIScene_EnchantingMenu::UIScene_EnchantingMenu(int iPad, void *_initData, UILaye gameMode->getTutorial()->changeTutorialState(e_Tutorial_State_Enchanting_Menu, this); } - EnchantmentMenu *menu = new EnchantmentMenu(initData->inventory, initData->level, initData->x, initData->y, initData->z); + menu = new EnchantmentMenu(initData->inventory, initData->level, initData->x, initData->y, initData->z); + //menu->iPad = initData->iPad; Initialize( initData->iPad, menu, true, EnchantmentMenu::INV_SLOT_START, eSectionEnchantUsing, eSectionEnchantMax ); m_slotListIngredient.addSlots(EnchantmentMenu::INGREDIENT_SLOT, 1); + m_slotListLapis.addSlots(EnchantmentMenu::LAPIS_SLOT, 1); app.SetRichPresenceContext(m_iPad,CONTEXT_GAME_STATE_ENCHANTING); delete initData; + + m_enchantButton[0].setLevel(); + m_enchantButton[1].setLevel(); + m_enchantButton[2].setLevel(); } wstring UIScene_EnchantingMenu::getMoviePath() @@ -54,6 +68,7 @@ void UIScene_EnchantingMenu::handleReload() Initialize( m_iPad, m_menu, true, EnchantmentMenu::INV_SLOT_START, eSectionEnchantUsing, eSectionEnchantMax ); m_slotListIngredient.addSlots(EnchantmentMenu::INGREDIENT_SLOT, 1); + m_slotListLapis.addSlots(EnchantmentMenu::LAPIS_SLOT, 1); } int UIScene_EnchantingMenu::getSectionColumns(ESceneSection eSection) @@ -64,6 +79,9 @@ int UIScene_EnchantingMenu::getSectionColumns(ESceneSection eSection) case eSectionEnchantSlot: cols = 1; break; + case eSectionLapisSlot: + cols = 1; + break; case eSectionEnchantInventory: cols = 9; break; @@ -85,6 +103,9 @@ int UIScene_EnchantingMenu::getSectionRows(ESceneSection eSection) case eSectionEnchantSlot: rows = 1; break; + case eSectionLapisSlot: + rows = 1; + break; case eSectionEnchantInventory: rows = 3; break; @@ -106,6 +127,10 @@ void UIScene_EnchantingMenu::GetPositionOfSection( ESceneSection eSection, UIVec pPosition->x = m_slotListIngredient.getXPos(); pPosition->y = m_slotListIngredient.getYPos(); break; + case eSectionLapisSlot: + pPosition->x = m_slotListLapis.getXPos(); + pPosition->y = m_slotListLapis.getYPos(); + break; case eSectionEnchantInventory: pPosition->x = m_slotListInventory.getXPos(); pPosition->y = m_slotListInventory.getYPos(); @@ -141,6 +166,10 @@ void UIScene_EnchantingMenu::GetItemScreenData( ESceneSection eSection, int iIte sectionSize.x = m_slotListIngredient.getWidth(); sectionSize.y = m_slotListIngredient.getHeight(); break; + case eSectionLapisSlot: + sectionSize.x = m_slotListLapis.getWidth(); + sectionSize.y = m_slotListLapis.getHeight(); + break; case eSectionEnchantInventory: sectionSize.x = m_slotListInventory.getWidth(); sectionSize.y = m_slotListInventory.getHeight(); @@ -200,6 +229,9 @@ void UIScene_EnchantingMenu::setSectionSelectedSlot(ESceneSection eSection, int case eSectionEnchantSlot: slotList = &m_slotListIngredient; break; + case eSectionLapisSlot: + slotList = &m_slotListLapis; + break; case eSectionEnchantInventory: slotList = &m_slotListInventory; break; @@ -222,6 +254,9 @@ UIControl *UIScene_EnchantingMenu::getSection(ESceneSection eSection) case eSectionEnchantSlot: control = &m_slotListIngredient; break; + case eSectionLapisSlot: + control = &m_slotListLapis; + break; case eSectionEnchantInventory: control = &m_slotListInventory; break; diff --git a/Minecraft.Client/Common/UI/UIScene_EnchantingMenu.h b/Minecraft.Client/Common/UI/UIScene_EnchantingMenu.h index 89ccd120..1a5ea177 100644 --- a/Minecraft.Client/Common/UI/UIScene_EnchantingMenu.h +++ b/Minecraft.Client/Common/UI/UIScene_EnchantingMenu.h @@ -20,8 +20,10 @@ public: virtual EUIScene getSceneType() { return eUIScene_EnchantingMenu;} + EnchantmentMenu* menu; + protected: - UIControl_SlotList m_slotListIngredient; + UIControl_SlotList m_slotListIngredient, m_slotListLapis; UIControl_Label m_labelEnchant; UIControl_EnchantmentButton m_enchantButton[3]; UIControl_EnchantmentBook m_enchantBook; @@ -29,6 +31,7 @@ protected: UI_BEGIN_MAP_ELEMENTS_AND_NAMES(UIScene_AbstractContainerMenu) UI_BEGIN_MAP_CHILD_ELEMENTS( m_controlMainPanel ) UI_MAP_ELEMENT( m_slotListIngredient, "ingredient") + UI_MAP_ELEMENT(m_slotListLapis, "lapis") UI_MAP_ELEMENT( m_enchantButton[0], "Button1") UI_MAP_ELEMENT( m_enchantButton[1], "Button2") UI_MAP_ELEMENT( m_enchantButton[2], "Button3") diff --git a/Minecraft.Client/Common/UI/UIScene_MainMenu.cpp b/Minecraft.Client/Common/UI/UIScene_MainMenu.cpp index 1eef994f..c382740f 100644 --- a/Minecraft.Client/Common/UI/UIScene_MainMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_MainMenu.cpp @@ -34,6 +34,7 @@ UIScene_MainMenu::UIScene_MainMenu(int iPad, void *initData, UILayer *parentLaye m_buttons[static_cast(eControl_PlayGame)].init(IDS_PLAY_GAME,eControl_PlayGame); + m_buttons[(int)eControl_MiniGames].init(L"Mini Games",eControl_MiniGames); #ifdef _XBOX_ONE if(!ProfileManager.IsFullVersion()) m_buttons[(int)eControl_PlayGame].setLabel(IDS_PLAY_TRIAL_GAME); @@ -325,6 +326,24 @@ void UIScene_MainMenu::handlePress(F64 controlId, F64 childId) //CD - Added for audio ui.PlayUISFX(eSFX_Press); + signInReturnedFunc = &UIScene_MainMenu::CreateLoad_SignInReturned; +#endif + break; + case eControl_MiniGames: + #ifdef __ORBIS__ + { + m_bIgnorePress=true; + + //CD - Added for audio + ui.PlayUISFX(eSFX_Press); + + ProfileManager.RefreshChatAndContentRestrictions(RefreshChatAndContentRestrictionsReturned_PlayGame, this); + } +#else + m_eAction=eAction_RunGame; + //CD - Added for audio + ui.PlayUISFX(eSFX_Press); + signInReturnedFunc = &UIScene_MainMenu::CreateLoad_SignInReturned; #endif break; diff --git a/Minecraft.Client/Common/UI/UIScene_MainMenu.h b/Minecraft.Client/Common/UI/UIScene_MainMenu.h index 2b49a44b..0a3665ee 100644 --- a/Minecraft.Client/Common/UI/UIScene_MainMenu.h +++ b/Minecraft.Client/Common/UI/UIScene_MainMenu.h @@ -12,6 +12,7 @@ private: eControl_Achievements, eControl_HelpAndOptions, eControl_UnlockOrDLC, + eControl_MiniGames, #ifndef _DURANGO eControl_Exit, #else @@ -38,7 +39,9 @@ private: UI_MAP_ELEMENT( m_buttons[(int)eControl_HelpAndOptions], "Button4") UI_MAP_ELEMENT( m_buttons[(int)eControl_UnlockOrDLC], "Button5") #ifndef _DURANGO + UI_MAP_ELEMENT( m_buttons[(int)eControl_MiniGames], "Button7") UI_MAP_ELEMENT( m_buttons[(int)eControl_Exit], "Button6") + #else UI_MAP_ELEMENT( m_buttons[(int)eControl_XboxHelp], "Button6") #endif diff --git a/Minecraft.Client/Common/res/1_2_2/mob/guardian.png b/Minecraft.Client/Common/res/1_2_2/mob/guardian.png new file mode 100644 index 00000000..12e1846b Binary files /dev/null and b/Minecraft.Client/Common/res/1_2_2/mob/guardian.png differ diff --git a/Minecraft.Client/Common/res/1_2_2/mob/guardian_beam.png b/Minecraft.Client/Common/res/1_2_2/mob/guardian_beam.png new file mode 100644 index 00000000..68f0109e Binary files /dev/null and b/Minecraft.Client/Common/res/1_2_2/mob/guardian_beam.png differ diff --git a/Minecraft.Client/Common/res/1_2_2/mob/guardian_elder.png b/Minecraft.Client/Common/res/1_2_2/mob/guardian_elder.png new file mode 100644 index 00000000..c8c827bb Binary files /dev/null and b/Minecraft.Client/Common/res/1_2_2/mob/guardian_elder.png differ diff --git a/Minecraft.Client/EntityRenderDispatcher.cpp b/Minecraft.Client/EntityRenderDispatcher.cpp index 474d3fa4..9b610b58 100644 --- a/Minecraft.Client/EntityRenderDispatcher.cpp +++ b/Minecraft.Client/EntityRenderDispatcher.cpp @@ -85,6 +85,8 @@ #include "ArmorStandRenderer.h" #include "EndermiteRenderer.h" +#include "GuardianRenderer.h" +#include "GuardianModel.h" #include "MobRenderer.h" double EntityRenderDispatcher::xOff = 0.0; @@ -128,6 +130,9 @@ EntityRenderDispatcher::EntityRenderDispatcher() renderers[eTYPE_VILLAGER] = new VillagerRenderer(); renderers[eTYPE_VILLAGERGOLEM] = new VillagerGolemRenderer(); renderers[eTYPE_BAT] = new BatRenderer(); + renderers[eTYPE_GUARDIAN] = new GuardianRenderer(new GuardianModel(), 0.5f); + renderers[eTYPE_ELDER_GUARDIAN] = new GuardianRenderer(new GuardianModel(), 0.5f); + renderers[eTYPE_MOB] = new MobRenderer(new HumanoidModel(), 0.5f); diff --git a/Minecraft.Client/EntityRenderer.cpp b/Minecraft.Client/EntityRenderer.cpp index 6d1d15b2..22698db3 100644 --- a/Minecraft.Client/EntityRenderer.cpp +++ b/Minecraft.Client/EntityRenderer.cpp @@ -407,6 +407,7 @@ void EntityRenderer::registerTerrainTextures(IconRegister *iconRegister) { } + ResourceLocation *EntityRenderer::getTextureLocation(shared_ptr mob) { return nullptr; diff --git a/Minecraft.Client/EntityRenderer.h b/Minecraft.Client/EntityRenderer.h index 02208f32..0445fe1e 100644 --- a/Minecraft.Client/EntityRenderer.h +++ b/Minecraft.Client/EntityRenderer.h @@ -75,4 +75,6 @@ public: virtual Model *getNewModel() { return newModel; } virtual Model *getNewModelSlim() { return newModelSlim; } virtual void SetItemFrame(bool bSet) {} + virtual bool shouldRender(shared_ptr entity, float camX, float camY, float camZ) { return true; } + }; diff --git a/Minecraft.Client/GuardianModel.cpp b/Minecraft.Client/GuardianModel.cpp new file mode 100644 index 00000000..61612d83 --- /dev/null +++ b/Minecraft.Client/GuardianModel.cpp @@ -0,0 +1,147 @@ +#include "stdafx.h" +#include "GuardianModel.h" +#include "..\Minecraft.World\Mth.h" +#include "ModelPart.h" +#include "..\Minecraft.World\Guardian.h" + + + +GuardianModel::GuardianModel() : Model() +{ + texWidth = 64; + texHeight = 64; + + + guardianBody = new ModelPart(this); + guardianBody->texOffs(0, 0)->addBox(-6.0f, 10.0f, -8.0f, 12, 12, 16); + guardianBody->texOffs(0, 28)->addBox(-8.0f, 10.0f, -6.0f, 2, 12, 12); + + + ModelPart *rightSide = new ModelPart(this); + rightSide->texOffs(0, 28)->mirror()->addBox(6.0f, 10.0f, -6.0f, 2, 12, 12); + guardianBody->addChild(rightSide); + + guardianBody->texOffs(16, 40)->addBox(-6.0f, 8.0f, -6.0f, 12, 2, 12); + guardianBody->texOffs(16, 40)->addBox(-6.0f, 22.0f, -6.0f, 12, 2, 12); + + + for (int i = 0; i < 12; i++) + { + guardianSpines[i] = new ModelPart(this, 0, 0); + guardianSpines[i]->addBox(-1.0f, -4.5f, -1.0f, 2, 9, 2); + guardianBody->addChild(guardianSpines[i]); + } + + + guardianEye = new ModelPart(this, 8, 0); + guardianEye->addBox(-1.0f, 15.0f, 0.0f, 2, 2, 1); + guardianBody->addChild(guardianEye); + + + guardianTail[0] = new ModelPart(this, 40, 0); + guardianTail[0]->addBox(-2.0f, 14.0f, 7.0f, 4, 4, 8); + + guardianTail[1] = new ModelPart(this, 0, 54); + guardianTail[1]->addBox(0.0f, 14.0f, 0.0f, 3, 3, 7); + + guardianTail[2] = new ModelPart(this); + guardianTail[2]->texOffs(41, 32)->addBox(0.0f, 14.0f, 0.0f, 2, 2, 6); + guardianTail[2]->texOffs(25, 19)->addBox(1.0f, 10.5f, 3.0f, 1, 9, 9); + + guardianBody->addChild(guardianTail[0]); + guardianTail[0]->addChild(guardianTail[1]); + guardianTail[1]->addChild(guardianTail[2]); +} + + + +void GuardianModel::setupAnim(float time, float r, float bob, float yRot, float xRot, + float scale, shared_ptr entity, + unsigned int uiBitmaskOverrideAnim) +{ + shared_ptr guardian = dynamic_pointer_cast(entity); + if (!guardian) return; + + + float afloat[] = { 1.75f, 0.25f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 0.5f, 1.25f, 0.75f, 0.0f, 0.0f }; + float afloat1[] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.25f,1.75f, 1.25f, 0.75f, 0.0f, 0.0f, 0.0f, 0.0f }; + float afloat2[] = { 0.0f, 0.0f, 0.25f,1.75f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.75f,1.25f}; + float afloat3[] = { 0.0f, 0.0f, 8.0f, -8.0f,-8.0f, 8.0f, 8.0f, -8.0f, 0.0f, 0.0f, 8.0f,-8.0f }; + float afloat4[] = {-8.0f, -8.0f, -8.0f, -8.0f, 0.0f, 0.0f, 0.0f, 0.0f, 8.0f, 8.0f, 8.0f, 8.0f }; + float afloat5[] = { 8.0f, -8.0f, 0.0f, 0.0f,-8.0f,-8.0f, 8.0f, 8.0f, 8.0f, -8.0f, 0.0f, 0.0f }; + + // Body orientation + guardianBody->yRot = yRot / (180.0f / (float)PI); + guardianBody->xRot = xRot / (180.0f / (float)PI); + + + guardianEye->z = -8.25f; + + if (guardian->hasTargetedEntity()) + { + shared_ptr target = guardian->getTargetedEntity(); + if (target) + { + + double d0 = (guardian->y + guardian->getEyeHeight()) + - (target->y + target->getEyeHeight()); + guardianEye->y = (d0 > 0.0) ? 0.0f : 1.0f; + + + double dx = target->x - guardian->x; + double dz = target->z - guardian->z; + float targetYaw = (float)(atan2(dz, dx) * 180.0 / PI) - 90.0f; + float diff = Mth::wrapDegrees(targetYaw - guardian->yRot); + + float clamped = diff / 45.0f; + if (clamped < -2.0f) clamped = -2.0f; + if (clamped > 2.0f) clamped = 2.0f; + guardianEye->x = clamped; + } + } + else + { + guardianEye->y = 0.0f; + guardianEye->x = 0.0f; + } + + + float f1 = (1.0f - guardian->getSpikesAnimation(0.0f)) * 0.55f; + + for (int i = 0; i < 12; ++i) + { + guardianSpines[i]->xRot = (float)PI * afloat[i]; + guardianSpines[i]->yRot = (float)PI * afloat1[i]; + guardianSpines[i]->zRot = (float)PI * afloat2[i]; + + float wave = 1.0f + Mth::cos(bob * 1.5f + (float)i) * 0.01f - f1; + guardianSpines[i]->x = afloat3[i] * wave; + guardianSpines[i]->y = 16.0f + afloat4[i] * wave; + guardianSpines[i]->z = afloat5[i] * wave; + } + + + float tailAnim = guardian->getTailAnimation(0.0f); + + guardianTail[0]->yRot = Mth::sin(tailAnim) * (float)PI * 0.05f; + + guardianTail[1]->yRot = Mth::sin(tailAnim) * (float)PI * 0.1f; + guardianTail[1]->x = -1.5f; + guardianTail[1]->y = 0.5f; + guardianTail[1]->z = 14.0f; + + guardianTail[2]->yRot = Mth::sin(tailAnim) * (float)PI * 0.15f; + guardianTail[2]->x = 0.5f; + guardianTail[2]->y = 0.5f; + guardianTail[2]->z = 6.0f; +} + + + +void GuardianModel::render(shared_ptr entity, float time, float r, float bob, + float yRot, float xRot, float scale, bool usecompiled) +{ + setupAnim(time, r, bob, yRot, xRot, scale, entity); + + guardianBody->render(scale, usecompiled); +} \ No newline at end of file diff --git a/Minecraft.Client/GuardianModel.h b/Minecraft.Client/GuardianModel.h new file mode 100644 index 00000000..24170885 --- /dev/null +++ b/Minecraft.Client/GuardianModel.h @@ -0,0 +1,25 @@ +#pragma once +#include "Model.h" + +class ModelPart; + +class GuardianModel : public Model +{ +public: + ModelPart *guardianBody; + ModelPart *guardianEye; + ModelPart *guardianSpines[12]; + ModelPart *guardianTail[3]; + + GuardianModel(); + + + int getTextureHeight() { return 64; } + + virtual void setupAnim(float time, float r, float bob, float yRot, float xRot, + float scale, shared_ptr entity, + unsigned int uiBitmaskOverrideAnim = 0) override; + + virtual void render(shared_ptr entity, float time, float r, float bob, + float yRot, float xRot, float scale, bool usecompiled) override; +}; \ No newline at end of file diff --git a/Minecraft.Client/GuardianRenderer.cpp b/Minecraft.Client/GuardianRenderer.cpp new file mode 100644 index 00000000..e6174792 --- /dev/null +++ b/Minecraft.Client/GuardianRenderer.cpp @@ -0,0 +1,239 @@ +#include "stdafx.h" +#include "GuardianRenderer.h" +#include "GuardianModel.h" +#include "..\Minecraft.World\Mth.h" +#include "..\Minecraft.World\net.minecraft.world.entity.animal.h" +#include "../Minecraft.World/Guardian.h" +#include "..\Minecraft.World\Level.h" +#include "Tesselator.h" + + + +ResourceLocation GuardianRenderer::GUARDIAN_LOCATION = ResourceLocation(TN_MOB_GUARDIAN); +ResourceLocation GuardianRenderer::GUARDIAN_ELDER_LOCATION = ResourceLocation(TN_MOB_GUARDIAN_ELDER); +ResourceLocation GuardianRenderer::GUARDIAN_BEAM_LOCATION = ResourceLocation(TN_MOB_GUARDIAN_BEAM); + +GuardianRenderer::GuardianRenderer(Model *model, float shadow) + : MobRenderer(model, shadow) +{ + guardianModel = static_cast(model); +} + + + + +ResourceLocation *GuardianRenderer::getTextureLocation(shared_ptr mob) +{ + shared_ptr guardian = dynamic_pointer_cast(mob); + if (guardian && guardian->isElder()) + return &GUARDIAN_ELDER_LOCATION; + return &GUARDIAN_LOCATION; +} + + + + + + + +bool GuardianRenderer::shouldRender(shared_ptr mob, float camX, float camY, float camZ) +{ + if (MobRenderer::shouldRender(mob, camX, camY, camZ)) + return true; + + shared_ptr guardian = dynamic_pointer_cast(mob); + if (!guardian || !guardian->hasTargetedEntity()) + return false; + + shared_ptr target = guardian->getTargetedEntity(); + if (!target) + return false; + + double tx, ty, tz, gx, gy, gz; + getInterpolatedPos(target, (double)target->bbHeight * 0.5, 1.0f, tx, ty, tz); + getInterpolatedPos(guardian, (double)guardian->getEyeHeight(), 1.0f, gx, gy, gz); + + + auto inRange = [&](double x, double y, double z) { + double dx = x - camX, dy = y - camY, dz = z - camZ; + return (dx*dx + dy*dy + dz*dz) < (64.0 * 64.0); + }; + + return inRange(gx, gy, gz) || inRange(tx, ty, tz); +} + + + +void GuardianRenderer::getInterpolatedPos(shared_ptr entity, double yOffset, + float partialTicks, + double &outX, double &outY, double &outZ) +{ + outX = entity->xo + (entity->x - entity->xo) * (double)partialTicks; + outY = yOffset + entity->yo + (entity->y - entity->yo) * (double)partialTicks; + outZ = entity->zo + (entity->z - entity->zo) * (double)partialTicks; +} + + + +void GuardianRenderer::setupRotations(shared_ptr _mob, float bob, + float bodyRot, float a) +{ + shared_ptr mob = dynamic_pointer_cast(_mob); + float bodyXRot = mob->xBodyRotO + (mob->xBodyRot - mob->xBodyRotO) * a; + + + glTranslatef(0, 1.2f, 0); + glRotatef(180.0f - bodyRot, 0, 1, 0); + glRotatef(bodyXRot, 1, 0, 0); + glTranslatef(0, -1.2f, 0); +} + + + +void GuardianRenderer::render(shared_ptr _mob, double x, double y, double z, + float rot, float a) +{ + + MobRenderer::render(_mob, x, y, z, rot, a); + + shared_ptr mob = dynamic_pointer_cast(_mob); + if (!mob || !mob->hasTargetedEntity()) return; + + shared_ptr target = mob->level->getEntity(mob->getTargetedEntityId()); + if (!target) { + target = mob->level->getNearestPlayer(mob->x, mob->y, mob->z, 64.0); + if (!target || target->entityId != mob->getTargetedEntityId()) return; + } + + + float f = mob->getAttackAnimationScale(a); + float time = (float)mob->tickCount + a; + float texVOff = -time * 0.2f - floor(-time * 0.1f); + float eyeHeight = mob->getEyeHeight(); + if (mob && mob->isElder()) + eyeHeight = mob->bbHeight * 0.5f * 2.35f; + + + double targetX = target->xo + (target->x - target->xo) * a; + double targetZ = target->zo + (target->z - target->zo) * a; + + double targetYBase = target->yo + (target->y - target->yo) * a; + double targetY = targetYBase - (target->bbHeight * 0.5f); + + + + double mobX = mob->xo + (mob->x - mob->xo) * a; + double mobY = mob->yo + (mob->y - mob->yo) * a + eyeHeight; + double mobZ = mob->zo + (mob->z - mob->zo) * a; + + double dx = targetX - mobX; + double dy = targetY - mobY; + double dz = targetZ - mobZ; + + double distOrizzontale = sqrt(dx * dx + dz * dz); + double distanzaTotale = sqrt(dx * dx + dy * dy + dz * dz); + + + bindTexture(&GUARDIAN_BEAM_LOCATION); + glDisable(GL_LIGHTING); + glDisable(GL_CULL_FACE); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDepthMask(true); + + glPushMatrix(); + glTranslatef((float)x, (float)y + eyeHeight, (float)z); + + + glRotatef((float)(atan2(dx, dz) * 180.0 / PI), 0, 1, 0); + glRotatef((float)(-atan2(dy, distOrizzontale) * 180.0 / PI), 1, 0, 0); + + Tesselator* t = Tesselator::getInstance(); + + + double r1 = 0.2; + double r2 = r1 * 1.41; + + double rotBeam = time * 0.05 * (1.0 - 2.5); + float f7 = f * f; + int red = (int)fmin(255, 64 + (int)(f7 * 240.0f)); + int green = (int)fmin(255, 32 + (int)(f7 * 192.0f)); + int blue = (int)fmax(0, fmin(255, 128 - (int)(f7 * 64.0f))); + + double vMin = 0.0 + texVOff; + double vMax = distanzaTotale * (0.5 / r1) + texVOff; + + + double d12 = cos(rotBeam + PI) * r1; + double d13 = sin(rotBeam + PI) * r1; + double d14 = cos(rotBeam + 0.0) * r1; + double d15 = sin(rotBeam + 0.0) * r1; + double d16 = cos(rotBeam + (PI / 2.0)) * r1; + double d17 = sin(rotBeam + (PI / 2.0)) * r1; + double d18 = cos(rotBeam + (PI * 3.0 / 2.0)) * r1; + double d19 = sin(rotBeam + (PI * 3.0 / 2.0)) * r1; + + + t->begin(); + t->color(red, green, blue, 255); + t->vertexUV(d12, d13, distanzaTotale, 0.4999, vMax); + t->vertexUV(d12, d13, 0.0, 0.4999, vMin); + t->vertexUV(d14, d15, 0.0, 0.0, vMin); + t->vertexUV(d14, d15, distanzaTotale, 0.0, vMax); + t->vertexUV(d16, d17, distanzaTotale, 0.4999, vMax); + t->vertexUV(d16, d17, 0.0, 0.4999, vMin); + t->vertexUV(d18, d19, 0.0, 0.0, vMin); + t->vertexUV(d18, d19, distanzaTotale, 0.0, vMax); + t->end(); + + + glDepthMask(false); + double d24 = (mob->tickCount % 2 == 0) ? 0.5 : 0.0; + + t->begin(); + t->color(red, green, blue, 64); + + double g1 = cos(rotBeam + 2.356) * r2; + double g2 = sin(rotBeam + 2.356) * r2; + double g3 = cos(rotBeam + 0.785) * r2; + double g4 = sin(rotBeam + 0.785) * r2; + double g5 = cos(rotBeam + 3.926) * r2; + double g6 = sin(rotBeam + 3.926) * r2; + double g7 = cos(rotBeam + 5.497) * r2; + double g8 = sin(rotBeam + 5.497) * r2; + + t->vertexUV(g1, g2, distanzaTotale, 0.5, d24 + 0.5); + t->vertexUV(g1, g2, 0.0, 0.5, d24); + t->vertexUV(g3, g4, 0.0, 1.0, d24); + t->vertexUV(g3, g4, distanzaTotale, 1.0, d24 + 0.5); + t->vertexUV(g7, g8, distanzaTotale, 1.0, d24 + 0.5); + t->vertexUV(g7, g8, 0.0, 1.0, d24); + t->vertexUV(g5, g6, 0.0, 0.5, d24); + t->vertexUV(g5, g6, distanzaTotale, 0.5, d24 + 0.5); + t->end(); + + glDepthMask(true); + glDisable(GL_BLEND); + glEnable(GL_LIGHTING); + glEnable(GL_CULL_FACE); + glPopMatrix(); +} + +void GuardianRenderer::renderModel(shared_ptr mob, float wp, float ws, float bob, + float headRotMinusBodyRot, float headRotx, float scale) +{ + shared_ptr guardian = dynamic_pointer_cast(mob); + if (guardian && guardian->isElder()) + { + glPushMatrix(); + + glTranslatef(0.0f, -2.0f, 0.0f); + glScalef(2.35f, 2.35f, 2.35f); + LivingEntityRenderer::renderModel(mob, wp, ws, bob, headRotMinusBodyRot, headRotx, scale); + glPopMatrix(); + } + else + { + LivingEntityRenderer::renderModel(mob, wp, ws, bob, headRotMinusBodyRot, headRotx, scale); + } +} \ No newline at end of file diff --git a/Minecraft.Client/GuardianRenderer.h b/Minecraft.Client/GuardianRenderer.h new file mode 100644 index 00000000..3b09d738 --- /dev/null +++ b/Minecraft.Client/GuardianRenderer.h @@ -0,0 +1,42 @@ +#pragma once +#include "MobRenderer.h" + +class GuardianModel; + +class GuardianRenderer : public MobRenderer +{ +private: + GuardianModel *guardianModel; + + static ResourceLocation GUARDIAN_LOCATION; + static ResourceLocation GUARDIAN_ELDER_LOCATION; + static ResourceLocation GUARDIAN_BEAM_LOCATION; + + + void getInterpolatedPos(shared_ptr entity, double yOffset, + float partialTicks, + double &outX, double &outY, double &outZ); + +public: + GuardianRenderer(Model *model, float shadow); + + + + +virtual bool shouldRender(shared_ptr mob, float camX, float camY, float camZ) override; + + virtual void render(shared_ptr mob, double x, double y, double z, + float rot, float a) override; + +protected: + + + + virtual void setupRotations(shared_ptr mob, float bob, + float bodyRot, float a) override; + + + virtual void renderModel(shared_ptr mob, float wp, float ws, float bob, + float headRotMinusBodyRot, float headRotx, float scale) override; + virtual ResourceLocation *getTextureLocation(shared_ptr mob) override; +}; \ No newline at end of file diff --git a/Minecraft.Client/Minecraft.cpp b/Minecraft.Client/Minecraft.cpp index 6e1074b0..b32ffd53 100644 --- a/Minecraft.Client/Minecraft.cpp +++ b/Minecraft.Client/Minecraft.cpp @@ -2646,6 +2646,28 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) case Item::writtenBook_Id: *piUse = IDS_TOOLTIPS_READ; break; + case Item::helmet_leather_Id: + case Item::helmet_chain_Id: + case Item::helmet_iron_Id: + case Item::helmet_gold_Id: + case Item::helmet_diamond_Id: + case Item::chestplate_leather_Id: + case Item::chestplate_chain_Id: + case Item::chestplate_iron_Id: + case Item::chestplate_gold_Id: + case Item::chestplate_diamond_Id: + case Item::leggings_leather_Id: + case Item::leggings_chain_Id: + case Item::leggings_iron_Id: + case Item::leggings_gold_Id: + case Item::leggings_diamond_Id: + case Item::boots_leather_Id: + case Item::boots_chain_Id: + case Item::boots_iron_Id: + case Item::boots_gold_Id: + case Item::boots_diamond_Id: + *piUse = IDS_TOOLTIPS_EQUIP; + break; } } diff --git a/Minecraft.Client/MobRenderer.cpp b/Minecraft.Client/MobRenderer.cpp index 7e1e3d85..7b841d3b 100644 --- a/Minecraft.Client/MobRenderer.cpp +++ b/Minecraft.Client/MobRenderer.cpp @@ -31,6 +31,17 @@ void MobRenderer::render(shared_ptr _mob, double x, double y, double z, renderLeash(mob, x, y, z, rot, a); } + +bool MobRenderer::shouldRender(shared_ptr entity, float camX, float camY, float camZ) +{ + + double dx = entity->x - camX; + double dy = entity->y - camY; + double dz = entity->z - camZ; + double distSq = dx*dx + dy*dy + dz*dz; + return entity->shouldRenderAtSqrDistance(distSq); +} + bool MobRenderer::shouldShowName(shared_ptr mob) { return LivingEntityRenderer::shouldShowName(mob) && (mob->shouldShowName() || dynamic_pointer_cast(mob)->hasCustomName()); diff --git a/Minecraft.Client/MobRenderer.h b/Minecraft.Client/MobRenderer.h index 6ab4af0c..798fc964 100644 --- a/Minecraft.Client/MobRenderer.h +++ b/Minecraft.Client/MobRenderer.h @@ -14,6 +14,7 @@ class MobRenderer : public LivingEntityRenderer public: MobRenderer(Model *model, float shadow); virtual void render(shared_ptr mob, double x, double y, double z, float rot, float a); + virtual bool shouldRender(shared_ptr entity, float camX, float camY, float camZ) override; protected: virtual bool shouldShowName(shared_ptr mob); diff --git a/Minecraft.Client/Model.cpp b/Minecraft.Client/Model.cpp index 63ba0c53..439cc2b7 100644 --- a/Minecraft.Client/Model.cpp +++ b/Minecraft.Client/Model.cpp @@ -6,7 +6,7 @@ Model::Model() { riding = false; - young=true; + young=false; //andi change texWidth=64; texHeight=32; } diff --git a/Minecraft.Client/ServerPlayerGameMode.cpp b/Minecraft.Client/ServerPlayerGameMode.cpp index 4e01d56a..67917f76 100644 --- a/Minecraft.Client/ServerPlayerGameMode.cpp +++ b/Minecraft.Client/ServerPlayerGameMode.cpp @@ -386,6 +386,7 @@ bool ServerPlayerGameMode::useItem(shared_ptr player, Level *level, shar player->inventory->items[player->inventory->selected] = itemInstance; if (isCreative()) { + //if (!(Item::items[itemInstance->id]->getBaseItemType() == 7 || Item::items[itemInstance->id]->getBaseItemType() == 8 || Item::items[itemInstance->id]->getBaseItemType() == 9 || Item::items[itemInstance->id]->getBaseItemType() == 10)) itemInstance->count = oldCount; if (itemInstance->isDamageableItem()) itemInstance->setAuxValue(oldAux); } diff --git a/Minecraft.Client/Textures.cpp b/Minecraft.Client/Textures.cpp index 6f0adf67..950e6a5b 100644 --- a/Minecraft.Client/Textures.cpp +++ b/Minecraft.Client/Textures.cpp @@ -191,6 +191,9 @@ const wchar_t *Textures::preLoaded[TN_COUNT] = L"mob/endermite", + L"mob/guardian", + L"mob/guardian_elder", + L"mob/guardian_beam", #ifdef _LARGE_WORLDS L"misc/additionalmapicons", diff --git a/Minecraft.Client/Textures.h b/Minecraft.Client/Textures.h index 0cbe036b..5f08fe57 100644 --- a/Minecraft.Client/Textures.h +++ b/Minecraft.Client/Textures.h @@ -177,6 +177,9 @@ typedef enum _TEXTURE_NAME TN_MOB_ENDERMITE, + TN_MOB_GUARDIAN, + TN_MOB_GUARDIAN_ELDER, + TN_MOB_GUARDIAN_BEAM, #ifdef _LARGE_WORLDS diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_chain1.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_chain1.ogg new file mode 100644 index 00000000..548ade93 Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_chain1.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_chain2.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_chain2.ogg new file mode 100644 index 00000000..ba21390f Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_chain2.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_chain3.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_chain3.ogg new file mode 100644 index 00000000..5daf5671 Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_chain3.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_chain4.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_chain4.ogg new file mode 100644 index 00000000..63d4cd32 Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_chain4.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_chain5.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_chain5.ogg new file mode 100644 index 00000000..6919e7d0 Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_chain5.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_chain6.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_chain6.ogg new file mode 100644 index 00000000..2a1a210b Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_chain6.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_diamond1.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_diamond1.ogg new file mode 100644 index 00000000..79d43b94 Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_diamond1.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_diamond2.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_diamond2.ogg new file mode 100644 index 00000000..5f71c986 Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_diamond2.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_diamond3.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_diamond3.ogg new file mode 100644 index 00000000..c5460e73 Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_diamond3.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_diamond4.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_diamond4.ogg new file mode 100644 index 00000000..e5adccad Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_diamond4.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_diamond5.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_diamond5.ogg new file mode 100644 index 00000000..77d64980 Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_diamond5.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_diamond6.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_diamond6.ogg new file mode 100644 index 00000000..bfe499bb Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_diamond6.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_generic1.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_generic1.ogg new file mode 100644 index 00000000..7f7f78f7 Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_generic1.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_generic2.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_generic2.ogg new file mode 100644 index 00000000..732f7819 Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_generic2.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_generic3.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_generic3.ogg new file mode 100644 index 00000000..5d0fb173 Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_generic3.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_generic4.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_generic4.ogg new file mode 100644 index 00000000..328a115d Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_generic4.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_generic5.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_generic5.ogg new file mode 100644 index 00000000..ee36a970 Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_generic5.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_generic6.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_generic6.ogg new file mode 100644 index 00000000..fe2e9efc Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_generic6.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_gold1.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_gold1.ogg new file mode 100644 index 00000000..c0bd9c98 Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_gold1.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_gold2.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_gold2.ogg new file mode 100644 index 00000000..3b60eb5c Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_gold2.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_gold3.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_gold3.ogg new file mode 100644 index 00000000..7844aa95 Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_gold3.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_gold4.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_gold4.ogg new file mode 100644 index 00000000..333583b9 Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_gold4.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_gold5.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_gold5.ogg new file mode 100644 index 00000000..c820ba3a Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_gold5.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_gold6.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_gold6.ogg new file mode 100644 index 00000000..21dbf985 Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_gold6.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_iron1.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_iron1.ogg new file mode 100644 index 00000000..829b3eb3 Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_iron1.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_iron2.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_iron2.ogg new file mode 100644 index 00000000..61dddefe Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_iron2.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_iron3.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_iron3.ogg new file mode 100644 index 00000000..0126098f Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_iron3.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_iron4.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_iron4.ogg new file mode 100644 index 00000000..7ac1a948 Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_iron4.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_iron5.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_iron5.ogg new file mode 100644 index 00000000..a3a9d0e9 Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_iron5.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_iron6.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_iron6.ogg new file mode 100644 index 00000000..1fdcb559 Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_iron6.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_leather1.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_leather1.ogg new file mode 100644 index 00000000..8e93a287 Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_leather1.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_leather2.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_leather2.ogg new file mode 100644 index 00000000..fd9bb6c5 Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_leather2.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_leather3.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_leather3.ogg new file mode 100644 index 00000000..73ad511a Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_leather3.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_leather4.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_leather4.ogg new file mode 100644 index 00000000..234518e6 Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_leather4.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_leather5.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_leather5.ogg new file mode 100644 index 00000000..6e27779a Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_leather5.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_leather6.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_leather6.ogg new file mode 100644 index 00000000..a6bb8c1f Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/item/armor/equip_leather6.ogg differ diff --git a/Minecraft.Client/cmake/sources/Common.cmake b/Minecraft.Client/cmake/sources/Common.cmake index cbe3372d..1c45883e 100644 --- a/Minecraft.Client/cmake/sources/Common.cmake +++ b/Minecraft.Client/cmake/sources/Common.cmake @@ -624,6 +624,8 @@ set(_MINECRAFT_CLIENT_COMMON_NET_MINECRAFT_CLIENT_MODEL "${CMAKE_CURRENT_SOURCE_DIR}/ArmorStandModel.h" "${CMAKE_CURRENT_SOURCE_DIR}/EndermiteModel.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/EndermiteModel.h" + "${CMAKE_CURRENT_SOURCE_DIR}/GuardianModel.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/GuardianModel.h" ) source_group("net/minecraft/client/model" FILES ${_MINECRAFT_CLIENT_COMMON_NET_MINECRAFT_CLIENT_MODEL}) @@ -901,6 +903,8 @@ set(_MINECRAFT_CLIENT_COMMON_NET_MINECRAFT_CLIENT_RENDERER_ENTITY "${CMAKE_CURRENT_SOURCE_DIR}/RabbitRenderer.h" "${CMAKE_CURRENT_SOURCE_DIR}/ArmorStandRenderer.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/EndermiteRenderer.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/GuardianRenderer.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/GuardianRenderer.h" ) source_group("net/minecraft/client/renderer/entity" FILES ${_MINECRAFT_CLIENT_COMMON_NET_MINECRAFT_CLIENT_RENDERER_ENTITY}) diff --git a/Minecraft.Client/glWrapper.cpp b/Minecraft.Client/glWrapper.cpp index c49620aa..e447d32b 100644 --- a/Minecraft.Client/glWrapper.cpp +++ b/Minecraft.Client/glWrapper.cpp @@ -389,4 +389,9 @@ void glTexGen(int coord, int mode, FloatBuffer *vec) void glCullFace(int dir) { RenderManager.StateSetFaceCullCW( dir == GL_BACK); -} \ No newline at end of file +} + +void glTexParameterf(int target, int param, float value) +{ + RenderManager.TextureSetParam(param, (int)value); +} diff --git a/Minecraft.Client/stubs.h b/Minecraft.Client/stubs.h index 10ba2d05..60aa4885 100644 --- a/Minecraft.Client/stubs.h +++ b/Minecraft.Client/stubs.h @@ -114,7 +114,7 @@ void glFogf(int,float); void glFog(int,FloatBuffer *); void glColorMaterial(int,int); void glMultiTexCoord2f(int, float, float); - +void glTexParameterf(int target, int param, float value); //1.8.2 void glClientActiveTexture(int); void glActiveTexture(int); diff --git a/Minecraft.World/ArmorItem.cpp b/Minecraft.World/ArmorItem.cpp index 0bd6111b..51bf3def 100644 --- a/Minecraft.World/ArmorItem.cpp +++ b/Minecraft.World/ArmorItem.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include #include "../Minecraft.Client/Minecraft.h" #include "net.minecraft.world.h" #include "net.minecraft.world.level.tile.h" @@ -128,6 +129,54 @@ ArmorItem::ArmorItem(int id, const ArmorMaterial *armorType, int icon, int slot) DispenserTile::REGISTRY.add(this, new ArmorDispenseItemBehavior()); } +shared_ptr ArmorItem::use(shared_ptr instance, Level* level, shared_ptr player) { + int slot = Mob::getEquipmentSlotForItem(instance) - 1; + + // If player is in survival mode (not creative) + if (!player->abilities.instabuild) { // + // Equip the armor to the appropriate slot + ItemInstance copy = *instance->copy_not_shared(); + if (player->inventory->armor[slot] == nullptr) { + player->inventory->armor[slot] = make_shared(copy); + player->inventory->removeItemNoUpdate(player->inventory->selected); + // Remove the item from hand (set count to 0) + instance->count = 0; + } + else { + player->inventory->setItem(player->inventory->selected, player->inventory->armor[slot]); + player->inventory->armor[slot] = make_shared(copy); + } + } + else { + ItemInstance copy = *instance->copy_not_shared(); + if (player->inventory->armor[slot] == nullptr) { + player->inventory->armor[slot] = make_shared(copy); + } + else { + player->inventory->setItem(player->inventory->selected, player->inventory->armor[slot]); + player->inventory->armor[slot] = make_shared(copy); + } + } + + int material = Item::items[instance->id]->getMaterial(); + int lo, hi; + switch (material) { + case Item::eMaterial_cloth: lo = 194; hi = 199; break; + case Item::eMaterial_chain: lo = 200; hi = 205; break; + case Item::eMaterial_iron: lo = 206; hi = 211; break; + case Item::eMaterial_gold: lo = 212; hi = 217; break; + case Item::eMaterial_diamond: lo = 218; hi = 223; break; + default: lo = 224; hi = 229; break; + } + + std::mt19937 rng(std::random_device{}()); + std::uniform_int_distribution dist(lo, hi); + player->playSound(dist(rng), 0.5f, 1.0f); + + // Return the (now empty) instance + return instance; +} + int ArmorItem::getColor(shared_ptr item, int spriteLayer) { if (spriteLayer > 0) diff --git a/Minecraft.World/ArmorItem.h b/Minecraft.World/ArmorItem.h index 92a40aea..7d976aee 100644 --- a/Minecraft.World/ArmorItem.h +++ b/Minecraft.World/ArmorItem.h @@ -87,5 +87,7 @@ public: virtual bool isValidRepairItem(shared_ptr source, shared_ptr repairItem); virtual void registerIcons(IconRegister *iconRegister); + virtual shared_ptr use(shared_ptr instance, Level* level, shared_ptr player); + static Icon *getEmptyIcon(int slot); }; \ No newline at end of file diff --git a/Minecraft.World/Class.h b/Minecraft.World/Class.h index b4ac588b..058cffd9 100644 --- a/Minecraft.World/Class.h +++ b/Minecraft.World/Class.h @@ -168,9 +168,11 @@ enum eINSTANCEOF eTYPE_BLAZE = eTYPE_MONSTER | eTYPE_VALID_IN_SPAWNER_FLAG | 0x6, eTYPE_WITCH = eTYPE_MONSTER | eTYPE_VALID_IN_SPAWNER_FLAG | 0x7, eTYPE_WITHERBOSS = eTYPE_MONSTER | eTYPE_VALID_IN_SPAWNER_FLAG | 0x8, + eTYPE_GUARDIAN = eTYPE_MONSTER | eTYPE_VALID_IN_SPAWNER_FLAG | 0x9, eTYPE_ENDERMITE = eTYPE_MONSTER | eTYPE_VALID_IN_SPAWNER_FLAG | 0x10, + eTYPE_ELDER_GUARDIAN = eTYPE_MONSTER | eTYPE_VALID_IN_SPAWNER_FLAG | 0x11, eTYPE_AMBIENT = eTYPE_MOB | BIT_AMBIENT_MOB, diff --git a/Minecraft.World/Enchantment.h b/Minecraft.World/Enchantment.h index d7bbca58..e4fd4ad2 100644 --- a/Minecraft.World/Enchantment.h +++ b/Minecraft.World/Enchantment.h @@ -84,8 +84,9 @@ public: virtual int getDescriptionId(); virtual HtmlString getFullname(int level); virtual bool canEnchant(shared_ptr item); - -private: // 4J Added wstring getLevelString(int level); + +private: + }; \ No newline at end of file diff --git a/Minecraft.World/EnchantmentContainer.cpp b/Minecraft.World/EnchantmentContainer.cpp index 068b6672..901767d5 100644 --- a/Minecraft.World/EnchantmentContainer.cpp +++ b/Minecraft.World/EnchantmentContainer.cpp @@ -2,19 +2,22 @@ #include "net.minecraft.world.inventory.h" #include "EnchantmentContainer.h" -EnchantmentContainer::EnchantmentContainer(EnchantmentMenu *menu) : SimpleContainer(IDS_ENCHANT, L"", false, 1), m_menu( menu ) + + +EnchantmentContainer::EnchantmentContainer(EnchantmentMenu *menu, int size) : SimpleContainer(IDS_ENCHANT, L"", false, 2), m_menu( menu ) { + MAX_STACK_SIZE = size; } int EnchantmentContainer::getMaxStackSize() const { - return 1; + return MAX_STACK_SIZE; } void EnchantmentContainer::setChanged() { SimpleContainer::setChanged(); - m_menu->slotsChanged(); // Remove this param as it's not needed + m_menu->slotsChanged(MAX_STACK_SIZE); } bool EnchantmentContainer::canPlaceItem(int slot, shared_ptr item) diff --git a/Minecraft.World/EnchantmentContainer.h b/Minecraft.World/EnchantmentContainer.h index 4ccbea69..5e17ee1b 100644 --- a/Minecraft.World/EnchantmentContainer.h +++ b/Minecraft.World/EnchantmentContainer.h @@ -12,7 +12,9 @@ class EnchantmentContainer : public SimpleContainer private: EnchantmentMenu *m_menu; public: - EnchantmentContainer(EnchantmentMenu *menu); + int MAX_STACK_SIZE; + + EnchantmentContainer(EnchantmentMenu *menu, int size = 1); virtual int getMaxStackSize() const; virtual void setChanged(); virtual bool canPlaceItem(int slot, shared_ptr item); diff --git a/Minecraft.World/EnchantmentMenu.cpp b/Minecraft.World/EnchantmentMenu.cpp index 6af7113a..f468907c 100644 --- a/Minecraft.World/EnchantmentMenu.cpp +++ b/Minecraft.World/EnchantmentMenu.cpp @@ -6,11 +6,15 @@ #include "net.minecraft.world.item.h" #include "net.minecraft.world.item.enchantment.h" #include "EnchantmentMenu.h" +#include "../../../Minecraft.Client/ServerPlayer.h" +#include "../../../Minecraft.Client/MinecraftServer.h" +#include "../../../Minecraft.Client/PlayerList.h" EnchantmentMenu::EnchantmentMenu(shared_ptr inventory, Level *level, int xt, int yt, int zt) { enchantSlots = std::make_shared(this); - + lapisSlot = std::make_shared(this, 64); + playerT = inventory->player; for(int i = 0; i < 3; ++i) { costs[i] = 0; @@ -21,6 +25,7 @@ EnchantmentMenu::EnchantmentMenu(shared_ptr inventory, Level *level, y = yt; z = zt; addSlot(new EnchantmentSlot(enchantSlots, 0, 21 + 4, 43 + 4)); + addSlot(new EnchantmentSlot(lapisSlot, 1, 40 + 4, 43 + 4)); for (int y = 0; y < 3; y++) { @@ -53,6 +58,9 @@ void EnchantmentMenu::broadcastChanges() // 4J Added m_costsChanged to stop continually sending update packets even when no changes have been made if(m_costsChanged) { + /*if (EnchantmentMenu::lapisSlot->getItem(1) == nullptr) { + return; + }*/ for (size_t i = 0; i < containerListeners.size(); i++) { ContainerListener *listener = containerListeners.at(i); @@ -77,22 +85,31 @@ void EnchantmentMenu::setData(int id, int value) } } -void EnchantmentMenu::slotsChanged() // 4J used to take a shared_ptr container but wasn't using it, so removed to simplify things +vector EnchantmentMenu::getEnchantment() { + random.setSeed(playerT->enchantmentSeed); + shared_ptr item = enchantSlots->getItem(0); + return *EnchantmentHelper::selectEnchantment(&random, item, costs[2]); +} + +void EnchantmentMenu::slotsChanged(int a) // 4J used to take a shared_ptr container but wasn't using it, so removed to simplify things { shared_ptr item = enchantSlots->getItem(0); + shared_ptr lapis = lapisSlot->getItem(1); + if (item == nullptr || !item->isEnchantable()) { for (int i = 0; i < 3; i++) { + tempCosts[i] = costs[i]; costs[i] = 0; } m_costsChanged = true; + alreadyRan = false; + } else { - nameSeed = random.nextLong(); - if (!level->isClientSide) { // find book cases @@ -139,15 +156,30 @@ void EnchantmentMenu::slotsChanged() // 4J used to take a shared_ptr } } } + bookcasesC = bookcases; + random.setSeed(playerT->enchantmentSeed); for (int i = 0; i < 3; i++) { costs[i] = EnchantmentHelper::getEnchantmentCost(&random, i, bookcases, item); } + if (!alreadyRan) { + en = false; + for (int i = 0; i < 3; i++) + { + //delete cachedEnchantments[i]; // clean up old one first <- doing it elsewhere + cachedEnchantments[i] = EnchantmentHelper::selectEnchantment(&random, item, costs[i]); + } + + } + + alreadyRan = true; m_costsChanged = true; broadcastChanges(); } } + + wasLapis = lapis != nullptr; } bool EnchantmentMenu::clickMenuButton(shared_ptr player, int i) @@ -155,44 +187,86 @@ bool EnchantmentMenu::clickMenuButton(shared_ptr player, int i) shared_ptr item = enchantSlots->getItem(0); if (costs[i] > 0 && item != nullptr && (player->experienceLevel >= costs[i] || player->abilities.instabuild) ) { + bool enough = getLapisCount() >= i+1; + if (!enough && !player->abilities.instabuild) return false; if (!level->isClientSide) { bool isBook = item->id == Item::book_Id; - vector *newEnchantment = EnchantmentHelper::selectEnchantment(&random, item, costs[i]); + vector *newEnchantment = cachedEnchantments[i]; if (newEnchantment != nullptr) { + player->giveExperienceLevels(-costs[i]); if (isBook) item->id = Item::enchantedBook_Id; int randomIndex = isBook ? random.nextInt(newEnchantment->size()) : -1; - //for (EnchantmentInstance e : newEnchantment) + for (int index = 0; index < newEnchantment->size(); index++) { - EnchantmentInstance *e = newEnchantment->at(index); - if (isBook && index != randomIndex) - {} + EnchantmentInstance* e = newEnchantment->at(index); + if (isBook) + { + Item::enchantedBook->addEnchantment(item, e); + en = true; + } else { - if (isBook) - { - Item::enchantedBook->addEnchantment(item, e); - } - else - { - item->enchant(e->enchantment, e->level); - } + item->enchant(e->enchantment, e->level); + en = true; } delete e; } delete newEnchantment; - slotsChanged();// Removed enchantSlots parameter as the function can reference it directly + slotsChanged(1);// Removed enchantSlots parameter as the function can reference it directly } } + if (!player->abilities.instabuild) lapisSlot->removeItem(1, i+1); + nameSeed = (long)nameSeed + random.nextInt(10000); + player->enchantmentSeed = random.nextInt(1000000); + alreadyRan = false; return true; } return false; } +EnchantmentInstance* EnchantmentMenu::predictEnchantment(shared_ptr player, int i) +{ + shared_ptr item = enchantSlots->getItem(0); + if (costs[i] > 0 && item != nullptr && (player->experienceLevel >= costs[i] || player->abilities.instabuild)) + { + if (0 == 0) + { + bool isBook = item->id == Item::book_Id; + Random tempRandom = random; + vector* newEnchantment = cachedEnchantments[i]; + if (newEnchantment != nullptr) + { + int randomIndex = isBook ? tempRandom.nextInt(newEnchantment->size()) : -1; + for (int index = 0; index < newEnchantment->size(); index++) + { + EnchantmentInstance* e = newEnchantment->at(index); + if (isBook) + { + return e; + //en = true; + } + else + { + //item->enchant(e->enchantment, e->level); + return e; + //en = true; + } + //delete e; + } + //delete newEnchantment; + //slotsChanged(1);// Removed enchantSlots parameter as the function can reference it directly + } + } + return nullptr; + } + return nullptr; +} + void EnchantmentMenu::removed(shared_ptr player) { @@ -204,6 +278,11 @@ void EnchantmentMenu::removed(shared_ptr player) { player->drop(item); } + item = lapisSlot->removeItemNoUpdate(1); + if (item != nullptr) + { + player->drop(item); + } } bool EnchantmentMenu::stillValid(shared_ptr player) @@ -213,6 +292,11 @@ bool EnchantmentMenu::stillValid(shared_ptr player) return true; } +int EnchantmentMenu::getLapisCount() { + if (lapisSlot->getItem(1) == nullptr) return 0; + return lapisSlot->getItem(1)->count; +} + shared_ptr EnchantmentMenu::quickMoveStack(shared_ptr player, int slotIndex) { if (slotIndex < 0 || slotIndex >= static_cast(slots.size())) @@ -223,10 +307,15 @@ shared_ptr EnchantmentMenu::quickMoveStack(shared_ptr play shared_ptr clicked = nullptr; Slot *slot = slots.at(slotIndex); Slot *IngredientSlot = nullptr; + Slot *LapisSlot = nullptr; if (INGREDIENT_SLOT >= 0 && INGREDIENT_SLOT < static_cast(slots.size())) { IngredientSlot = slots.at(INGREDIENT_SLOT); } + if (LAPIS_SLOT >= 0 && LAPIS_SLOT < static_cast(slots.size())) + { + LapisSlot = slots.at(LAPIS_SLOT); + } if (slot != nullptr && slot->hasItem()) { @@ -244,6 +333,16 @@ shared_ptr EnchantmentMenu::quickMoveStack(shared_ptr play } } + else if (slotIndex == LAPIS_SLOT) { + if (!moveItemStackTo(stack, INV_SLOT_START, INV_SLOT_END, true)) + { + if (!moveItemStackTo(stack, USE_ROW_SLOT_START, USE_ROW_SLOT_END, false)) + { + return nullptr; + } + + } + } else if (slotIndex >= INV_SLOT_START && slotIndex < INV_SLOT_END) { // if the item is an enchantable tool @@ -255,6 +354,14 @@ shared_ptr EnchantmentMenu::quickMoveStack(shared_ptr play return nullptr; } } + //DyePowderItem::BLACK + else if (stack->getItem()->id == 351 && stack->getItem()->getMaterial() == 11) + { + if(!moveItemStackTo(stack, LAPIS_SLOT, LAPIS_SLOT+1, false)) + { + return nullptr; + } + } else { if(!moveItemStackTo(stack, USE_ROW_SLOT_START, USE_ROW_SLOT_END, false)) @@ -274,6 +381,13 @@ shared_ptr EnchantmentMenu::quickMoveStack(shared_ptr play return nullptr; } } + else if (stack->getItem()->id == 351 && stack->getItem()->getMaterial() == 11) + { + if (!moveItemStackTo(stack, LAPIS_SLOT, LAPIS_SLOT + 1, false)) + { + return nullptr; + } + } else { if(!moveItemStackTo(stack, INV_SLOT_START, INV_SLOT_END, false)) diff --git a/Minecraft.World/EnchantmentMenu.h b/Minecraft.World/EnchantmentMenu.h index 62408f1d..ee53608b 100644 --- a/Minecraft.World/EnchantmentMenu.h +++ b/Minecraft.World/EnchantmentMenu.h @@ -1,40 +1,57 @@ #pragma once #include "AbstractContainerMenu.h" #include "Random.h" +#include "EnchantmentInstance.h" class EnchantmentMenu : public AbstractContainerMenu { // 4J Stu Made these public for UI menus, perhaps should make friend class? public: static const int INGREDIENT_SLOT = 0; - static const int INV_SLOT_START = EnchantmentMenu::INGREDIENT_SLOT + 1; + static const int LAPIS_SLOT = 1; + static const int INV_SLOT_START = EnchantmentMenu::INGREDIENT_SLOT + 2; static const int INV_SLOT_END = EnchantmentMenu::INV_SLOT_START + 9 * 3; static const int USE_ROW_SLOT_START = EnchantmentMenu::INV_SLOT_END; static const int USE_ROW_SLOT_END = EnchantmentMenu::USE_ROW_SLOT_START + 9; public: shared_ptr enchantSlots; + shared_ptr lapisSlot; + bool alreadyRan = false; + bool en = false; + // Header + std::vector* cachedEnchantments[3] = { nullptr, nullptr, nullptr }; + int getLapisCount(); + //int iPad; + Player* playerT; private: Level *level; int x, y, z; - Random random; + bool m_costsChanged; // 4J Added + int bookcasesC = -1; public: int64_t nameSeed; - + bool wasLapis; + + Random random; public: int costs[3]; + int tempCosts[3]; + EnchantmentMenu(shared_ptr inventory, Level *level, int xt, int yt, int zt); virtual void addSlotListener(ContainerListener *listener); virtual void broadcastChanges(); + vector getEnchantment(); virtual void setData(int id, int value); - virtual void slotsChanged();// 4J used to take a shared_ptr container but wasn't using it, so removed to simplify things + virtual void slotsChanged(int a);// 4J used to take a shared_ptr container but wasn't using it, so removed to simplify things virtual bool clickMenuButton(shared_ptr player, int i); + virtual EnchantmentInstance* predictEnchantment(shared_ptr player, int i); void removed(shared_ptr player); virtual bool stillValid(shared_ptr player); virtual shared_ptr quickMoveStack(shared_ptr player, int slotIndex); diff --git a/Minecraft.World/EntityIO.cpp b/Minecraft.World/EntityIO.cpp index 7b67d8fe..3d5eec44 100644 --- a/Minecraft.World/EntityIO.cpp +++ b/Minecraft.World/EntityIO.cpp @@ -46,7 +46,7 @@ void EntityIO::staticCtor() { setId(ItemEntity::create, eTYPE_ITEMENTITY, L"Item", 1); setId(ExperienceOrb::create, eTYPE_EXPERIENCEORB, L"XPOrb", 2); - + setId(Guardian::create, eTYPE_ELDER_GUARDIAN, L"ElderGuardian", 4, eMinecraftColour_Armour_Default_Leather_Colour, eMinecraftColour_Sky_IceMountains, IDS_PIGZOMBIE); setId(LeashFenceKnotEntity::create, eTYPE_LEASHFENCEKNOT, L"LeashKnot", 8); setId(Painting::create, eTYPE_PAINTING, L"Painting", 9); setId(Arrow::create, eTYPE_ARROW, L"Arrow", 10); @@ -95,6 +95,12 @@ void EntityIO::staticCtor() setId(WitherBoss::create, eTYPE_WITHERBOSS, L"WitherBoss", 64); setId(Bat::create, eTYPE_BAT, L"Bat", 65, eMinecraftColour_Mob_Bat_Colour1, eMinecraftColour_Mob_Bat_Colour2, IDS_BAT); setId(Witch::create, eTYPE_WITCH, L"Witch", 66, eMinecraftColour_Mob_Witch_Colour1, eMinecraftColour_Mob_Witch_Colour2, IDS_WITCH); + + setId(Endermite::create, eTYPE_ENDERMITE, L"Endermite", 67, + eMinecraftColour_Mob_Endermite_Colour1, + eMinecraftColour_Mob_Endermite_Colour2, IDS_ENDERMITE); + + setId(Guardian::create, eTYPE_GUARDIAN, L"Guardian", 68, eMinecraftColour_Mob_Witch_Colour1, eMinecraftColour_Mob_Witch_Colour2, IDS_WITCH); setId(Pig::create, eTYPE_PIG, L"Pig", 90, eMinecraftColour_Mob_Pig_Colour1, eMinecraftColour_Mob_Pig_Colour2, IDS_PIG); @@ -114,9 +120,7 @@ void EntityIO::staticCtor() setId(ArmorStand::create, eTYPE_ARMORSTAND, L"ArmorStand", 102); - setId(Endermite::create, eTYPE_ENDERMITE, L"Endermite", 67, - eMinecraftColour_Mob_Endermite_Colour1, - eMinecraftColour_Mob_Endermite_Colour2, IDS_ENDERMITE);//change IDS_Endermite later + //change IDS_Endermite later setId(Villager::create, eTYPE_VILLAGER, L"Villager", 120, eMinecraftColour_Mob_Villager_Colour1, eMinecraftColour_Mob_Villager_Colour2, IDS_VILLAGER); diff --git a/Minecraft.World/Guardian.cpp b/Minecraft.World/Guardian.cpp new file mode 100644 index 00000000..d44644e5 --- /dev/null +++ b/Minecraft.World/Guardian.cpp @@ -0,0 +1,480 @@ +#include "stdafx.h" +#include "com.mojang.nbt.h" +#include "net.minecraft.world.level.tile.h" +#include "net.minecraft.world.phys.h" +#include "net.minecraft.world.level.h" +#include "net.minecraft.world.item.h" +#include "net.minecraft.world.entity.h" +#include "net.minecraft.world.entity.player.h" +#include "net.minecraft.world.entity.ai.attributes.h" +#include "net.minecraft.world.entity.monster.h" +#include "net.minecraft.world.damagesource.h" +#include "SharedConstants.h" +#include "Guardian.h" +#include "..\Minecraft.Client\Textures.h" +#include "..\Minecraft.World\Mth.h" +#include "..\Minecraft.World\net.minecraft.world.entity.animal.h" +#include "MobEffect.h" +#include "MobEffectInstance.h" + + +void Guardian::_init() +{ + clientSideTailAnimation = 0.0f; + clientSideTailAnimationO = 0.0f; + clientSideSpikesAnimation = 0.0f; + clientSideSpikesAnimationO = 0.0f; + clientSideAttackTime = 0.0f; + clientSideTouchedGround = false; + + xBodyRot = xBodyRotO = 0.0f; + zBodyRot = zBodyRotO = 0.0f; + + tx = ty = tz = 0.0f; + attackTimer = 0; +} + +Guardian::Guardian(Level *level) : WaterAnimal(level) +{ + this->defineSynchedData(); + registerAttributes(); + setHealth(getMaxHealth()); + _init(); + if (isElder()) { + this->setSize(1.9975f, 1.9975f); + } + else { + this->setSize(0.85f, 0.85f); + } +} + + + +void Guardian::registerAttributes() +{ + WaterAnimal::registerAttributes(); + getAttributes()->registerAttribute(SharedMonsterAttributes::ATTACK_DAMAGE); + getAttribute(SharedMonsterAttributes::ATTACK_DAMAGE)->setBaseValue(6.0); + getAttribute(SharedMonsterAttributes::MOVEMENT_SPEED)->setBaseValue(0.5); + getAttribute(SharedMonsterAttributes::FOLLOW_RANGE)->setBaseValue(16.0); + getAttribute(SharedMonsterAttributes::MAX_HEALTH)->setBaseValue(30.0); +} + + + +void Guardian::defineSynchedData() +{ + WaterAnimal::defineSynchedData(); + entityData->define(16, (byte)0); + entityData->define(17, 0); +} + + +// NBT + + +void Guardian::readAdditionalSaveData(CompoundTag *tag) +{ + WaterAnimal::readAdditionalSaveData(tag); + setElder(tag->getBoolean(L"Elder")); +} + +void Guardian::addAdditonalSaveData(CompoundTag *tag) +{ + WaterAnimal::addAdditonalSaveData(tag); + tag->putBoolean(L"Elder", isElder()); +} + + + +bool Guardian::isElder() +{ + return (entityData->getByte(16) & 4) != 0; +} + +void Guardian::setElder(bool elder) +{ + byte flags = entityData->getByte(16); + if (elder) + { + entityData->set(16, (byte)(flags | 4)); + + + this->setSize(1.9975f, 1.9975f); + getAttribute(SharedMonsterAttributes::MOVEMENT_SPEED)->setBaseValue(0.30000001192092896); + getAttribute(SharedMonsterAttributes::ATTACK_DAMAGE)->setBaseValue(8.0); + getAttribute(SharedMonsterAttributes::MAX_HEALTH)->setBaseValue(80.0); + setHealth(getMaxHealth()); + } + else + { + entityData->set(16, (byte)(flags & ~4)); + this->setSize(0.85f, 0.85f); + } +} + + +void Guardian::setElderClient() +{ + setElder(true); + clientSideSpikesAnimation = clientSideSpikesAnimationO = 1.0f; +} + +bool Guardian::isMoving() +{ + return (entityData->getByte(16) & 2) != 0; +} + +void Guardian::setMoving(bool moving) +{ + byte flags = entityData->getByte(16); + if (moving) + entityData->set(16, (byte)(flags | 2)); + else + entityData->set(16, (byte)(flags & ~2)); +} + + + +int Guardian::getTargetedEntityId() +{ + return entityData->getInteger(17); +} + +void Guardian::setTargetedEntityId(int id) +{ + entityData->set(17, id); + entityData->markDirty(17); +} + +bool Guardian::hasTargetedEntity() +{ + return entityData->getInteger(17) != 0; +} + +shared_ptr Guardian::getTargetedEntity() +{ + if (!hasTargetedEntity()) + return nullptr; + + if (level->isClientSide) + { + if (targetedEntity != nullptr) + return targetedEntity; + + shared_ptr entity = level->getEntity(getTargetedEntityId()); + if (entity != nullptr && dynamic_pointer_cast(entity)) + { + targetedEntity = dynamic_pointer_cast(entity); + return targetedEntity; + } + return nullptr; + } + + shared_ptr e = level->getEntity(getTargetedEntityId()); + return dynamic_pointer_cast(e); +} + + + +int Guardian::getAttackDuration() +{ + // Java func_175464_ck + return isElder() ? 60 : 80; +} + +float Guardian::getAttackAnimationScale(float partialTicks) +{ + return (clientSideAttackTime + partialTicks) / (float)getAttackDuration(); +} + +// Java func_175471_a +float Guardian::getTailAnimation(float partialTicks) +{ + return clientSideSpikesAnimationO + (clientSideSpikesAnimation - clientSideSpikesAnimationO) * partialTicks; +} + +// Java func_175469_o +float Guardian::getSpikesAnimation(float partialTicks) +{ + return isMoving() ? 1.0f : 0.0f; +} + + + +int Guardian::getAmbientSound() { return -1; } +int Guardian::getHurtSound() { return -1; } +int Guardian::getDeathSound() { return -1; } +float Guardian::getSoundVolume() { return 1.0f; } +int Guardian::getDeathLoot() { return 0; } +bool Guardian::makeStepSound() { return false; } + +void Guardian::dropDeathLoot(bool wasKilledByPlayer, int playerBonusLevel) +{ + //loot (prismarine, sponge) +} + +float Guardian::getEyeHeight() +{ + return bbHeight * 0.5f; +} + +bool Guardian::isInWater() +{ + return level->checkAndHandleWater(bb->grow(0, -0.6f, 0), Material::water, shared_from_this()); +} + +float Guardian::rotlerp(float a, float b, float max) +{ + float f = Mth::wrapDegrees(b - a); + if (f > max) f = max; + if (f < -max) f = -max; + return a + f; +} + +void Guardian::lookAt(shared_ptr e, float yMax, float xMax) +{ + double d0 = e->x - x; + double d1 = e->z - z; + double d2; + + if (dynamic_pointer_cast(e)) + { + shared_ptr living = dynamic_pointer_cast(e); + d2 = living->y + living->getEyeHeight() - (y + getEyeHeight()); + } + else + { + d2 = (e->bb->y0 + e->bb->y1) / 2.0 - (y + getEyeHeight()); + } + + double d3 = sqrt(d0 * d0 + d1 * d1); + float f = (float)(atan2(d1, d0) * 180.0 / PI) - 90.0f; + float f1 = (float)(-(atan2(d2, d3) * 180.0 / PI)); + xRot = rotlerp(xRot, f1, xMax); + yRot = rotlerp(yRot, f, yMax); +} + + + +void Guardian::serverAiStep() +{ + WaterAnimal::serverAiStep(); + + if (isElder() && !level->isClientSide) + { + if (((tickCount + entityId) % 1200 == 0)) + { + auto& players = level->players; + for (int i = 0; i < (int)players.size(); i++) + { + shared_ptr player = players[i]; + if (!player) continue; + + if (distanceToSqr(player) >= 2500.0) + continue; + + if (player->abilities.invulnerable) + continue; + + + MobEffectInstance *existing = player->getEffect(MobEffect::digSlowdown); + if (existing == nullptr || existing->getAmplifier() < 2 || existing->getDuration() < 1200) + { + player->addEffect(new MobEffectInstance(MobEffect::digSlowdown->id, 6000, 2)); + } + } + } + } + + + if (!hasTargetedEntity()) + { + shared_ptr nearest = level->getNearestPlayer(x, y, z, 16.0); + if (nearest != nullptr && canSee(nearest) && !nearest->abilities.invulnerable) + { + setTargetedEntityId(nearest->entityId); + attackTimer = 0; + } + } + + shared_ptr target = getTargetedEntity(); + if (target != nullptr) + { + if (!target->isAlive() || distanceToSqr(target) > 256.0 || !canSee(target)) + { + setTargetedEntityId(0); + target = nullptr; + } + } + + if (target != nullptr) + { + lookAt(target, 90.0f, 90.0f); + setMoving(false); + tx = ty = tz = 0.0f; + + attackTimer++; + + + if (attackTimer == 1) + { + level->broadcastEntityEvent(shared_from_this(), 21); + } + else if (attackTimer >= getAttackDuration()) + { + + float dmg = 1.0f; + if (isElder()) dmg += 2.0f; + + target->hurt(DamageSource::mobAttack(dynamic_pointer_cast(shared_from_this())), dmg); + target->hurt(DamageSource::magic, + (float)getAttribute(SharedMonsterAttributes::ATTACK_DAMAGE)->getValue()); + + setTargetedEntityId(0); + attackTimer = 0; + } + } + else + { + + attackTimer = 0; + setTargetedEntityId(0); + + noActionTime++; + if (noActionTime > 100 || random->nextInt(50) == 0 || + (tx == 0.0f && ty == 0.0f && tz == 0.0f)) + { + float angle = random->nextFloat() * (float)PI * 2.0f; + tx = Mth::cos(angle) * 0.2f; + ty = -0.1f + random->nextFloat() * 0.2f; + tz = Mth::sin(angle) * 0.2f; + noActionTime = 0; + } + + setMoving(true); + } + + + if (isMoving()) + { + xd += (tx - xd) * 0.1f; + yd += (ty - yd) * 0.1f; + zd += (tz - zd) * 0.1f; + + double horizontalMovement = sqrt(xd * xd + zd * zd); + yBodyRot += ((-static_cast(atan2(xd, zd)) * 180.0f / (float)PI) - yBodyRot) * 0.1f; + yRot = yBodyRot; + zBodyRot = zBodyRot + (float)PI * 0.05f; + xBodyRot += ((-static_cast(atan2(horizontalMovement, yd)) * 180.0f / (float)PI) - xBodyRot) * 0.1f; + } +} + + + +void Guardian::aiStep() +{ + if (level->isClientSide) + { + clientSideTailAnimationO = clientSideTailAnimation; + + if (!isInWater()) + { + clientSideTailAnimation = 2.0f; + clientSideTouchedGround = yd < 0.0 && + level->hasChunkAt(Mth::floor(x), Mth::floor(y - 1), Mth::floor(z)); + } + else if (isMoving()) + { + if (clientSideTailAnimation < 0.5f) + clientSideTailAnimation = 4.0f; + else + clientSideTailAnimation += (0.5f - clientSideTailAnimation) * 0.1f; + } + else + { + clientSideTailAnimation += (0.125f - clientSideTailAnimation) * 0.2f; + } + + clientSideSpikesAnimationO = clientSideSpikesAnimation; + clientSideSpikesAnimation += clientSideTailAnimation; + + if (hasTargetedEntity() && clientSideAttackTime < (float)getAttackDuration()) + clientSideAttackTime++; + else if (!hasTargetedEntity()) + clientSideAttackTime = 0.0f; + } + + + if (isInWater()) + { + setAirSupply(300); + } + else if (onGround) + { + yd += 0.5; + xd += (random->nextFloat() * 2.0f - 1.0f) * 0.4f; + zd += (random->nextFloat() * 2.0f - 1.0f) * 0.4f; + yRot = random->nextFloat() * 360.0f; + onGround = false; + hasImpulse = true; + } + + if (hasTargetedEntity()) + yRot = yHeadRot; + + xBodyRotO = xBodyRot; + zBodyRotO = zBodyRot; + + WaterAnimal::aiStep(); +} + +void Guardian::updateSize(bool elder) +{ + if (elder) + this->setSize(1.9975f, 1.9975f); + else + setSize(0.85f, 0.85f); +} + +void Guardian::travel(float xa, float ya) +{ + if (level->isClientSide) + { + if (isInWater()) + { + move(xd, yd, zd); + xd *= 0.9f; + yd *= 0.9f; + zd *= 0.9f; + } + else + { + WaterAnimal::travel(xa, ya); + } + } + else + { + if (isInWater()) + { + moveRelative(xa, ya, 0.1f); + move(xd, yd, zd); + xd *= 0.9f; + yd *= 0.9f; + zd *= 0.9f; + } + else + { + WaterAnimal::travel(xa, ya); + } + } + +} + +MobGroupData *Guardian::finalizeMobSpawn(MobGroupData *groupData, int extraData) +{ + WaterAnimal::finalizeMobSpawn(groupData, extraData); + if (extraData == 1) + setElder(true); + return groupData; +} \ No newline at end of file diff --git a/Minecraft.World/Guardian.h b/Minecraft.World/Guardian.h new file mode 100644 index 00000000..b03bf7bd --- /dev/null +++ b/Minecraft.World/Guardian.h @@ -0,0 +1,79 @@ +#pragma once +using namespace std; +#include "WaterAnimal.h" + +class Level; +class Player; + +class Guardian : public WaterAnimal +{ +public: + eINSTANCEOF GetType() { return eTYPE_GUARDIAN; } + static Entity *create(Level *level) { return new Guardian(level); } + + void _init(); + + + float clientSideTailAnimation; + float clientSideTailAnimationO; + float clientSideSpikesAnimation; + float clientSideSpikesAnimationO; + float clientSideAttackTime; + bool clientSideTouchedGround; + + + float xBodyRot, xBodyRotO; + float zBodyRot, zBodyRotO; + + Guardian(Level *level); + +protected: + virtual void registerAttributes(); + virtual void defineSynchedData(); + virtual int getAmbientSound(); + virtual int getHurtSound(); + virtual int getDeathSound(); + virtual float getSoundVolume(); + virtual int getDeathLoot(); + virtual bool makeStepSound(); + virtual void dropDeathLoot(bool wasKilledByPlayer, int playerBonusLevel); + virtual void serverAiStep(); + +public: + virtual bool isInWater(); + virtual void aiStep(); + virtual void travel(float xa, float ya); + virtual void readAdditionalSaveData(CompoundTag *tag); + virtual void addAdditonalSaveData(CompoundTag *tag); + virtual float getEyeHeight(); + void updateSize(bool isElder); + + bool isElder(); + void setElder(bool elder); + void setElderClient(); + + bool isMoving(); + void setMoving(bool moving); + + + int getTargetedEntityId(); + void setTargetedEntityId(int entityId); + bool hasTargetedEntity(); + shared_ptr getTargetedEntity(); + + virtual MobGroupData *finalizeMobSpawn(MobGroupData *groupData, int extraData = 0) override; + int getAttackDuration(); + float getTailAnimation(float partialTicks); + float getSpikesAnimation(float partialTicks); + float getAttackAnimationScale(float partialTicks); + +protected: + void lookAt(shared_ptr e, float yMax, float xMax); + +private: + float rotlerp(float a, float b, float max); + + float tx, ty, tz; + int attackTimer; + shared_ptr targetedEntity; +}; \ No newline at end of file diff --git a/Minecraft.World/LivingEntity.cpp b/Minecraft.World/LivingEntity.cpp index 1113bace..ac6a1b7e 100644 --- a/Minecraft.World/LivingEntity.cpp +++ b/Minecraft.World/LivingEntity.cpp @@ -2084,3 +2084,34 @@ bool LivingEntity::isAlliedTo(Team *other) } return false; } + +float LivingEntity::getEyeHeight() +{ + + return getHeadHeight(); +} + +Vec3 *LivingEntity::getPositionEyes(float partialTicks) +{ + if (partialTicks == 1.0f) + { + return Vec3::newTemp(x, y + (double)getEyeHeight(), z); + } + else + { + double d0 = xo + (x - xo) * (double)partialTicks; + double d1 = yo + (y - yo) * (double)partialTicks + (double)getEyeHeight(); + double d2 = zo + (z - zo) * (double)partialTicks; + return Vec3::newTemp(d0, d1, d2); + } +} + +HitResult *LivingEntity::rayTrace(double blockReachDistance, float partialTicks) +{ + Vec3 *vec3 = this->getPositionEyes(partialTicks); + Vec3 *vec31 = this->getViewVector(partialTicks); + Vec3 *vec32 = vec3->add(vec31->x * blockReachDistance, vec31->y * blockReachDistance, vec31->z * blockReachDistance); + + + return this->level->clip(vec3, vec32, false, false); +} \ No newline at end of file diff --git a/Minecraft.World/LivingEntity.h b/Minecraft.World/LivingEntity.h index 4ca84126..ee8a742d 100644 --- a/Minecraft.World/LivingEntity.h +++ b/Minecraft.World/LivingEntity.h @@ -325,4 +325,9 @@ public: virtual Team *getTeam(); virtual bool isAlliedTo(shared_ptr other); virtual bool isAlliedTo(Team *other); + +public: + virtual float getEyeHeight(); + virtual Vec3 *getPositionEyes(float partialTicks); + virtual HitResult *rayTrace(double blockReachDistance, float partialTicks); }; diff --git a/Minecraft.World/OceanMonumentFeature.cpp b/Minecraft.World/OceanMonumentFeature.cpp index dd8d78d4..3d98a84f 100644 --- a/Minecraft.World/OceanMonumentFeature.cpp +++ b/Minecraft.World/OceanMonumentFeature.cpp @@ -6,10 +6,16 @@ #include "Mth.h" #include "LevelData.h" + void OceanMonumentFeature::_init() { spacing = 32; separation = 5; + monumentEnemies.push_back(new Biome::MobSpawnerData(eTYPE_GUARDIAN, 1, 2, 4)); +} +std::vector* OceanMonumentFeature::getMonumentEnemies() +{ + return &monumentEnemies; } OceanMonumentFeature::OceanMonumentFeature() : StructureFeature() { _init(); } diff --git a/Minecraft.World/OceanMonumentFeature.h b/Minecraft.World/OceanMonumentFeature.h index 8cc965e1..d24eebb8 100644 --- a/Minecraft.World/OceanMonumentFeature.h +++ b/Minecraft.World/OceanMonumentFeature.h @@ -14,7 +14,7 @@ class OceanMonumentFeature : public StructureFeature { public: // static void staticCtor(); // Removed, merged into _init - + std::vector monumentEnemies; private: int spacing; int separation; @@ -22,6 +22,7 @@ private: void _init(); public: + vector* getMonumentEnemies(); OceanMonumentFeature(); OceanMonumentFeature(std::unordered_map options); ~OceanMonumentFeature(); @@ -49,4 +50,5 @@ public: }; + }; \ No newline at end of file diff --git a/Minecraft.World/OceanMonumentPieces.cpp b/Minecraft.World/OceanMonumentPieces.cpp index d861b519..8882c073 100644 --- a/Minecraft.World/OceanMonumentPieces.cpp +++ b/Minecraft.World/OceanMonumentPieces.cpp @@ -8,7 +8,8 @@ #include #include #include -#include "Squid.h" + +#include "Guardian.h" @@ -176,18 +177,16 @@ bool OceanMonumentPieces::Piece::intersectsXZ(BoundingBox* chunkBB, int x0, int bool OceanMonumentPieces::Piece::spawnElderGuardian(Level* level, BoundingBox* bb, int x, int y, int z) { - int wx = getWorldX(x, z); int wy = getWorldY(y); int wz = getWorldZ(x, z); if (bb->isInside(wx, wy, wz)) { - Squid *guardian = new Squid(level); - //guardian->setElder(true); + Guardian* guardian = new Guardian(level); + guardian->setElder(true); guardian->heal(guardian->getMaxHealth()); - /*entityguardian.setLocationAndAngles((double)i + 0.5D, (double)j, (double)k + 0.5D, 0.0F, 0.0F); - entityguardian.onInitialSpawn(worldIn.getDifficultyForLocation(new BlockPos(entityguardian)), (IEntityLivingData)null); - worldIn.spawnEntityInWorld(entityguardian);*/ + guardian->setPos((double)wx + 0.5, (double)wy, (double)wz + 0.5); + level->addEntity(shared_ptr(guardian)); return true; } return false; @@ -1080,7 +1079,7 @@ bool OceanMonumentPieces::SimpleTopRoom::postProcess(Level* level, Random* rando if (random->nextInt(3) != 0) { int k = 2 + (random->nextInt(4) == 0 ? 0 : 1); - generateBox(level, chunkBB, i, k, j, i, 3, j, Tile::sponge_Id, 1, false); + generateBox(level, chunkBB, i, k, j, i, 3, j, Tile::sponge_Id, 1, Tile::sponge_Id, 1, false); } } diff --git a/Minecraft.World/Player.cpp b/Minecraft.World/Player.cpp index e4c561cd..07a89e67 100644 --- a/Minecraft.World/Player.cpp +++ b/Minecraft.World/Player.cpp @@ -1270,6 +1270,7 @@ void Player::readAdditionalSaveData(CompoundTag *entityTag) sleepCounter = entityTag->getShort(L"SleepTimer"); experienceProgress = entityTag->getFloat(L"XpP"); + enchantmentSeed = entityTag->getInt(L"enchSeed"); experienceLevel = entityTag->getInt(L"XpLevel"); totalExperience = entityTag->getInt(L"XpTotal"); setScore(entityTag->getInt(L"Score")); @@ -1308,6 +1309,7 @@ void Player::addAdditonalSaveData(CompoundTag *entityTag) entityTag->putShort(L"SleepTimer", static_cast(sleepCounter)); entityTag->putFloat(L"XpP", experienceProgress); + entityTag->putInt(L"enchSeed", enchantmentSeed); entityTag->putInt(L"XpLevel", experienceLevel); entityTag->putInt(L"XpTotal", totalExperience); entityTag->putInt(L"Score", getScore()); diff --git a/Minecraft.World/Player.h b/Minecraft.World/Player.h index 520fc3aa..ea972481 100644 --- a/Minecraft.World/Player.h +++ b/Minecraft.World/Player.h @@ -66,6 +66,7 @@ private: public: AbstractContainerMenu *inventoryMenu; AbstractContainerMenu *containerMenu; + int enchantmentSeed = 0; protected: FoodData foodData; diff --git a/Minecraft.World/RandomLevelSource.cpp b/Minecraft.World/RandomLevelSource.cpp index cc709bae..1a24ad06 100644 --- a/Minecraft.World/RandomLevelSource.cpp +++ b/Minecraft.World/RandomLevelSource.cpp @@ -846,9 +846,16 @@ vector *RandomLevelSource::getMobsAt(MobCategory *mobCa { return nullptr; } - if (mobCategory == MobCategory::monster && scatteredFeature->isSwamphut(x, y, z)) + if (mobCategory == MobCategory::monster) { - return scatteredFeature->getSwamphutEnemies(); + if (scatteredFeature->isSwamphut(x, y, z)) + { + return scatteredFeature->getSwamphutEnemies(); + } + if (oceanMonument->isInsideFeature(x, y, z)) + { + return oceanMonument->getMonumentEnemies(); + } } return biome->getMobs(mobCategory); } diff --git a/Minecraft.World/SimpleContainer.h b/Minecraft.World/SimpleContainer.h index bb22d141..e51258f8 100644 --- a/Minecraft.World/SimpleContainer.h +++ b/Minecraft.World/SimpleContainer.h @@ -20,6 +20,7 @@ public: virtual void addListener(net_minecraft_world::ContainerListener *listener); virtual void removeListener(net_minecraft_world::ContainerListener *listener); virtual shared_ptr getItem(unsigned int slot); + virtual ItemInstanceArray* getItems() { return items; } virtual shared_ptr removeItem(unsigned int slot, int count); virtual shared_ptr removeItemNoUpdate(int slot); virtual void setItem(unsigned int slot, shared_ptr item); diff --git a/Minecraft.World/SoundTypes.h b/Minecraft.World/SoundTypes.h index c577eb83..388cd43a 100644 --- a/Minecraft.World/SoundTypes.h +++ b/Minecraft.World/SoundTypes.h @@ -218,7 +218,47 @@ enum eSOUND_TYPE eSoundType_MOB_RABBIT_DEATH, eSoundType_MOB_RABBIT_HOP, + eSoundType_ITEM_ARMOR_equipLeather1, + eSoundType_ITEM_ARMOR_equipLeather2, + eSoundType_ITEM_ARMOR_equipLeather3, + eSoundType_ITEM_ARMOR_equipLeather4, + eSoundType_ITEM_ARMOR_equipLeather5, + eSoundType_ITEM_ARMOR_equipLeather6, + eSoundType_ITEM_ARMOR_equipChain1, + eSoundType_ITEM_ARMOR_equipChain2, + eSoundType_ITEM_ARMOR_equipChain3, + eSoundType_ITEM_ARMOR_equipChain4, + eSoundType_ITEM_ARMOR_equipChain5, + eSoundType_ITEM_ARMOR_equipChain6, + + eSoundType_ITEM_ARMOR_equipIron1, + eSoundType_ITEM_ARMOR_equipIron2, + eSoundType_ITEM_ARMOR_equipIron3, + eSoundType_ITEM_ARMOR_equipIron4, + eSoundType_ITEM_ARMOR_equipIron5, + eSoundType_ITEM_ARMOR_equipIron6, + + eSoundType_ITEM_ARMOR_equipGold1, + eSoundType_ITEM_ARMOR_equipGold2, + eSoundType_ITEM_ARMOR_equipGold3, + eSoundType_ITEM_ARMOR_equipGold4, + eSoundType_ITEM_ARMOR_equipGold5, + eSoundType_ITEM_ARMOR_equipGold6, + + eSoundType_ITEM_ARMOR_equipDiamond1, + eSoundType_ITEM_ARMOR_equipDiamond2, + eSoundType_ITEM_ARMOR_equipDiamond3, + eSoundType_ITEM_ARMOR_equipDiamond4, + eSoundType_ITEM_ARMOR_equipDiamond5, + eSoundType_ITEM_ARMOR_equipDiamond6, + + eSoundType_ITEM_ARMOR_equipGeneric1, + eSoundType_ITEM_ARMOR_equipGeneric2, + eSoundType_ITEM_ARMOR_equipGeneric3, + eSoundType_ITEM_ARMOR_equipGeneric4, + eSoundType_ITEM_ARMOR_equipGeneric5, + eSoundType_ITEM_ARMOR_equipGeneric6, eSoundType_MAX }; diff --git a/Minecraft.World/SpawnEggItem.cpp b/Minecraft.World/SpawnEggItem.cpp index 2fe7b841..a4de941f 100644 --- a/Minecraft.World/SpawnEggItem.cpp +++ b/Minecraft.World/SpawnEggItem.cpp @@ -10,7 +10,8 @@ #include "HitResult.h" #include "SpawnEggItem.h" #include "Difficulty.h" - +#include +#include "AABB.h" SpawnEggItem::SpawnEggItem(int id) : Item(id) { @@ -335,7 +336,19 @@ shared_ptr SpawnEggItem::spawnMobAt(Level *level, int auxVal, double x, mob->yBodyRot = mob->yRot; mob->finalizeMobSpawn(nullptr, extraData); + + + level->addEntity(newEntity); + + if (mobId == 4) + { + shared_ptr g = dynamic_pointer_cast(newEntity); + if (g) + g->setElder(true); + + + } mob->playAmbientSound(); } } diff --git a/Minecraft.World/cmake/sources/Common.cmake b/Minecraft.World/cmake/sources/Common.cmake index c3e83803..88d81925 100644 --- a/Minecraft.World/cmake/sources/Common.cmake +++ b/Minecraft.World/cmake/sources/Common.cmake @@ -783,6 +783,8 @@ set(_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_ENTITY_ANIMAL "${CMAKE_CURRENT_SOURCE_DIR}/WaterAnimal.h" "${CMAKE_CURRENT_SOURCE_DIR}/Wolf.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/Wolf.h" + "${CMAKE_CURRENT_SOURCE_DIR}/Rabbit.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/Rabbit.h" "${CMAKE_CURRENT_SOURCE_DIR}/net.minecraft.world.entity.animal.h" ) source_group("net/minecraft/world/entity/animal" FILES ${_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_ENTITY_ANIMAL}) @@ -847,6 +849,9 @@ set(_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_ENTITY_ITEM "${CMAKE_CURRENT_SOURCE_DIR}/MinecartTNT.h" "${CMAKE_CURRENT_SOURCE_DIR}/PrimedTnt.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/PrimedTnt.h" + + "${CMAKE_CURRENT_SOURCE_DIR}/ArmorStand.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/ArmorStand.h" "${CMAKE_CURRENT_SOURCE_DIR}/net.minecraft.world.entity.item.h" ) source_group("net/minecraft/world/entity/item" FILES ${_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_ENTITY_ITEM}) @@ -887,6 +892,12 @@ set(_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_ENTITY_MONSTER "${CMAKE_CURRENT_SOURCE_DIR}/Witch.h" "${CMAKE_CURRENT_SOURCE_DIR}/Zombie.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/Zombie.h" + + "${CMAKE_CURRENT_SOURCE_DIR}/Endermite.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/Endermite.h" + + "${CMAKE_CURRENT_SOURCE_DIR}/Guardian.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/Guardian.h" "${CMAKE_CURRENT_SOURCE_DIR}/net.minecraft.world.entity.monster.h" ) source_group("net/minecraft/world/entity/monster" FILES ${_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_ENTITY_MONSTER}) @@ -1999,10 +2010,7 @@ set(_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_LEVEL_TILE "${CMAKE_CURRENT_SOURCE_DIR}/SeaLanternTile.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/PrismarineTile.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/TallGrass2.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/Rabbit.cpp" - - "${CMAKE_CURRENT_SOURCE_DIR}/Endermite.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/ArmorStand.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/FishFoodItem.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/ArmorStandItem.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/SavannaTreeFeature.cpp" diff --git a/Minecraft.World/net.minecraft.world.entity.monster.h b/Minecraft.World/net.minecraft.world.entity.monster.h index 1512f1fa..dde56293 100644 --- a/Minecraft.World/net.minecraft.world.entity.monster.h +++ b/Minecraft.World/net.minecraft.world.entity.monster.h @@ -28,3 +28,4 @@ //TU 31 #include "Endermite.h" +#include "Guardian.h"