Merge branch 'main' into upstream-merge

This commit is contained in:
George V. 2026-04-11 02:52:52 +03:00
commit a0f4063807
No known key found for this signature in database
GPG key ID: 1DB61094F2DD4982
92 changed files with 1619 additions and 60 deletions

View file

@ -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"
};

View file

@ -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<EnchantmentMenu*>(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<HtmlString>* lines = new vector<HtmlString>();
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;

View file

@ -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);

View file

@ -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

View file

@ -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 <MinecraftServer.h>
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<Player>(pMinecraft->localplayers[iPad]), index))
MinecraftServer *aMinecraft = MinecraftServer::getInstance();
if (index >= 0 && dynamic_cast<EnchantmentMenu*>(aMinecraft->getPlayers()->players[iPad]->containerMenu)->clickMenuButton(dynamic_pointer_cast<Player>(aMinecraft->getPlayers()->players[iPad]), index))
{
pMinecraft->localgameModes[iPad]->handleInventoryButtonClick(m_menu->containerId, index);
pMinecraft->localgameModes[iPad]->handleInventoryButtonClick(dynamic_cast<EnchantmentMenu*>(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;

View file

@ -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;

View file

@ -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);

View file

@ -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<EnchantingScreenInput *>(_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;

View file

@ -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")

View file

@ -34,6 +34,7 @@ UIScene_MainMenu::UIScene_MainMenu(int iPad, void *initData, UILayer *parentLaye
m_buttons[static_cast<int>(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;

View file

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,016 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 965 B

View file

@ -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);

View file

@ -407,6 +407,7 @@ void EntityRenderer::registerTerrainTextures(IconRegister *iconRegister)
{
}
ResourceLocation *EntityRenderer::getTextureLocation(shared_ptr<Entity> mob)
{
return nullptr;

View file

@ -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> entity, float camX, float camY, float camZ) { return true; }
};

View file

@ -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> entity,
unsigned int uiBitmaskOverrideAnim)
{
shared_ptr<Guardian> guardian = dynamic_pointer_cast<Guardian>(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<LivingEntity> 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> 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);
}

View file

@ -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> entity,
unsigned int uiBitmaskOverrideAnim = 0) override;
virtual void render(shared_ptr<Entity> entity, float time, float r, float bob,
float yRot, float xRot, float scale, bool usecompiled) override;
};

View file

@ -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<GuardianModel *>(model);
}
ResourceLocation *GuardianRenderer::getTextureLocation(shared_ptr<Entity> mob)
{
shared_ptr<Guardian> guardian = dynamic_pointer_cast<Guardian>(mob);
if (guardian && guardian->isElder())
return &GUARDIAN_ELDER_LOCATION;
return &GUARDIAN_LOCATION;
}
bool GuardianRenderer::shouldRender(shared_ptr<Entity> mob, float camX, float camY, float camZ)
{
if (MobRenderer::shouldRender(mob, camX, camY, camZ))
return true;
shared_ptr<Guardian> guardian = dynamic_pointer_cast<Guardian>(mob);
if (!guardian || !guardian->hasTargetedEntity())
return false;
shared_ptr<LivingEntity> 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<LivingEntity> 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<LivingEntity> _mob, float bob,
float bodyRot, float a)
{
shared_ptr<Guardian> mob = dynamic_pointer_cast<Guardian>(_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<Entity> _mob, double x, double y, double z,
float rot, float a)
{
MobRenderer::render(_mob, x, y, z, rot, a);
shared_ptr<Guardian> mob = dynamic_pointer_cast<Guardian>(_mob);
if (!mob || !mob->hasTargetedEntity()) return;
shared_ptr<Entity> 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<LivingEntity> mob, float wp, float ws, float bob,
float headRotMinusBodyRot, float headRotx, float scale)
{
shared_ptr<Guardian> guardian = dynamic_pointer_cast<Guardian>(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);
}
}

View file

@ -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<LivingEntity> entity, double yOffset,
float partialTicks,
double &outX, double &outY, double &outZ);
public:
GuardianRenderer(Model *model, float shadow);
virtual bool shouldRender(shared_ptr<Entity> mob, float camX, float camY, float camZ) override;
virtual void render(shared_ptr<Entity> mob, double x, double y, double z,
float rot, float a) override;
protected:
virtual void setupRotations(shared_ptr<LivingEntity> mob, float bob,
float bodyRot, float a) override;
virtual void renderModel(shared_ptr<LivingEntity> mob, float wp, float ws, float bob,
float headRotMinusBodyRot, float headRotx, float scale) override;
virtual ResourceLocation *getTextureLocation(shared_ptr<Entity> mob) override;
};

View file

@ -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;
}
}

View file

@ -31,6 +31,17 @@ void MobRenderer::render(shared_ptr<Entity> _mob, double x, double y, double z,
renderLeash(mob, x, y, z, rot, a);
}
bool MobRenderer::shouldRender(shared_ptr<Entity> 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<LivingEntity> mob)
{
return LivingEntityRenderer::shouldShowName(mob) && (mob->shouldShowName() || dynamic_pointer_cast<Mob>(mob)->hasCustomName());

View file

@ -14,6 +14,7 @@ class MobRenderer : public LivingEntityRenderer
public:
MobRenderer(Model *model, float shadow);
virtual void render(shared_ptr<Entity> mob, double x, double y, double z, float rot, float a);
virtual bool shouldRender(shared_ptr<Entity> entity, float camX, float camY, float camZ) override;
protected:
virtual bool shouldShowName(shared_ptr<LivingEntity> mob);

View file

@ -6,7 +6,7 @@
Model::Model()
{
riding = false;
young=true;
young=false; //andi change
texWidth=64;
texHeight=32;
}

View file

@ -386,6 +386,7 @@ bool ServerPlayerGameMode::useItem(shared_ptr<Player> 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);
}

View file

@ -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",

View file

@ -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

View file

@ -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})

View file

@ -389,4 +389,9 @@ void glTexGen(int coord, int mode, FloatBuffer *vec)
void glCullFace(int dir)
{
RenderManager.StateSetFaceCullCW( dir == GL_BACK);
}
}
void glTexParameterf(int target, int param, float value)
{
RenderManager.TextureSetParam(param, (int)value);
}

View file

@ -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);

View file

@ -1,4 +1,5 @@
#include "stdafx.h"
#include <random>
#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<ItemInstance> ArmorItem::use(shared_ptr<ItemInstance> instance, Level* level, shared_ptr<Player> 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<ItemInstance>(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<ItemInstance>(copy);
}
}
else {
ItemInstance copy = *instance->copy_not_shared();
if (player->inventory->armor[slot] == nullptr) {
player->inventory->armor[slot] = make_shared<ItemInstance>(copy);
}
else {
player->inventory->setItem(player->inventory->selected, player->inventory->armor[slot]);
player->inventory->armor[slot] = make_shared<ItemInstance>(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<int> dist(lo, hi);
player->playSound(dist(rng), 0.5f, 1.0f);
// Return the (now empty) instance
return instance;
}
int ArmorItem::getColor(shared_ptr<ItemInstance> item, int spriteLayer)
{
if (spriteLayer > 0)

View file

@ -87,5 +87,7 @@ public:
virtual bool isValidRepairItem(shared_ptr<ItemInstance> source, shared_ptr<ItemInstance> repairItem);
virtual void registerIcons(IconRegister *iconRegister);
virtual shared_ptr<ItemInstance> use(shared_ptr<ItemInstance> instance, Level* level, shared_ptr<Player> player);
static Icon *getEmptyIcon(int slot);
};

View file

@ -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,

View file

@ -84,8 +84,9 @@ public:
virtual int getDescriptionId();
virtual HtmlString getFullname(int level);
virtual bool canEnchant(shared_ptr<ItemInstance> item);
private:
// 4J Added
wstring getLevelString(int level);
private:
};

View file

@ -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<ItemInstance> item)

View file

@ -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<ItemInstance> item);

View file

@ -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> inventory, Level *level, int xt, int yt, int zt)
{
enchantSlots = std::make_shared<EnchantmentContainer>(this);
lapisSlot = std::make_shared<EnchantmentContainer>(this, 64);
playerT = inventory->player;
for(int i = 0; i < 3; ++i)
{
costs[i] = 0;
@ -21,6 +25,7 @@ EnchantmentMenu::EnchantmentMenu(shared_ptr<Inventory> 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> container but wasn't using it, so removed to simplify things
vector<EnchantmentInstance*> EnchantmentMenu::getEnchantment() {
random.setSeed(playerT->enchantmentSeed);
shared_ptr<ItemInstance> item = enchantSlots->getItem(0);
return *EnchantmentHelper::selectEnchantment(&random, item, costs[2]);
}
void EnchantmentMenu::slotsChanged(int a) // 4J used to take a shared_ptr<Container> container but wasn't using it, so removed to simplify things
{
shared_ptr<ItemInstance> item = enchantSlots->getItem(0);
shared_ptr<ItemInstance> 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<Container>
}
}
}
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> player, int i)
@ -155,44 +187,86 @@ bool EnchantmentMenu::clickMenuButton(shared_ptr<Player> player, int i)
shared_ptr<ItemInstance> 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<EnchantmentInstance *> *newEnchantment = EnchantmentHelper::selectEnchantment(&random, item, costs[i]);
vector<EnchantmentInstance *> *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> player, int i)
{
shared_ptr<ItemInstance> 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<EnchantmentInstance*>* 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> player)
{
@ -204,6 +278,11 @@ void EnchantmentMenu::removed(shared_ptr<Player> player)
{
player->drop(item);
}
item = lapisSlot->removeItemNoUpdate(1);
if (item != nullptr)
{
player->drop(item);
}
}
bool EnchantmentMenu::stillValid(shared_ptr<Player> player)
@ -213,6 +292,11 @@ bool EnchantmentMenu::stillValid(shared_ptr<Player> player)
return true;
}
int EnchantmentMenu::getLapisCount() {
if (lapisSlot->getItem(1) == nullptr) return 0;
return lapisSlot->getItem(1)->count;
}
shared_ptr<ItemInstance> EnchantmentMenu::quickMoveStack(shared_ptr<Player> player, int slotIndex)
{
if (slotIndex < 0 || slotIndex >= static_cast<int>(slots.size()))
@ -223,10 +307,15 @@ shared_ptr<ItemInstance> EnchantmentMenu::quickMoveStack(shared_ptr<Player> play
shared_ptr<ItemInstance> clicked = nullptr;
Slot *slot = slots.at(slotIndex);
Slot *IngredientSlot = nullptr;
Slot *LapisSlot = nullptr;
if (INGREDIENT_SLOT >= 0 && INGREDIENT_SLOT < static_cast<int>(slots.size()))
{
IngredientSlot = slots.at(INGREDIENT_SLOT);
}
if (LAPIS_SLOT >= 0 && LAPIS_SLOT < static_cast<int>(slots.size()))
{
LapisSlot = slots.at(LAPIS_SLOT);
}
if (slot != nullptr && slot->hasItem())
{
@ -244,6 +333,16 @@ shared_ptr<ItemInstance> EnchantmentMenu::quickMoveStack(shared_ptr<Player> 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<ItemInstance> EnchantmentMenu::quickMoveStack(shared_ptr<Player> 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<ItemInstance> EnchantmentMenu::quickMoveStack(shared_ptr<Player> 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))

View file

@ -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<Container> enchantSlots;
shared_ptr<Container> lapisSlot;
bool alreadyRan = false;
bool en = false;
// Header
std::vector<EnchantmentInstance*>* 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> inventory, Level *level, int xt, int yt, int zt);
virtual void addSlotListener(ContainerListener *listener);
virtual void broadcastChanges();
vector<EnchantmentInstance*> getEnchantment();
virtual void setData(int id, int value);
virtual void slotsChanged();// 4J used to take a shared_ptr<Container> container but wasn't using it, so removed to simplify things
virtual void slotsChanged(int a);// 4J used to take a shared_ptr<Container> container but wasn't using it, so removed to simplify things
virtual bool clickMenuButton(shared_ptr<Player> player, int i);
virtual EnchantmentInstance* predictEnchantment(shared_ptr<Player> player, int i);
void removed(shared_ptr<Player> player);
virtual bool stillValid(shared_ptr<Player> player);
virtual shared_ptr<ItemInstance> quickMoveStack(shared_ptr<Player> player, int slotIndex);

View file

@ -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);

View file

@ -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<LivingEntity> Guardian::getTargetedEntity()
{
if (!hasTargetedEntity())
return nullptr;
if (level->isClientSide)
{
if (targetedEntity != nullptr)
return targetedEntity;
shared_ptr<Entity> entity = level->getEntity(getTargetedEntityId());
if (entity != nullptr && dynamic_pointer_cast<LivingEntity>(entity))
{
targetedEntity = dynamic_pointer_cast<LivingEntity>(entity);
return targetedEntity;
}
return nullptr;
}
shared_ptr<Entity> e = level->getEntity(getTargetedEntityId());
return dynamic_pointer_cast<LivingEntity>(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<Entity> e, float yMax, float xMax)
{
double d0 = e->x - x;
double d1 = e->z - z;
double d2;
if (dynamic_pointer_cast<LivingEntity>(e))
{
shared_ptr<LivingEntity> living = dynamic_pointer_cast<LivingEntity>(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> 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<Player> nearest = level->getNearestPlayer(x, y, z, 16.0);
if (nearest != nullptr && canSee(nearest) && !nearest->abilities.invulnerable)
{
setTargetedEntityId(nearest->entityId);
attackTimer = 0;
}
}
shared_ptr<LivingEntity> 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<LivingEntity>(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<float>(atan2(xd, zd)) * 180.0f / (float)PI) - yBodyRot) * 0.1f;
yRot = yBodyRot;
zBodyRot = zBodyRot + (float)PI * 0.05f;
xBodyRot += ((-static_cast<float>(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;
}

View file

@ -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<LivingEntity> 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<Entity> e, float yMax, float xMax);
private:
float rotlerp(float a, float b, float max);
float tx, ty, tz;
int attackTimer;
shared_ptr<LivingEntity> targetedEntity;
};

View file

@ -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);
}

View file

@ -325,4 +325,9 @@ public:
virtual Team *getTeam();
virtual bool isAlliedTo(shared_ptr<LivingEntity> other);
virtual bool isAlliedTo(Team *other);
public:
virtual float getEyeHeight();
virtual Vec3 *getPositionEyes(float partialTicks);
virtual HitResult *rayTrace(double blockReachDistance, float partialTicks);
};

View file

@ -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<Biome::MobSpawnerData*>* OceanMonumentFeature::getMonumentEnemies()
{
return &monumentEnemies;
}
OceanMonumentFeature::OceanMonumentFeature() : StructureFeature() { _init(); }

View file

@ -14,7 +14,7 @@ class OceanMonumentFeature : public StructureFeature
{
public:
// static void staticCtor(); // Removed, merged into _init
std::vector<Biome::MobSpawnerData*> monumentEnemies;
private:
int spacing;
int separation;
@ -22,6 +22,7 @@ private:
void _init();
public:
vector<Biome::MobSpawnerData*>* getMonumentEnemies();
OceanMonumentFeature();
OceanMonumentFeature(std::unordered_map<std::wstring, std::wstring> options);
~OceanMonumentFeature();
@ -49,4 +50,5 @@ public:
};
};

View file

@ -8,7 +8,8 @@
#include <algorithm>
#include <random>
#include <vector>
#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<Entity>(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);
}
}

View file

@ -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<short>(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());

View file

@ -66,6 +66,7 @@ private:
public:
AbstractContainerMenu *inventoryMenu;
AbstractContainerMenu *containerMenu;
int enchantmentSeed = 0;
protected:
FoodData foodData;

View file

@ -846,9 +846,16 @@ vector<Biome::MobSpawnerData *> *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);
}

View file

@ -20,6 +20,7 @@ public:
virtual void addListener(net_minecraft_world::ContainerListener *listener);
virtual void removeListener(net_minecraft_world::ContainerListener *listener);
virtual shared_ptr<ItemInstance> getItem(unsigned int slot);
virtual ItemInstanceArray* getItems() { return items; }
virtual shared_ptr<ItemInstance> removeItem(unsigned int slot, int count);
virtual shared_ptr<ItemInstance> removeItemNoUpdate(int slot);
virtual void setItem(unsigned int slot, shared_ptr<ItemInstance> item);

View file

@ -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
};

View file

@ -10,7 +10,8 @@
#include "HitResult.h"
#include "SpawnEggItem.h"
#include "Difficulty.h"
#include <Guardian.h>
#include "AABB.h"
SpawnEggItem::SpawnEggItem(int id) : Item(id)
{
@ -335,7 +336,19 @@ shared_ptr<Entity> SpawnEggItem::spawnMobAt(Level *level, int auxVal, double x,
mob->yBodyRot = mob->yRot;
mob->finalizeMobSpawn(nullptr, extraData);
level->addEntity(newEntity);
if (mobId == 4)
{
shared_ptr<Guardian> g = dynamic_pointer_cast<Guardian>(newEntity);
if (g)
g->setElder(true);
}
mob->playAmbientSound();
}
}

View file

@ -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"

View file

@ -28,3 +28,4 @@
//TU 31
#include "Endermite.h"
#include "Guardian.h"