TU43 Structures, bug fixes & minor changes
- Elytra flight, damage, kinetic energy, pretty much any bug someone reported, paper doll, etc. - Fossil & Igloo generation - Texture interpolation - Iggy mouse fix for world settings - Neo branding on main screen - Release build txt logger - Debug mode spectator - Several server fixes - Flowerpot fixes - Several more changes made in TU43
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"inheritEnvironments": [
|
||||
"msvc_x64"
|
||||
],
|
||||
"name": "x64-Debug",
|
||||
"includePath": [
|
||||
"${env.INCLUDE}",
|
||||
"${workspaceRoot}\\**"
|
||||
],
|
||||
"defines": [
|
||||
"WIN32",
|
||||
"_DEBUG",
|
||||
"UNICODE",
|
||||
"_UNICODE"
|
||||
],
|
||||
"intelliSenseMode": "windows-msvc-x64"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -70,6 +70,11 @@ set_source_files_properties(compat_shims.cpp PROPERTIES SKIP_PRECOMPILE_HEADERS
|
||||
|
||||
configure_compiler_target(Minecraft.Client)
|
||||
|
||||
if(PLATFORM_NAME STREQUAL "Windows64")
|
||||
target_compile_options(Minecraft.Client PRIVATE $<$<CONFIG:Release>:/Zi>)
|
||||
target_link_options(Minecraft.Client PRIVATE $<$<CONFIG:Release>:/DEBUG /OPT:REF /OPT:ICF>)
|
||||
endif()
|
||||
|
||||
set(MINECRAFT_CLIENT_USE_4J_DEBUG_LIBS TRUE)
|
||||
if(CMAKE_CROSSCOMPILING AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
set(MINECRAFT_CLIENT_USE_4J_DEBUG_LIBS FALSE)
|
||||
@@ -88,6 +93,7 @@ if(MINECRAFT_CLIENT_USE_4J_DEBUG_LIBS)
|
||||
d3dcompiler
|
||||
XInput9_1_0
|
||||
wsock32
|
||||
dbghelp
|
||||
legacy_stdio_definitions
|
||||
4JLibs.${PLATFORM_NAME}.Input
|
||||
4JLibs.${PLATFORM_NAME}.Profile
|
||||
@@ -102,6 +108,7 @@ else()
|
||||
d3dcompiler
|
||||
XInput9_1_0
|
||||
wsock32
|
||||
dbghelp
|
||||
legacy_stdio_definitions
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/${PLATFORM_NAME}/4JLibs/libs/4J_Input.lib"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/${PLATFORM_NAME}/4JLibs/libs/4J_Storage.lib"
|
||||
|
||||
@@ -3486,6 +3486,10 @@ void ClientConnection::handleTileEntityData(shared_ptr<TileEntityDataPacket> pac
|
||||
{
|
||||
dynamic_pointer_cast<BannerTileEntity>(te)->load(packet->tag);
|
||||
}
|
||||
else if (packet->type == TileEntityDataPacket::TYPE_FLOWER_POT && dynamic_pointer_cast<FlowerPotTileEntity>(te) != nullptr)
|
||||
{
|
||||
dynamic_pointer_cast<FlowerPotTileEntity>(te)->load(packet->tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3834,8 +3838,10 @@ void ClientConnection::handlePlayerAbilities(shared_ptr<PlayerAbilitiesPacket> p
|
||||
player->abilities.instabuild = playerAbilitiesPacket->canInstabuild();
|
||||
player->abilities.invulnerable = playerAbilitiesPacket->isInvulnerable();
|
||||
player->abilities.mayfly = playerAbilitiesPacket->canFly();
|
||||
player->abilities.spectatorMode = playerAbilitiesPacket->isNoPhysics();
|
||||
player->abilities.setFlyingSpeed(playerAbilitiesPacket->getFlyingSpeed());
|
||||
player->abilities.setWalkingSpeed(playerAbilitiesPacket->getWalkingSpeed());
|
||||
player->noPhysics = playerAbilitiesPacket->isNoPhysics();
|
||||
}
|
||||
|
||||
void ClientConnection::handleSoundEvent(shared_ptr<LevelSoundPacket> packet)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -77,11 +77,28 @@ void UIControl_MinecraftPlayer::render(IggyCustomDrawCallbackRegion *region)
|
||||
glTranslatef(0, pMinecraft->localplayers[containerMenu->getPad()]->heightOffset, 0);
|
||||
EntityRenderDispatcher::instance->playerRotY = 180;
|
||||
|
||||
auto lp = pMinecraft->localplayers[containerMenu->getPad()];
|
||||
float owp = lp->walkAnimPos;
|
||||
float ows = lp->walkAnimSpeed;
|
||||
float owsO = lp->walkAnimSpeedO;
|
||||
if (lp->isElytraFlying())
|
||||
{
|
||||
lp->walkAnimPos = 0.0f;
|
||||
lp->walkAnimSpeed = 0.0f;
|
||||
lp->walkAnimSpeedO = 0.0f;
|
||||
}
|
||||
|
||||
// 4J Stu - Turning on hideGui while we do this stops the name rendering in split-screen
|
||||
bool wasHidingGui = pMinecraft->options->hideGui;
|
||||
pMinecraft->options->hideGui = true;
|
||||
EntityRenderDispatcher::instance->render(pMinecraft->localplayers[containerMenu->getPad()], 0, 0, 0, 0, 1, false, false);
|
||||
EntityRenderDispatcher::instance->isInventoryRender = true;
|
||||
EntityRenderDispatcher::instance->render(lp, 0, 0, 0, 0, 1, false, false);
|
||||
EntityRenderDispatcher::instance->isInventoryRender = false;
|
||||
pMinecraft->options->hideGui = wasHidingGui;
|
||||
|
||||
lp->walkAnimPos = owp;
|
||||
lp->walkAnimSpeed = ows;
|
||||
lp->walkAnimSpeedO = owsO;
|
||||
//pMinecraft->localplayers[m_iPad]->glow = 0;
|
||||
|
||||
pMinecraft->localplayers[containerMenu->getPad()]->yBodyRot = oybr;
|
||||
|
||||
@@ -80,6 +80,8 @@ UIScene_LaunchMoreOptionsMenu::UIScene_LaunchMoreOptionsMenu(int iPad, void *ini
|
||||
m_bUpdateCheats = false;
|
||||
// Update cheat checkboxes
|
||||
UpdateCheats();
|
||||
m_bPendingTabSwitch = false;
|
||||
m_iPendingTabIndex = -1;
|
||||
|
||||
m_checkboxes[eLaunchCheckbox_Online].init(app.GetString(IDS_ONLINE_GAME),eLaunchCheckbox_Online,bOnlineGame);
|
||||
m_checkboxes[eLaunchCheckbox_InviteOnly].init(app.GetString(IDS_INVITE_ONLY),eLaunchCheckbox_InviteOnly,bInviteOnly);
|
||||
@@ -240,6 +242,14 @@ void UIScene_LaunchMoreOptionsMenu::tick()
|
||||
UpdateOnline();
|
||||
m_bUpdateOnline = false;
|
||||
}
|
||||
if (m_bPendingTabSwitch)
|
||||
{
|
||||
m_bPendingTabSwitch = false;
|
||||
m_tabIndex = m_iPendingTabIndex;
|
||||
updateTooltips();
|
||||
IggyDataValue result;
|
||||
IggyResult out = IggyPlayerCallMethodRS(getMovie(), &result, IggyPlayerRootPath(getMovie()), m_funcChangeTab, 0, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void UIScene_LaunchMoreOptionsMenu::handleDestroy()
|
||||
@@ -339,6 +349,42 @@ void UIScene_LaunchMoreOptionsMenu::handleTouchInput(unsigned int iPad, S32 x, S
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
bool UIScene_LaunchMoreOptionsMenu::handleMouseClick(F32 x, F32 y)
|
||||
{
|
||||
if (!hasFocus(m_iPad) || getMovie() == nullptr || g_KBMInput.IsMouseGrabbed() || !g_KBMInput.IsKBMActive())
|
||||
return false;
|
||||
|
||||
if (m_bIgnoreInput)
|
||||
return false;
|
||||
|
||||
float sceneMouseX = x;
|
||||
float sceneMouseY = y;
|
||||
|
||||
if (sceneMouseY >= 190.0f && sceneMouseY <= 270.0f)
|
||||
{
|
||||
int newTab = -1;
|
||||
if (sceneMouseX >= 480.0f && sceneMouseX <= 700.0f)
|
||||
newTab = TAB_WORLD_OPTIONS;
|
||||
else if (sceneMouseX > 700.0f && sceneMouseX <= 960.0f)
|
||||
newTab = TAB_GAME_OPTIONS;
|
||||
|
||||
if (newTab >= 0)
|
||||
{
|
||||
if (m_tabIndex != newTab)
|
||||
{
|
||||
m_bPendingTabSwitch = true;
|
||||
m_iPendingTabIndex = newTab;
|
||||
ui.PlayUISFX(eSFX_Press);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return UIScene::handleMouseClick(x, y);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__PSVITA__) || defined(_WINDOWS64)
|
||||
UIControl* UIScene_LaunchMoreOptionsMenu::GetMainPanel()
|
||||
{
|
||||
|
||||
@@ -146,6 +146,9 @@ public:
|
||||
#endif
|
||||
// INPUT
|
||||
virtual void handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled);
|
||||
#ifdef _WINDOWS64
|
||||
virtual bool handleMouseClick(F32 x, F32 y);
|
||||
#endif
|
||||
virtual void handleFocusChange(F64 controlId, F64 childId);
|
||||
virtual void handleTimerComplete(int id);
|
||||
static int KeyboardCompleteSeedCallback(LPVOID lpParam,const bool bRes);
|
||||
@@ -162,6 +165,9 @@ private:
|
||||
bool m_bUpdateOnline; // If true, update online settings on next tick
|
||||
void UpdateOnline();
|
||||
|
||||
bool m_bPendingTabSwitch;
|
||||
int m_iPendingTabIndex;
|
||||
|
||||
#ifdef __PSVITA__
|
||||
virtual void handleTouchInput(unsigned int iPad, S32 x, S32 y, int iId, bool bPressed, bool bRepeat, bool bReleased);
|
||||
#endif //__PSVITA__
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
#include "stdafx.h"
|
||||
#include "../../Lighting.h"
|
||||
#ifdef _WINDOWS64
|
||||
#include "../../Windows64/Iggy/gdraw/gdraw_d3d11.h"
|
||||
#include "../../Windows64/4JLibs/inc/4J_Render.h"
|
||||
#endif
|
||||
#include "../../../Minecraft.World/Mth.h"
|
||||
#include "../../../Minecraft.World/StringHelpers.h"
|
||||
#include "../../../Minecraft.World/Random.h"
|
||||
@@ -556,6 +561,60 @@ void UIScene_MainMenu::customDrawSplash(IggyCustomDrawCallbackRegion *region)
|
||||
ui.endCustomDraw(region);
|
||||
}
|
||||
|
||||
void UIScene_MainMenu::render(S32 width, S32 height, C4JRender::eViewportType viewport)
|
||||
{
|
||||
UIScene::render(width, height, viewport);
|
||||
|
||||
Minecraft *pMinecraft = Minecraft::GetInstance();
|
||||
if (!pMinecraft || !pMinecraft->font) return;
|
||||
|
||||
Font *font = pMinecraft->font;
|
||||
const wstring part1 = L"neo";
|
||||
const wstring part2 = L"Legacy";
|
||||
const float scale = 0.6f;
|
||||
const int pad = 4;
|
||||
|
||||
ScreenSizeCalculator ssc(pMinecraft->options, pMinecraft->width_phys, pMinecraft->height_phys);
|
||||
S32 sw = ssc.getWidth();
|
||||
S32 sh = ssc.getHeight();
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
RenderManager.StartFrame();
|
||||
gdraw_D3D11_setViewport_4J();
|
||||
#endif
|
||||
RenderManager.Set_matrixDirty();
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0, sw, sh, 0, 1000, 3000);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glTranslatef(0.0f, 0.0f, -2000.0f);
|
||||
|
||||
Lighting::turnOff();
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(false);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
int totalW = static_cast<int>((font->width(part1) + font->width(part2)) * scale);
|
||||
int tx = sw - totalW - pad;
|
||||
int ty = sh - static_cast<int>(8 * scale) - pad;
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(static_cast<float>(tx), static_cast<float>(ty), 0.0f);
|
||||
glScalef(scale, scale, scale);
|
||||
font->drawShadow(part1, 0, 0, 0x66A254FA);
|
||||
font->drawShadow(part2, font->width(part1), 0, 0x66ffffff);
|
||||
glPopMatrix();
|
||||
|
||||
glDepthMask(true);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
int UIScene_MainMenu::MustSignInReturned(void *pParam, int iPad, C4JStorage::EMessageResult result)
|
||||
{
|
||||
UIScene_MainMenu* pClass = static_cast<UIScene_MainMenu *>(pParam);
|
||||
|
||||
@@ -118,6 +118,7 @@ public:
|
||||
virtual EUIScene getSceneType() { return eUIScene_MainMenu;}
|
||||
|
||||
virtual void customDraw(IggyCustomDrawCallbackRegion *region);
|
||||
virtual void render(S32 width, S32 height, C4JRender::eViewportType viewport);
|
||||
protected:
|
||||
void customDrawSplash(IggyCustomDrawCallbackRegion *region);
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 776 B |
@@ -0,0 +1,4 @@
|
||||
interp:1
|
||||
0*8
|
||||
1*8
|
||||
2*8
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 198 KiB After Width: | Height: | Size: 3.2 KiB |
@@ -1,440 +1,23 @@
|
||||
0*15
|
||||
1*15
|
||||
2*15
|
||||
3*15
|
||||
4*15
|
||||
5*15
|
||||
6*15
|
||||
7*15
|
||||
8*15
|
||||
9*15
|
||||
10*15
|
||||
11*15
|
||||
12*15
|
||||
13*15
|
||||
14*15
|
||||
15*15
|
||||
16*15
|
||||
17*15
|
||||
18*15
|
||||
19*15
|
||||
20*15
|
||||
21*15
|
||||
22*15
|
||||
23*15
|
||||
24*15
|
||||
25*15
|
||||
26*15
|
||||
27*15
|
||||
28*15
|
||||
29*15
|
||||
30*15
|
||||
31*15
|
||||
32*15
|
||||
33*15
|
||||
34*15
|
||||
35*15
|
||||
36*15
|
||||
37*15
|
||||
38*15
|
||||
39*15
|
||||
40*15
|
||||
41*15
|
||||
42*15
|
||||
43*15
|
||||
44*15
|
||||
45*15
|
||||
46*15
|
||||
47*15
|
||||
48*15
|
||||
49*15
|
||||
50*15
|
||||
51*15
|
||||
52*15
|
||||
53*15
|
||||
54*15
|
||||
55*15
|
||||
56*15
|
||||
57*15
|
||||
58*15
|
||||
59*15
|
||||
60*15
|
||||
61*15
|
||||
62*15
|
||||
63*15
|
||||
64*15
|
||||
65*15
|
||||
66*15
|
||||
67*15
|
||||
68*15
|
||||
69*15
|
||||
70*15
|
||||
71*15
|
||||
72*15
|
||||
73*15
|
||||
74*15
|
||||
75*15
|
||||
76*15
|
||||
77*15
|
||||
78*15
|
||||
79*15
|
||||
80*15
|
||||
81*15
|
||||
82*15
|
||||
83*15
|
||||
84*15
|
||||
85*15
|
||||
86*15
|
||||
87*15
|
||||
88*15
|
||||
89*15
|
||||
90*15
|
||||
91*15
|
||||
92*15
|
||||
93*15
|
||||
94*15
|
||||
95*15
|
||||
96*15
|
||||
97*15
|
||||
98*15
|
||||
99*15
|
||||
100*15
|
||||
101*15
|
||||
102*15
|
||||
103*15
|
||||
104*15
|
||||
105*15
|
||||
106*15
|
||||
107*15
|
||||
108*15
|
||||
109*15
|
||||
110*15
|
||||
111*15
|
||||
112*15
|
||||
113*15
|
||||
114*15
|
||||
115*15
|
||||
116*15
|
||||
117*15
|
||||
118*15
|
||||
119*15
|
||||
120*15
|
||||
121*15
|
||||
122*15
|
||||
123*15
|
||||
124*15
|
||||
125*15
|
||||
126*15
|
||||
127*15
|
||||
128*15
|
||||
129*15
|
||||
130*15
|
||||
131*15
|
||||
132*15
|
||||
133*15
|
||||
134*15
|
||||
135*15
|
||||
136*15
|
||||
137*15
|
||||
138*15
|
||||
139*15
|
||||
140*15
|
||||
141*15
|
||||
142*15
|
||||
143*15
|
||||
144*15
|
||||
145*15
|
||||
146*15
|
||||
147*15
|
||||
148*15
|
||||
149*15
|
||||
150*15
|
||||
151*15
|
||||
152*15
|
||||
153*15
|
||||
154*15
|
||||
155*15
|
||||
156*15
|
||||
157*15
|
||||
158*15
|
||||
159*15
|
||||
160*15
|
||||
161*15
|
||||
162*15
|
||||
163*15
|
||||
164*15
|
||||
165*15
|
||||
166*15
|
||||
167*15
|
||||
168*15
|
||||
169*15
|
||||
170*15
|
||||
171*15
|
||||
172*15
|
||||
173*15
|
||||
174*15
|
||||
175*15
|
||||
176*15
|
||||
177*15
|
||||
178*15
|
||||
179*15
|
||||
180*15
|
||||
181*15
|
||||
182*15
|
||||
183*15
|
||||
184*15
|
||||
185*15
|
||||
186*15
|
||||
187*15
|
||||
188*15
|
||||
189*15
|
||||
190*15
|
||||
191*15
|
||||
192*15
|
||||
193*15
|
||||
194*15
|
||||
195*15
|
||||
196*15
|
||||
197*15
|
||||
198*15
|
||||
199*15
|
||||
200*15
|
||||
201*15
|
||||
202*15
|
||||
203*15
|
||||
204*15
|
||||
205*15
|
||||
206*15
|
||||
207*15
|
||||
208*15
|
||||
209*15
|
||||
210*15
|
||||
211*15
|
||||
212*15
|
||||
213*15
|
||||
214*15
|
||||
215*15
|
||||
216*15
|
||||
217*15
|
||||
218*15
|
||||
219*15
|
||||
220*15
|
||||
221*15
|
||||
222*15
|
||||
223*15
|
||||
224*15
|
||||
225*15
|
||||
226*15
|
||||
227*15
|
||||
228*15
|
||||
229*15
|
||||
230*15
|
||||
231*15
|
||||
232*15
|
||||
233*15
|
||||
234*15
|
||||
235*15
|
||||
236*15
|
||||
237*15
|
||||
238*15
|
||||
239*15
|
||||
240*15
|
||||
241*15
|
||||
242*15
|
||||
243*15
|
||||
244*15
|
||||
245*15
|
||||
246*15
|
||||
247*15
|
||||
248*15
|
||||
249*15
|
||||
250*15
|
||||
251*15
|
||||
252*15
|
||||
253*15
|
||||
254*15
|
||||
255*15
|
||||
256*15
|
||||
257*15
|
||||
258*15
|
||||
259*15
|
||||
260*15
|
||||
261*15
|
||||
262*15
|
||||
263*15
|
||||
264*15
|
||||
265*15
|
||||
266*15
|
||||
267*15
|
||||
268*15
|
||||
269*15
|
||||
270*15
|
||||
271*15
|
||||
272*15
|
||||
273*15
|
||||
274*15
|
||||
275*15
|
||||
276*15
|
||||
277*15
|
||||
278*15
|
||||
279*15
|
||||
280*15
|
||||
281*15
|
||||
282*15
|
||||
283*15
|
||||
284*15
|
||||
285*15
|
||||
286*15
|
||||
287*15
|
||||
288*15
|
||||
289*15
|
||||
290*15
|
||||
291*15
|
||||
292*15
|
||||
293*15
|
||||
294*15
|
||||
295*15
|
||||
296*15
|
||||
297*15
|
||||
298*15
|
||||
299*15
|
||||
300*15
|
||||
301*15
|
||||
302*15
|
||||
303*15
|
||||
304*15
|
||||
305*15
|
||||
306*15
|
||||
307*15
|
||||
308*15
|
||||
309*15
|
||||
310*15
|
||||
311*15
|
||||
312*15
|
||||
313*15
|
||||
314*15
|
||||
315*15
|
||||
316*15
|
||||
317*15
|
||||
318*15
|
||||
319*15
|
||||
320*15
|
||||
321*15
|
||||
322*15
|
||||
323*15
|
||||
324*15
|
||||
325*15
|
||||
326*15
|
||||
327*15
|
||||
328*15
|
||||
329*15
|
||||
330*15
|
||||
331*15
|
||||
332*15
|
||||
333*15
|
||||
334*15
|
||||
335*15
|
||||
336*15
|
||||
337*15
|
||||
338*15
|
||||
339*15
|
||||
340*15
|
||||
341*15
|
||||
342*15
|
||||
343*15
|
||||
344*15
|
||||
345*15
|
||||
346*15
|
||||
347*15
|
||||
348*15
|
||||
349*15
|
||||
350*15
|
||||
351*15
|
||||
352*15
|
||||
353*15
|
||||
354*15
|
||||
355*15
|
||||
356*15
|
||||
357*15
|
||||
358*15
|
||||
359*15
|
||||
360*15
|
||||
361*15
|
||||
362*15
|
||||
363*15
|
||||
364*15
|
||||
365*15
|
||||
366*15
|
||||
367*15
|
||||
368*15
|
||||
369*15
|
||||
370*15
|
||||
371*15
|
||||
372*15
|
||||
373*15
|
||||
374*15
|
||||
375*15
|
||||
376*15
|
||||
377*15
|
||||
378*15
|
||||
379*15
|
||||
380*15
|
||||
381*15
|
||||
382*15
|
||||
383*15
|
||||
384*15
|
||||
385*15
|
||||
386*15
|
||||
387*15
|
||||
388*15
|
||||
389*15
|
||||
390*15
|
||||
391*15
|
||||
392*15
|
||||
393*15
|
||||
394*15
|
||||
395*15
|
||||
396*15
|
||||
397*15
|
||||
398*15
|
||||
399*15
|
||||
400*15
|
||||
401*15
|
||||
402*15
|
||||
403*15
|
||||
404*15
|
||||
405*15
|
||||
406*15
|
||||
407*15
|
||||
408*15
|
||||
409*15
|
||||
410*15
|
||||
411*15
|
||||
412*15
|
||||
413*15
|
||||
414*15
|
||||
415*15
|
||||
416*15
|
||||
417*15
|
||||
418*15
|
||||
419*15
|
||||
420*15
|
||||
421*15
|
||||
422*15
|
||||
423*15
|
||||
424*15
|
||||
425*15
|
||||
426*15
|
||||
427*15
|
||||
428*15
|
||||
429*15
|
||||
430*15
|
||||
431*15
|
||||
432*15
|
||||
433*15
|
||||
434*15
|
||||
435*15
|
||||
436*15
|
||||
437*15
|
||||
438*15
|
||||
439*15
|
||||
interp:1
|
||||
0*300
|
||||
1*300
|
||||
0*300
|
||||
2*300
|
||||
0*300
|
||||
3*300
|
||||
0*300
|
||||
1*300
|
||||
2*300
|
||||
1*300
|
||||
3*300
|
||||
1*300
|
||||
0*300
|
||||
2*300
|
||||
1*300
|
||||
2*300
|
||||
3*300
|
||||
2*300
|
||||
0*300
|
||||
3*300
|
||||
1*300
|
||||
3*300
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 198 KiB |
@@ -4726,7 +4726,7 @@ At night monsters come out, make sure to build a shelter before that happens.</v
|
||||
</data>
|
||||
|
||||
<data name="IDS_TOOLTIPS_WHAT_IS_THIS">
|
||||
<value>What's This?</value>
|
||||
<value>Info</value>
|
||||
</data>
|
||||
|
||||
<data name="IDS_TOOLTIPS_SHARE">
|
||||
|
||||
@@ -214,9 +214,8 @@ void GameRenderer::tick(bool first) // 4J - add bFirst
|
||||
{
|
||||
shared_ptr<Player> yBobPlayer = dynamic_pointer_cast<Player>(mc->cameraTargetPlayer);
|
||||
float target = 0.0f;
|
||||
if (yBobPlayer != nullptr && yBobPlayer->isElytraFlying())
|
||||
if (yBobPlayer != nullptr && yBobPlayer->isElytraFlying())
|
||||
{
|
||||
|
||||
target = (float)(atan(-yBobPlayer->yd * 0.2) * 15.0);
|
||||
}
|
||||
m_yBob += (target - m_yBob) * 0.8f;
|
||||
@@ -482,7 +481,8 @@ void GameRenderer::bobView(float a)
|
||||
glRotatef((float) tilt, 1, 0, 0);
|
||||
|
||||
float yBobAngle = m_yBobO + (m_yBob - m_yBobO) * a;
|
||||
if (fabsf(yBobAngle) > 0.001f)
|
||||
shared_ptr<LocalPlayer> yBobLocalPlayer = dynamic_pointer_cast<LocalPlayer>(mc->cameraTargetPlayer);
|
||||
if (fabsf(yBobAngle) > 0.001f && yBobLocalPlayer != nullptr && yBobLocalPlayer->isElytraFlying() && !yBobLocalPlayer->ThirdPersonView())
|
||||
glRotatef(yBobAngle, 1, 0, 0);
|
||||
|
||||
}
|
||||
@@ -742,7 +742,11 @@ void GameRenderer::setupCamera(float a, int eye)
|
||||
glTranslatef(static_cast<float>(zoom_x), static_cast<float>(-zoom_y), 0);
|
||||
glScaled(zoom, zoom, 1);
|
||||
}
|
||||
gluPerspective(fov, aspect, 0.05f, renderDistance * 2);
|
||||
{
|
||||
auto _sp = dynamic_pointer_cast<Player>(mc->cameraTargetPlayer);
|
||||
float nearClip = (_sp && _sp->abilities.spectatorMode) ? 0.99f : 0.05f;
|
||||
gluPerspective(fov, aspect, nearClip, renderDistance * 2);
|
||||
}
|
||||
|
||||
if (mc->gameMode->isCutScene())
|
||||
{
|
||||
@@ -825,7 +829,11 @@ void GameRenderer::renderItemInHand(float a, int eye)
|
||||
glTranslatef(static_cast<float>(zoom_x), static_cast<float>(-zoom_y), 0);
|
||||
glScaled(zoom, zoom, 1);
|
||||
}
|
||||
gluPerspective(fov, aspect, 0.05f, renderDistance * 2);
|
||||
{
|
||||
auto _sp = dynamic_pointer_cast<Player>(mc->cameraTargetPlayer);
|
||||
float nearClip = (_sp && _sp->abilities.spectatorMode) ? 0.99f : 0.05f;
|
||||
gluPerspective(fov, aspect, nearClip, renderDistance * 2);
|
||||
}
|
||||
|
||||
if (mc->gameMode->isCutScene())
|
||||
{
|
||||
|
||||
@@ -685,9 +685,13 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse)
|
||||
{
|
||||
characterDisplayTimer[iPad] = 30;
|
||||
}
|
||||
else if( minecraft->player->isElytraFlying() )
|
||||
{
|
||||
characterDisplayTimer[iPad] = 30;
|
||||
}
|
||||
else if( minecraft->player->abilities.flying)
|
||||
{
|
||||
characterDisplayTimer[iPad] = 5; // quickly get rid of the player display if they stop flying
|
||||
characterDisplayTimer[iPad] = 5;
|
||||
}
|
||||
else if( characterDisplayTimer[iPad] > 0 )
|
||||
{
|
||||
@@ -696,8 +700,9 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse)
|
||||
bool displayCrouch = minecraft->player->isSneaking() || ( characterDisplayTimer[iPad] > 0 );
|
||||
bool displaySprint = minecraft->player->isSprinting() || ( characterDisplayTimer[iPad] > 0 );
|
||||
bool displayFlying = minecraft->player->abilities.flying || ( characterDisplayTimer[iPad] > 0 );
|
||||
bool displayElytra = minecraft->player->isElytraFlying() || ( characterDisplayTimer[iPad] > 0 );
|
||||
|
||||
if( bDisplayGui && (displayCrouch || displaySprint || displayFlying) )
|
||||
if( bDisplayGui && (displayCrouch || displaySprint || displayElytra || displayFlying) )
|
||||
{
|
||||
EntityRenderDispatcher::instance->prepare(minecraft->level, minecraft->textures, minecraft->font, minecraft->cameraTargetPlayer, minecraft->crosshairPickMob, minecraft->options, a);
|
||||
glEnable(GL_RESCALE_NORMAL);
|
||||
@@ -714,7 +719,10 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse)
|
||||
#endif
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(static_cast<float>(xo), static_cast<float>(yo), 50);
|
||||
float pitchOffset = minecraft->player->isElytraFlying()
|
||||
? -minecraft->player->xRot / 180.0f * 40.0f
|
||||
: 0.0f;
|
||||
glTranslatef(static_cast<float>(xo), static_cast<float>(yo) + pitchOffset, 50);
|
||||
|
||||
// correct paper doll aspect ratio
|
||||
float ss = 12.0f;
|
||||
@@ -756,7 +764,8 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse)
|
||||
Lighting::turnOn();
|
||||
glRotatef(-45 - 90, 0, 1, 0);
|
||||
|
||||
const float xRotAngle = -(float) atan(yd / 40.0f) * 20;
|
||||
bool elytraFlying = minecraft->player->isElytraFlying();
|
||||
const float xRotAngle = elytraFlying ? 0.0f : -(float) atan(yd / 40.0f) * 20;
|
||||
glRotatef(xRotAngle, 1, 0, 0);
|
||||
float bodyRot = (minecraft->player->yBodyRotO + (minecraft->player->yBodyRot - minecraft->player->yBodyRotO));
|
||||
// Fixed rotation angle of degrees, adjusted by bodyRot to negate the rotation that occurs in the renderer
|
||||
@@ -768,7 +777,7 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse)
|
||||
// Set head rotation to body rotation to make head static
|
||||
minecraft->player->yRot = bodyRot;
|
||||
minecraft->player->yRotO = minecraft->player->yRot;
|
||||
minecraft->player->xRot = xRotAngle;
|
||||
minecraft->player->xRot = elytraFlying ? oxr : xRotAngle;
|
||||
|
||||
minecraft->player->onFire = 0;
|
||||
minecraft->player->setSharedFlag(Entity::FLAG_ONFIRE, false);
|
||||
|
||||
@@ -1387,9 +1387,15 @@ void HumanoidModel::setupAnim(float time, float r, float bob, float yRot, float
|
||||
if (elytraCrouching)
|
||||
{
|
||||
arm0->xRot = PI; arm0->yRot = 0.0f; arm0->zRot = 0.0f; arm0->y = 2.0f;
|
||||
if (sleeve0) { sleeve0->xRot = PI; sleeve0->yRot = 0.0f; sleeve0->zRot = 0.0f; sleeve0->y = 2.0f; }
|
||||
|
||||
arm1->xRot = 0.0f; arm1->yRot = 0.0f; arm1->zRot = 0.0f; arm1->y = 2.0f;
|
||||
if (sleeve1) { sleeve1->xRot = 0.0f; sleeve1->yRot = 0.0f; sleeve1->zRot = 0.0f; sleeve1->y = 2.0f; }
|
||||
|
||||
leg0->xRot = 0.0f; leg0->yRot = 0.0f; leg0->zRot = 0.0f;
|
||||
leg1->xRot = 0.0f; leg1->yRot = 0.0f; leg1->zRot = 0.0f;
|
||||
if (pants0) { pants0->xRot = 0.0f; pants0->yRot = 0.0f; pants0->zRot = 0.0f; }
|
||||
if (pants1) { pants1->xRot = 0.0f; pants1->yRot = 0.0f; pants1->zRot = 0.0f; }
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1404,14 +1410,30 @@ void HumanoidModel::setupAnim(float time, float r, float bob, float yRot, float
|
||||
|
||||
arm0->xRot = Mth::cos(elytraTime + PI) * armAmp;
|
||||
arm0->yRot = 0.0f; arm0->zRot = 0.0f; arm0->y = 2.0f;
|
||||
if (sleeve0) { sleeve0->xRot = arm0->xRot; sleeve0->yRot = 0.0f; sleeve0->zRot = 0.0f; sleeve0->y = 2.0f; }
|
||||
|
||||
if (attackTime > -9990.0f)
|
||||
{
|
||||
float elytraSwing = 1.0f - attackTime;
|
||||
elytraSwing *= elytraSwing; elytraSwing *= elytraSwing;
|
||||
elytraSwing = 1.0f - elytraSwing;
|
||||
float elytraAA = Mth::sin(elytraSwing * PI);
|
||||
float elytraBB = Mth::sin(attackTime * PI) * -(head->xRot - 0.7f) * 0.75f;
|
||||
arm0->xRot -= elytraAA * 1.2f + elytraBB;
|
||||
arm0->zRot = Mth::sin(attackTime * PI) * -0.4f;
|
||||
if (sleeve0) { sleeve0->xRot -= elytraAA * 1.2f + elytraBB; sleeve0->zRot = Mth::sin(attackTime * PI) * -0.4f; }
|
||||
}
|
||||
|
||||
arm1->xRot = Mth::cos(elytraTime) * armAmp;
|
||||
arm1->yRot = 0.0f; arm1->zRot = 0.0f; arm1->y = 2.0f;
|
||||
if (sleeve1) { sleeve1->xRot = arm1->xRot; sleeve1->yRot = 0.0f; sleeve1->zRot = 0.0f; sleeve1->y = 2.0f; }
|
||||
|
||||
leg0->xRot = Mth::cos(elytraTime) * legAmp;
|
||||
leg0->yRot = 0.0f; leg0->zRot = 0.0f;
|
||||
leg1->xRot = Mth::cos(elytraTime + PI) * legAmp;
|
||||
leg1->yRot = 0.0f; leg1->zRot = 0.0f;
|
||||
if (pants0) { pants0->xRot = leg0->xRot; pants0->yRot = 0.0f; pants0->zRot = 0.0f; }
|
||||
if (pants1) { pants1->xRot = leg1->xRot; pants1->yRot = 0.0f; pants1->zRot = 0.0f; }
|
||||
}
|
||||
|
||||
body->xRot = 0.0f;
|
||||
|
||||
@@ -128,6 +128,8 @@ LocalPlayer::LocalPlayer(Minecraft *minecraft, Level *level, User *user, int dim
|
||||
|
||||
LocalPlayer::~LocalPlayer()
|
||||
{
|
||||
if (minecraft != nullptr && minecraft->soundEngine != nullptr)
|
||||
minecraft->soundEngine->stopElytraSound();
|
||||
if( this->input != nullptr )
|
||||
delete input;
|
||||
}
|
||||
@@ -168,6 +170,9 @@ bool LocalPlayer::isEffectiveAi() const
|
||||
|
||||
void LocalPlayer::aiStep()
|
||||
{
|
||||
if (abilities.spectatorMode)
|
||||
noPhysics = true;
|
||||
|
||||
if (sprintTime > 0)
|
||||
{
|
||||
sprintTime--;
|
||||
|
||||
@@ -0,0 +1,340 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#undef OutputDebugStringA
|
||||
#undef OutputDebugStringW
|
||||
#undef OutputDebugString
|
||||
|
||||
#include "Logger.h"
|
||||
#include <dbghelp.h>
|
||||
#include <time.h>
|
||||
#include <intrin.h>
|
||||
|
||||
static FILE *s_logFile = nullptr;
|
||||
static CRITICAL_SECTION s_cs;
|
||||
static bool s_csInit = false;
|
||||
|
||||
static const char *s_wittyComments[] =
|
||||
{
|
||||
"Who set us up the TNT?",
|
||||
"Everything's a creeper when you think about it",
|
||||
"I bet Notch wouldn't have this problem",
|
||||
"Oops.",
|
||||
"Why did you do that?",
|
||||
"Uh... Did I do that?",
|
||||
"I just don't know what went wrong",
|
||||
"Quite honestly, I wouldn't worry myself about that.",
|
||||
"This doesn't make any sense!",
|
||||
"This is a bug, not a feature!",
|
||||
"The server is on fire.",
|
||||
"My bad.",
|
||||
"I feel sad now :(",
|
||||
"Don't be sad, have a hug! <3",
|
||||
"You should try our sister game, Minceraft!",
|
||||
"Hi. I'm Minecraft, and I'm a crashaholic.",
|
||||
"Ooh. Shiny.",
|
||||
"This is not good.",
|
||||
"Abandon ship!",
|
||||
"Oh - I know what I did wrong!",
|
||||
"Shall we play a game?",
|
||||
"Quite honestly, I wouldn't worry myself about that.",
|
||||
"Sorry, Dave.",
|
||||
"We're sorry, we're sorry, we're sorry...",
|
||||
"Never gonna give you up.",
|
||||
"A wild Herobrine appeared.",
|
||||
"Surprise! Haha. Well, this is awkward.",
|
||||
"Would you like a cupcake?",
|
||||
"Oh man. I thought that might happen.",
|
||||
"This is not a good sign.",
|
||||
};
|
||||
|
||||
static void writeRaw(const char *msg)
|
||||
{
|
||||
if (!s_logFile) return;
|
||||
fputs(msg, s_logFile);
|
||||
fflush(s_logFile);
|
||||
}
|
||||
|
||||
static void writeLineA(const char *msg)
|
||||
{
|
||||
if (!s_logFile) return;
|
||||
EnterCriticalSection(&s_cs);
|
||||
fputs(msg, s_logFile);
|
||||
fputc('\n', s_logFile);
|
||||
fflush(s_logFile);
|
||||
LeaveCriticalSection(&s_cs);
|
||||
}
|
||||
|
||||
static void getTimestamp(char *buf, size_t size)
|
||||
{
|
||||
time_t t = time(nullptr);
|
||||
struct tm tm_info;
|
||||
localtime_s(&tm_info, &t);
|
||||
strftime(buf, size, "%Y-%m-%d %H:%M:%S", &tm_info);
|
||||
}
|
||||
|
||||
static void getCpuName(char *buf, size_t size)
|
||||
{
|
||||
int regs[4] = {};
|
||||
char name[49] = {};
|
||||
__cpuid(regs, 0x80000002); memcpy(name, regs, 16);
|
||||
__cpuid(regs, 0x80000003); memcpy(name + 16, regs, 16);
|
||||
__cpuid(regs, 0x80000004); memcpy(name + 32, regs, 16);
|
||||
name[48] = '\0';
|
||||
const char *p = name;
|
||||
while (*p == ' ') p++;
|
||||
strncpy_s(buf, size, p, _TRUNCATE);
|
||||
}
|
||||
|
||||
static void getOsName(char *buf, size_t size)
|
||||
{
|
||||
DWORD major = 0, minor = 0, build = 0;
|
||||
|
||||
HKEY hKey = nullptr;
|
||||
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
||||
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
|
||||
{
|
||||
DWORD val = 0, sz = sizeof(val);
|
||||
if (RegQueryValueExW(hKey, L"CurrentMajorVersionNumber", nullptr, nullptr, (LPBYTE)&val, &sz) == ERROR_SUCCESS) major = val;
|
||||
sz = sizeof(val);
|
||||
if (RegQueryValueExW(hKey, L"CurrentMinorVersionNumber", nullptr, nullptr, (LPBYTE)&val, &sz) == ERROR_SUCCESS) minor = val;
|
||||
sz = sizeof(val);
|
||||
if (RegQueryValueExW(hKey, L"CurrentBuildNumber", nullptr, nullptr, (LPBYTE)&val, &sz) == ERROR_SUCCESS) build = val;
|
||||
if (build == 0)
|
||||
{
|
||||
wchar_t strBuild[16] = {};
|
||||
DWORD strSz = sizeof(strBuild);
|
||||
if (RegQueryValueExW(hKey, L"CurrentBuildNumber", nullptr, nullptr, (LPBYTE)strBuild, &strSz) == ERROR_SUCCESS)
|
||||
build = (DWORD)_wtoi(strBuild);
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
|
||||
SYSTEM_INFO si = {};
|
||||
GetNativeSystemInfo(&si);
|
||||
const char *arch = (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) ? "amd64" : "x86";
|
||||
|
||||
snprintf(buf, size, "Windows %lu.%lu (Build %lu) (%s)", major, minor, build, arch);
|
||||
}
|
||||
|
||||
static const char *exceptionName(DWORD code)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case EXCEPTION_ACCESS_VIOLATION: return "ACCESS_VIOLATION";
|
||||
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: return "ARRAY_BOUNDS_EXCEEDED";
|
||||
case EXCEPTION_BREAKPOINT: return "BREAKPOINT";
|
||||
case EXCEPTION_DATATYPE_MISALIGNMENT: return "DATATYPE_MISALIGNMENT";
|
||||
case EXCEPTION_FLT_DENORMAL_OPERAND: return "FLT_DENORMAL_OPERAND";
|
||||
case EXCEPTION_FLT_DIVIDE_BY_ZERO: return "FLT_DIVIDE_BY_ZERO";
|
||||
case EXCEPTION_FLT_INEXACT_RESULT: return "FLT_INEXACT_RESULT";
|
||||
case EXCEPTION_FLT_INVALID_OPERATION: return "FLT_INVALID_OPERATION";
|
||||
case EXCEPTION_FLT_OVERFLOW: return "FLT_OVERFLOW";
|
||||
case EXCEPTION_FLT_STACK_CHECK: return "FLT_STACK_CHECK";
|
||||
case EXCEPTION_FLT_UNDERFLOW: return "FLT_UNDERFLOW";
|
||||
case EXCEPTION_ILLEGAL_INSTRUCTION: return "ILLEGAL_INSTRUCTION";
|
||||
case EXCEPTION_IN_PAGE_ERROR: return "IN_PAGE_ERROR";
|
||||
case EXCEPTION_INT_DIVIDE_BY_ZERO: return "INT_DIVIDE_BY_ZERO";
|
||||
case EXCEPTION_INT_OVERFLOW: return "INT_OVERFLOW";
|
||||
case EXCEPTION_INVALID_DISPOSITION: return "INVALID_DISPOSITION";
|
||||
case EXCEPTION_NONCONTINUABLE_EXCEPTION: return "NONCONTINUABLE_EXCEPTION";
|
||||
case EXCEPTION_PRIV_INSTRUCTION: return "PRIV_INSTRUCTION";
|
||||
case EXCEPTION_SINGLE_STEP: return "SINGLE_STEP";
|
||||
case EXCEPTION_STACK_OVERFLOW: return "STACK_OVERFLOW";
|
||||
default: return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
static LONG WINAPI crashHandler(EXCEPTION_POINTERS *ep)
|
||||
{
|
||||
if (!s_logFile) return EXCEPTION_CONTINUE_SEARCH;
|
||||
|
||||
DWORD code = ep->ExceptionRecord->ExceptionCode;
|
||||
const char *name = exceptionName(code);
|
||||
|
||||
srand((unsigned)time(nullptr));
|
||||
const char *comment = s_wittyComments[rand() % (sizeof(s_wittyComments) / sizeof(s_wittyComments[0]))];
|
||||
|
||||
char timestamp[64];
|
||||
getTimestamp(timestamp, sizeof(timestamp));
|
||||
|
||||
char description[128];
|
||||
if (code == EXCEPTION_ACCESS_VIOLATION && ep->ExceptionRecord->NumberParameters >= 2)
|
||||
{
|
||||
const char *op = ep->ExceptionRecord->ExceptionInformation[0] == 1 ? "write" : "read";
|
||||
snprintf(description, sizeof(description),
|
||||
"%s (0x%08X) - Attempted to %s from address 0x%p",
|
||||
name, code, op, (void*)ep->ExceptionRecord->ExceptionInformation[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(description, sizeof(description), "%s (0x%08X)", name, code);
|
||||
}
|
||||
|
||||
EnterCriticalSection(&s_cs);
|
||||
|
||||
fprintf(s_logFile,
|
||||
"\n\n---- neoLegacy Crash Report ----\n"
|
||||
"// %s\n\n"
|
||||
"Time: %s\n"
|
||||
"Description: %s\n\n",
|
||||
comment, timestamp, description);
|
||||
|
||||
HANDLE proc = GetCurrentProcess();
|
||||
HANDLE thread = GetCurrentThread();
|
||||
|
||||
SymInitialize(proc, nullptr, TRUE);
|
||||
SymSetOptions(SYMOPT_LOAD_LINES | SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
|
||||
|
||||
CONTEXT ctx = *ep->ContextRecord;
|
||||
|
||||
STACKFRAME64 frame = {};
|
||||
#ifdef _WIN64
|
||||
DWORD machineType = IMAGE_FILE_MACHINE_AMD64;
|
||||
frame.AddrPC.Offset = ctx.Rip;
|
||||
frame.AddrStack.Offset = ctx.Rsp;
|
||||
#else
|
||||
DWORD machineType = IMAGE_FILE_MACHINE_I386;
|
||||
frame.AddrPC.Offset = ctx.Eip;
|
||||
frame.AddrStack.Offset = ctx.Esp;
|
||||
#endif
|
||||
frame.AddrPC.Mode = AddrModeFlat;
|
||||
frame.AddrStack.Mode = AddrModeFlat;
|
||||
|
||||
char symBuf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
|
||||
SYMBOL_INFO *sym = (SYMBOL_INFO*)symBuf;
|
||||
|
||||
IMAGEHLP_LINE64 line = {};
|
||||
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
|
||||
|
||||
fputs("Stack Trace:\n", s_logFile);
|
||||
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
if (!StackWalk64(machineType, proc, thread, &frame, &ctx,
|
||||
nullptr, SymFunctionTableAccess64, SymGetModuleBase64, nullptr))
|
||||
break;
|
||||
if (frame.AddrPC.Offset == 0) break;
|
||||
|
||||
sym->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
sym->MaxNameLen = MAX_SYM_NAME;
|
||||
|
||||
DWORD64 disp64 = 0;
|
||||
DWORD disp32 = 0;
|
||||
|
||||
if (SymFromAddr(proc, frame.AddrPC.Offset, &disp64, sym))
|
||||
{
|
||||
if (SymGetLineFromAddr64(proc, frame.AddrPC.Offset, &disp32, &line))
|
||||
fprintf(s_logFile, "\tat %s (%s:%lu)\n", sym->Name, line.FileName, line.LineNumber);
|
||||
else
|
||||
fprintf(s_logFile, "\tat %s+0x%llx\n", sym->Name, disp64);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(s_logFile, "\tat 0x%016llX\n", frame.AddrPC.Offset);
|
||||
}
|
||||
}
|
||||
|
||||
SymCleanup(proc);
|
||||
|
||||
fprintf(s_logFile,
|
||||
"\nA detailed walkthrough of the error, its code path and all known details is as follows:\n"
|
||||
"---------------------------------------------------------------------------\n\n");
|
||||
|
||||
fprintf(s_logFile, "-- System Details --\nDetails:\n");
|
||||
|
||||
fprintf(s_logFile, "\tneoLegacy Version: %s\n", NEOL_VERSION);
|
||||
|
||||
char osBuf[128];
|
||||
getOsName(osBuf, sizeof(osBuf));
|
||||
fprintf(s_logFile, "\tOperating System: %s\n", osBuf);
|
||||
|
||||
char cpuBuf[64];
|
||||
getCpuName(cpuBuf, sizeof(cpuBuf));
|
||||
fprintf(s_logFile, "\tCPU: %s\n", cpuBuf);
|
||||
|
||||
MEMORYSTATUSEX mem = {};
|
||||
mem.dwLength = sizeof(mem);
|
||||
GlobalMemoryStatusEx(&mem);
|
||||
DWORDLONG freeMB = mem.ullAvailPhys / (1024 * 1024);
|
||||
DWORDLONG totalMB = mem.ullTotalPhys / (1024 * 1024);
|
||||
fprintf(s_logFile, "\tMemory: %llu bytes (%llu MB) free / %llu bytes (%llu MB) total\n",
|
||||
mem.ullAvailPhys, freeMB, mem.ullTotalPhys, totalMB);
|
||||
|
||||
fflush(s_logFile);
|
||||
LeaveCriticalSection(&s_cs);
|
||||
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
void Logger::init()
|
||||
{
|
||||
InitializeCriticalSection(&s_cs);
|
||||
s_csInit = true;
|
||||
|
||||
char exePath[MAX_PATH] = {};
|
||||
GetModuleFileNameA(nullptr, exePath, MAX_PATH);
|
||||
char *slash = strrchr(exePath, '\\');
|
||||
if (slash) *(slash + 1) = '\0';
|
||||
strcat_s(exePath, "neoLegacy_log.txt");
|
||||
|
||||
fopen_s(&s_logFile, exePath, "w");
|
||||
if (!s_logFile) return;
|
||||
|
||||
SetUnhandledExceptionFilter(crashHandler);
|
||||
|
||||
char timestamp[64];
|
||||
getTimestamp(timestamp, sizeof(timestamp));
|
||||
|
||||
char osBuf[128];
|
||||
getOsName(osBuf, sizeof(osBuf));
|
||||
|
||||
char cpuBuf[64];
|
||||
getCpuName(cpuBuf, sizeof(cpuBuf));
|
||||
|
||||
fprintf(s_logFile,
|
||||
"neoLegacy log started %s\n"
|
||||
"Version: %s | OS: %s | CPU: %s\n"
|
||||
"--------------------------------------------------------------------------\n\n",
|
||||
timestamp, NEOL_VERSION, osBuf, cpuBuf);
|
||||
fflush(s_logFile);
|
||||
}
|
||||
|
||||
void Logger::shutdown()
|
||||
{
|
||||
if (s_logFile)
|
||||
{
|
||||
char timestamp[64];
|
||||
getTimestamp(timestamp, sizeof(timestamp));
|
||||
fprintf(s_logFile, "\n--------------------------------------------------------------------------\n");
|
||||
fprintf(s_logFile, "neoLegacy log ended %s\n", timestamp);
|
||||
fclose(s_logFile);
|
||||
s_logFile = nullptr;
|
||||
}
|
||||
if (s_csInit)
|
||||
{
|
||||
DeleteCriticalSection(&s_cs);
|
||||
s_csInit = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::interceptA(const char *msg)
|
||||
{
|
||||
#ifndef _FINAL_BUILD
|
||||
OutputDebugStringA(msg);
|
||||
#endif
|
||||
writeLineA(msg);
|
||||
}
|
||||
|
||||
void Logger::interceptW(const wchar_t *msg)
|
||||
{
|
||||
#ifndef _FINAL_BUILD
|
||||
OutputDebugStringW(msg);
|
||||
#endif
|
||||
if (!s_logFile) return;
|
||||
int needed = WideCharToMultiByte(CP_UTF8, 0, msg, -1, nullptr, 0, nullptr, nullptr);
|
||||
if (needed <= 0) return;
|
||||
char *buf = new char[needed];
|
||||
WideCharToMultiByte(CP_UTF8, 0, msg, -1, buf, needed, nullptr, nullptr);
|
||||
writeLineA(buf);
|
||||
delete[] buf;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#define NEOL_VERSION "TU43"
|
||||
|
||||
class Logger
|
||||
{
|
||||
public:
|
||||
static void init();
|
||||
static void shutdown();
|
||||
static void interceptA(const char *msg);
|
||||
static void interceptW(const wchar_t *msg);
|
||||
};
|
||||
@@ -4342,10 +4342,10 @@ void Minecraft::releaseLevel(int message)
|
||||
// time when exiting from an online game
|
||||
void Minecraft::forceStatsSave(int idx)
|
||||
{
|
||||
//4J Gordon: Force a stats save
|
||||
if (idx < 0 || idx >= 4 || stats[idx] == nullptr) return;
|
||||
|
||||
stats[idx]->save(idx, true);
|
||||
|
||||
//4J Gordon: If the player is signed in, save the leaderboards
|
||||
if( ProfileManager.IsSignedInLive(idx) )
|
||||
{
|
||||
int tempLockedProfile = ProfileManager.GetLockedProfile();
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "ClientConnection.h"
|
||||
#include "../Minecraft.World/net.minecraft.world.level.h"
|
||||
#include "../Minecraft.World/net.minecraft.network.h"
|
||||
#include "../Minecraft.World/PlayerActionPacket.h"
|
||||
#include "../Minecraft.World/Mth.h"
|
||||
#include "../Minecraft.World/AABB.h"
|
||||
#include "../Minecraft.World/net.minecraft.stats.h"
|
||||
@@ -76,7 +77,7 @@ void MultiplayerLocalPlayer::tick()
|
||||
{
|
||||
if (isRiding())
|
||||
{
|
||||
connection->send(std::make_shared<MovePlayerPacket::Rot>(yRot, xRot, onGround, abilities.flying));
|
||||
connection->send(std::make_shared<MovePlayerPacket::Rot>(yRot, xRot, onGround, abilities.flying || isElytraFlying()));
|
||||
connection->send(std::make_shared<PlayerInputPacket>(xxa, yya, input->jumping, input->sneaking));
|
||||
}
|
||||
else
|
||||
@@ -131,26 +132,26 @@ void MultiplayerLocalPlayer::sendPosition()
|
||||
bool rot = rydd != 0 || rxdd != 0;
|
||||
if (riding != nullptr)
|
||||
{
|
||||
connection->send(std::make_shared<MovePlayerPacket::PosRot>(xd, -999, -999, zd, yRot, xRot, onGround, abilities.flying));
|
||||
connection->send(std::make_shared<MovePlayerPacket::PosRot>(xd, -999, -999, zd, yRot, xRot, onGround, abilities.flying || isElytraFlying()));
|
||||
move = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (move && rot)
|
||||
{
|
||||
connection->send(std::make_shared<MovePlayerPacket::PosRot>(x, bb->y0, y, z, yRot, xRot, onGround, abilities.flying));
|
||||
connection->send(std::make_shared<MovePlayerPacket::PosRot>(x, bb->y0, y, z, yRot, xRot, onGround, abilities.flying || isElytraFlying()));
|
||||
}
|
||||
else if (move)
|
||||
{
|
||||
connection->send(std::make_shared<MovePlayerPacket::Pos>(x, bb->y0, y, z, onGround, abilities.flying));
|
||||
connection->send(std::make_shared<MovePlayerPacket::Pos>(x, bb->y0, y, z, onGround, abilities.flying || isElytraFlying()));
|
||||
}
|
||||
else if (rot)
|
||||
{
|
||||
connection->send(std::make_shared<MovePlayerPacket::Rot>(yRot, xRot, onGround, abilities.flying));
|
||||
connection->send(std::make_shared<MovePlayerPacket::Rot>(yRot, xRot, onGround, abilities.flying || isElytraFlying()));
|
||||
}
|
||||
else
|
||||
{
|
||||
connection->send(std::make_shared<MovePlayerPacket>(onGround, abilities.flying));
|
||||
connection->send(std::make_shared<MovePlayerPacket>(onGround, abilities.flying || isElytraFlying()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,6 +211,21 @@ void MultiplayerLocalPlayer::actuallyHurt(DamageSource *source, float dmg)
|
||||
setHealth(getHealth() - dmg);
|
||||
}
|
||||
|
||||
void MultiplayerLocalPlayer::onElytraKineticDamage(float damage)
|
||||
{
|
||||
if (damage <= 0.0f) return;
|
||||
int dmg = (int)damage;
|
||||
if ((float)dmg < damage) dmg++;
|
||||
if (dmg < 1) dmg = 1;
|
||||
connection->send(std::make_shared<PlayerActionPacket>(PlayerActionPacket::ELYTRA_IMPACT, dmg, 0, 0, 0));
|
||||
}
|
||||
|
||||
void MultiplayerLocalPlayer::onElytraFallDamage(int amount)
|
||||
{
|
||||
if (amount <= 0) return;
|
||||
connection->send(std::make_shared<PlayerActionPacket>(PlayerActionPacket::ELYTRA_FALL_DAMAGE, amount, 0, 0, 0));
|
||||
}
|
||||
|
||||
// 4J Added override to capture event for tutorial messages
|
||||
void MultiplayerLocalPlayer::completeUsingItem()
|
||||
{
|
||||
|
||||
@@ -44,6 +44,8 @@ public:
|
||||
virtual void respawn();
|
||||
protected:
|
||||
virtual void actuallyHurt(DamageSource *source, float dmg);
|
||||
virtual void onElytraKineticDamage(float damage);
|
||||
virtual void onElytraFallDamage(int amount);
|
||||
|
||||
// 4J Added override to capture event for tutorial messages
|
||||
virtual void completeUsingItem();
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include "../Minecraft.World/net.minecraft.world.level.dimension.h"
|
||||
#include "../Minecraft.World/net.minecraft.world.item.h"
|
||||
#include "../Minecraft.World/net.minecraft.world.item.trading.h"
|
||||
#include "../Minecraft.World/net.minecraft.world.damagesource.h"
|
||||
#include "../Minecraft.World/net.minecraft.world.effect.h"
|
||||
#include "../Minecraft.World/net.minecraft.world.inventory.h"
|
||||
#include "../Minecraft.World/net.minecraft.world.level.tile.entity.h"
|
||||
#include "../Minecraft.World/net.minecraft.world.level.saveddata.h"
|
||||
@@ -85,6 +87,8 @@ PlayerConnection::PlayerConnection(MinecraftServer *server, Connection *connecti
|
||||
done = false;
|
||||
tickCount = 0;
|
||||
aboveGroundTickCount = 0;
|
||||
elytraDurabilityTicks = 0;
|
||||
elytraBoostCooldown = 0;
|
||||
xLastOk = yLastOk = zLastOk = 0;
|
||||
synched = true;
|
||||
hasDoneFirstTickFourKit = false;
|
||||
@@ -460,14 +464,20 @@ void PlayerConnection::handleMovePlayer(shared_ptr<MovePlayerPacket> packet)
|
||||
return;
|
||||
}
|
||||
bool newOk = level->getCubes(player, playerBB->copy()->shrink(r, r, r))->empty();
|
||||
if (oldOk && (fail || !newOk) && !player->isSleeping())
|
||||
if (oldOk && (fail || !newOk) && !player->isSleeping() && !player->abilities.spectatorMode)
|
||||
{
|
||||
teleport(xLastOk, yLastOk, zLastOk, yRotT, xRotT);
|
||||
return;
|
||||
}
|
||||
if (player->abilities.spectatorMode)
|
||||
{
|
||||
xLastOk = xt;
|
||||
yLastOk = yt;
|
||||
zLastOk = zt;
|
||||
}
|
||||
AABB *testBox = playerBB->copy()->grow(r, r, r)->expand(0, -0.55, 0);
|
||||
// && server.level.getCubes(player, testBox).size() == 0
|
||||
if (!server->isFlightAllowed() && !player->gameMode->isCreative() && !level->containsAnyBlocks(testBox) && !player->isAllowedToFly() )
|
||||
if (!server->isFlightAllowed() && !player->gameMode->isCreative() && !level->containsAnyBlocks(testBox) && !player->isAllowedToFly() && !player->abilities.spectatorMode)
|
||||
{
|
||||
if (oyDist >= (-0.5f / 16.0f))
|
||||
{
|
||||
@@ -490,9 +500,32 @@ void PlayerConnection::handleMovePlayer(shared_ptr<MovePlayerPacket> packet)
|
||||
|
||||
player->onGround = packet->onGround;
|
||||
server->getPlayers()->move(player);
|
||||
player->doCheckFallDamage(player->y - startY, packet->onGround);
|
||||
if (packet->isFlying)
|
||||
player->fallDistance = 0.0f;
|
||||
else
|
||||
player->doCheckFallDamage(player->y - startY, packet->onGround);
|
||||
|
||||
{
|
||||
shared_ptr<ItemInstance> chestItem = player->inventory->armor[LivingEntity::SLOT_CHEST - 1];
|
||||
bool elytraFlying = packet->isFlying && !player->onGround
|
||||
&& chestItem != nullptr && dynamic_cast<ElytraItem*>(chestItem->getItem()) != nullptr;
|
||||
if (elytraFlying)
|
||||
{
|
||||
if (++elytraDurabilityTicks >= 20)
|
||||
{
|
||||
elytraDurabilityTicks = 0;
|
||||
chestItem->hurtAndBreak(1, dynamic_pointer_cast<LivingEntity>(player));
|
||||
}
|
||||
if (elytraBoostCooldown > 0)
|
||||
elytraBoostCooldown--;
|
||||
}
|
||||
else
|
||||
{
|
||||
elytraDurabilityTicks = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((tickCount % SharedConstants::TICKS_PER_SECOND) == 0)
|
||||
else if ((tickCount % SharedConstants::TICKS_PER_SECOND) == 0 && !player->abilities.spectatorMode)
|
||||
{
|
||||
teleport(xLastOk, yLastOk, zLastOk, player->yRot, player->xRot);
|
||||
}
|
||||
@@ -574,6 +607,20 @@ void PlayerConnection::handlePlayerAction(shared_ptr<PlayerActionPacket> packet)
|
||||
player->releaseUsingItem();
|
||||
return;
|
||||
}
|
||||
else if (packet->action == PlayerActionPacket::ELYTRA_IMPACT)
|
||||
{
|
||||
float damage = (float)packet->x;
|
||||
if (damage > 0.0f)
|
||||
player->hurt(DamageSource::flyIntoWall, damage);
|
||||
return;
|
||||
}
|
||||
else if (packet->action == PlayerActionPacket::ELYTRA_FALL_DAMAGE)
|
||||
{
|
||||
float damage = (float)packet->x;
|
||||
if (damage > 0.0f)
|
||||
player->hurt(DamageSource::fall, damage);
|
||||
return;
|
||||
}
|
||||
|
||||
bool shouldVerifyLocation = false;
|
||||
if (packet->action == PlayerActionPacket::START_DESTROY_BLOCK) shouldVerifyLocation = true;
|
||||
@@ -668,6 +715,22 @@ void PlayerConnection::handleUseItem(shared_ptr<UseItemPacket> packet)
|
||||
}
|
||||
#endif
|
||||
player->gameMode->useItem(player, level, item);
|
||||
|
||||
if (item->getItem() != nullptr && item->getItem()->getBaseItemType() == Item::eBaseItemType_fireworks && !player->abilities.instabuild)
|
||||
{
|
||||
shared_ptr<ItemInstance> chestItem = player->inventory->armor[LivingEntity::SLOT_CHEST - 1];
|
||||
bool elytraFlying = !player->onGround
|
||||
&& chestItem != nullptr
|
||||
&& dynamic_cast<ElytraItem*>(chestItem->getItem()) != nullptr
|
||||
&& ElytraItem::isFlyEnabled(chestItem);
|
||||
if (elytraFlying && elytraBoostCooldown == 0)
|
||||
{
|
||||
elytraBoostCooldown = 20;
|
||||
item->count--;
|
||||
if (item->count <= 0)
|
||||
player->inventory->items[player->inventory->selected] = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((packet->getY() < server->getMaxBuildHeight() - 1) || (packet->getFace() != Facing::UP && packet->getY() < server->getMaxBuildHeight()))
|
||||
{
|
||||
@@ -1412,6 +1475,33 @@ if (cmd == L"tp" || cmd == L"teleport")
|
||||
shared_ptr<GameCommandPacket> packet = GiveItemCommand::preparePacket(target, item, amount, aux);
|
||||
server->getCommandDispatcher()->performCommand(player, eGameCommand_Give, packet->data);
|
||||
}
|
||||
#ifndef _CONTENT_PACKAGE
|
||||
else if (cmd == L"spectator")
|
||||
{
|
||||
player->m_spectatorMode = !player->m_spectatorMode;
|
||||
if (player->m_spectatorMode)
|
||||
{
|
||||
player->abilities.mayfly = true;
|
||||
player->abilities.flying = true;
|
||||
player->abilities.invulnerable = true;
|
||||
player->abilities.spectatorMode = true;
|
||||
player->abilities.setFlyingSpeed(0.1f);
|
||||
player->noPhysics = true;
|
||||
player->addEffect(new MobEffectInstance(MobEffect::nightVision->id, 0x7fffffff, 0, true));
|
||||
info(L"Spectator mode enabled.");
|
||||
}
|
||||
else
|
||||
{
|
||||
player->gameMode->getGameModeForPlayer()->updatePlayerAbilities(&player->abilities);
|
||||
player->abilities.spectatorMode = false;
|
||||
player->abilities.setFlyingSpeed(0.05f);
|
||||
player->noPhysics = false;
|
||||
player->removeEffect(MobEffect::nightVision->id);
|
||||
info(L"Spectator mode disabled.");
|
||||
}
|
||||
player->onUpdateAbilities();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void PlayerConnection::handleAnimate(shared_ptr<AnimatePacket> packet)
|
||||
|
||||
@@ -28,6 +28,8 @@ private:
|
||||
shared_ptr<ServerPlayer> player;
|
||||
int tickCount;
|
||||
int aboveGroundTickCount;
|
||||
int elytraDurabilityTicks;
|
||||
int elytraBoostCooldown;
|
||||
|
||||
bool didTick;
|
||||
bool hasDoneFirstTickFourKit;
|
||||
|
||||
@@ -191,6 +191,7 @@ ServerPlayer::ServerPlayer(MinecraftServer *server, Level *level, const wstring&
|
||||
connection = nullptr;
|
||||
lastMoveX = lastMoveZ = 0;
|
||||
spewTimer = 0;
|
||||
m_spectatorMode = false;
|
||||
lastRecordedHealthAndAbsorption = FLT_MIN;
|
||||
lastSentHealth = -99999999;
|
||||
lastSentFood = -99999999;
|
||||
|
||||
@@ -31,6 +31,7 @@ public:
|
||||
vector<int> entitiesToRemove;
|
||||
unordered_set<ChunkPos, ChunkPosKeyHash, ChunkPosKeyEq> seenChunks;
|
||||
int spewTimer;
|
||||
bool m_spectatorMode;
|
||||
|
||||
// 4J-Added, for 'Adventure Time' achievement.
|
||||
Biome *currentBiome;
|
||||
|
||||
@@ -43,6 +43,7 @@ StitchedTexture::StitchedTexture(const wstring &name, const wstring &filename) :
|
||||
frameOverride = nullptr;
|
||||
flags = 0;
|
||||
frames = nullptr;
|
||||
m_bInterpolate = false;
|
||||
m_fileName = filename;
|
||||
}
|
||||
|
||||
@@ -84,7 +85,8 @@ void StitchedTexture::init(Texture *source, vector<Texture *> *frames, int x, in
|
||||
{
|
||||
this->source = source;
|
||||
this->frames = frames;
|
||||
frame = -1; // Force an update of animated textures
|
||||
frame = -1;
|
||||
m_bInterpolate = false;
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->width = width;
|
||||
@@ -209,12 +211,21 @@ void StitchedTexture::cycleFrames()
|
||||
|
||||
current = frameOverride->at(frame);
|
||||
int newFrame = current.first;
|
||||
if (oldFrame != newFrame && newFrame >= 0 && newFrame < frames->size())
|
||||
if (oldFrame != newFrame && newFrame >= 0 && newFrame < (int)frames->size())
|
||||
{
|
||||
source->blit(x, y, frames->at(newFrame), rotated);
|
||||
}
|
||||
}
|
||||
|
||||
else if (m_bInterpolate)
|
||||
{
|
||||
int curIdx = current.first;
|
||||
int nextIdx = frameOverride->at((frame + 1) % frameOverride->size()).first;
|
||||
if (curIdx >= 0 && curIdx < (int)frames->size() && nextIdx >= 0 && nextIdx < (int)frames->size())
|
||||
{
|
||||
float t = static_cast<float>(subFrame) / static_cast<float>(current.second);
|
||||
source->blitInterpolated(x, y, frames->at(curIdx), frames->at(nextIdx), t);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -324,6 +335,11 @@ void StitchedTexture::loadAnimationFrames(const wstring &string)
|
||||
for(auto& it : tokens)
|
||||
{
|
||||
token = trimString(it);
|
||||
if (token == L"interp:1")
|
||||
{
|
||||
m_bInterpolate = true;
|
||||
continue;
|
||||
}
|
||||
int multiPos = token.find_first_of('*');
|
||||
if (multiPos > 0)
|
||||
{
|
||||
|
||||
@@ -42,6 +42,7 @@ protected:
|
||||
protected:
|
||||
int frame;
|
||||
int subFrame;
|
||||
bool m_bInterpolate;
|
||||
|
||||
public:
|
||||
static StitchedTexture *create(const wstring &name);
|
||||
|
||||
@@ -367,6 +367,38 @@ void Texture::writeAsPNG(const wstring &filename)
|
||||
#endif
|
||||
}
|
||||
|
||||
void Texture::blitInterpolated(int x, int y, Texture *srcA, Texture *srcB, float t)
|
||||
{
|
||||
ByteBuffer *bufA = srcA->getData(0);
|
||||
ByteBuffer *bufB = srcB->getData(0);
|
||||
if (!bufA || !bufB) return;
|
||||
|
||||
bufA->position(0);
|
||||
bufB->position(0);
|
||||
|
||||
int sw = srcA->getWidth();
|
||||
int sh = srcA->getHeight();
|
||||
|
||||
for (int srcY = 0; srcY < sh; srcY++)
|
||||
{
|
||||
int dstY = y + srcY;
|
||||
for (int srcX = 0; srcX < sw; srcX++)
|
||||
{
|
||||
int srcPos = (srcY * sw + srcX) * 4;
|
||||
int dstPos = (dstY * width + (x + srcX)) * 4;
|
||||
for (int c = 0; c < 4; c++)
|
||||
{
|
||||
int a = bufA->get(srcPos + c) & 0xFF;
|
||||
int b = bufB->get(srcPos + c) & 0xFF;
|
||||
data[0]->put(dstPos + c, (BYTE)(a + (int)((b - a) * t)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (immediateUpdate) updateOnGPU();
|
||||
else updated = false;
|
||||
}
|
||||
|
||||
void Texture::blit(int x, int y, Texture *source)
|
||||
{
|
||||
blit(x, y, source, false);
|
||||
|
||||
@@ -82,6 +82,7 @@ public:
|
||||
void writeAsPNG(const wstring &filename);
|
||||
void blit(int x, int y, Texture *source);
|
||||
void blit(int x, int y, Texture *source, bool rotated);
|
||||
void blitInterpolated(int x, int y, Texture *srcA, Texture *srcB, float t);
|
||||
void transferFromBuffer(intArray buffer);
|
||||
void transferFromImage(BufferedImage *image);
|
||||
int getManagerId();
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "LevelRenderer.h"
|
||||
#include "Options.h"
|
||||
#include "../Minecraft.World/TallGrass2.h"
|
||||
#include "../Minecraft.World/FlowerPotTileEntity.h"
|
||||
|
||||
bool TileRenderer::fancy = true;
|
||||
|
||||
@@ -932,9 +933,6 @@ bool TileRenderer::tesselateFlowerPotInWorld(FlowerPotTile *tt, int x, int y, in
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case FlowerPotTile::TYPE_FLOWER_RED:
|
||||
plant = Tile::rose;
|
||||
break;
|
||||
case FlowerPotTile::TYPE_FLOWER_YELLOW:
|
||||
plant = Tile::flower;
|
||||
break;
|
||||
@@ -954,7 +952,32 @@ bool TileRenderer::tesselateFlowerPotInWorld(FlowerPotTile *tt, int x, int y, in
|
||||
}
|
||||
else
|
||||
{
|
||||
if (type == FlowerPotTile::TYPE_CACTUS)
|
||||
if (type == FlowerPotTile::TYPE_FLOWER_RED)
|
||||
{
|
||||
int aux = 0;
|
||||
shared_ptr<TileEntity> te = level->getTileEntity(x, y, z);
|
||||
shared_ptr<FlowerPotTileEntity> fpte = te ? std::dynamic_pointer_cast<FlowerPotTileEntity>(te) : nullptr;
|
||||
if (fpte && fpte->hasFlower())
|
||||
aux = fpte->getFlowerAuxValue();
|
||||
tesselateCrossTexture(Tile::rose, aux, x, y, z, 0.75f);
|
||||
}
|
||||
else if (type == FlowerPotTile::TYPE_FLOWER_BLUE_ORCHID)
|
||||
{
|
||||
tesselateCrossTexture(Tile::rose, Rose::BLUE_ORCHID, x, y, z, 0.75f);
|
||||
}
|
||||
else if (type == FlowerPotTile::TYPE_FLOWER_ALLIUM)
|
||||
{
|
||||
tesselateCrossTexture(Tile::rose, Rose::ALLIUM, x, y, z, 0.75f);
|
||||
}
|
||||
else if (type == FlowerPotTile::TYPE_FLOWER_AZURE_BLUET)
|
||||
{
|
||||
tesselateCrossTexture(Tile::rose, Rose::AZURE_BLUET, x, y, z, 0.75f);
|
||||
}
|
||||
else if (type == FlowerPotTile::TYPE_FLOWER_OXEYE_DAISY)
|
||||
{
|
||||
tesselateCrossTexture(Tile::rose, Rose::OXEYE_DAISY, x, y, z, 0.75f);
|
||||
}
|
||||
else if (type == FlowerPotTile::TYPE_CACTUS)
|
||||
{
|
||||
|
||||
// Force drawing of all faces else the cactus misses faces
|
||||
|
||||
@@ -1547,6 +1547,8 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
|
||||
UNREFERENCED_PARAMETER(hPrevInstance);
|
||||
UNREFERENCED_PARAMETER(lpCmdLine);
|
||||
|
||||
Logger::init();
|
||||
|
||||
// 4J-Win64: set CWD to exe dir so asset paths resolve correctly
|
||||
{
|
||||
char szExeDir[MAX_PATH] = {};
|
||||
@@ -1718,6 +1720,7 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
|
||||
if( FAILED( InitDevice() ) )
|
||||
{
|
||||
CleanupDevice();
|
||||
Logger::shutdown();
|
||||
return 0;
|
||||
}
|
||||
// Restore fullscreen state from previous session. Route through the
|
||||
@@ -1747,6 +1750,7 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
|
||||
}
|
||||
}
|
||||
|
||||
Logger::shutdown();
|
||||
return (int) msg.wParam;
|
||||
#endif
|
||||
|
||||
@@ -1787,6 +1791,7 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
|
||||
if (pMinecraft == nullptr)
|
||||
{
|
||||
CleanupDevice();
|
||||
Logger::shutdown();
|
||||
return 1;
|
||||
}
|
||||
g_bResizeReady = true;
|
||||
|
||||
@@ -451,6 +451,8 @@ set(_MINECRAFT_CLIENT_COMMON_NET_MINECRAFT_CLIENT
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/KeyMapping.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/Lighting.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/Lighting.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/Logger.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/Logger.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/MemoryTracker.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/MemoryTracker.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/Minecraft.cpp"
|
||||
|
||||
@@ -351,6 +351,16 @@ typedef XUID GameSessionUID;
|
||||
|
||||
|
||||
|
||||
#include "Logger.h"
|
||||
#ifndef _FINAL_BUILD
|
||||
#undef OutputDebugString
|
||||
#undef OutputDebugStringA
|
||||
#undef OutputDebugStringW
|
||||
#define OutputDebugStringA(s) Logger::interceptA(s)
|
||||
#define OutputDebugStringW(s) Logger::interceptW(s)
|
||||
#define OutputDebugString(s) Logger::interceptW(s)
|
||||
#endif
|
||||
|
||||
#ifdef _FINAL_BUILD
|
||||
#define printf BREAKTHECOMPILE
|
||||
#define wprintf BREAKTHECOMPILE
|
||||
|
||||
@@ -9,6 +9,7 @@ Abilities::Abilities()
|
||||
mayfly = false;
|
||||
instabuild = false;
|
||||
mayBuild = true;
|
||||
spectatorMode = false;
|
||||
flyingSpeed = 0.05f;
|
||||
walkingSpeed = 0.1f;
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ public:
|
||||
bool mayfly;
|
||||
bool instabuild;
|
||||
bool mayBuild;
|
||||
bool spectatorMode;
|
||||
|
||||
private:
|
||||
float flyingSpeed;
|
||||
|
||||
@@ -49,10 +49,7 @@ void Animal::aiStep()
|
||||
setInLoveValue(getInLoveValue()-1);
|
||||
if (getInLoveValue() % 10 == 0)
|
||||
{
|
||||
double xa = random->nextGaussian() * 0.02;
|
||||
double ya = random->nextGaussian() * 0.02;
|
||||
double za = random->nextGaussian() * 0.02;
|
||||
level->addParticle(eParticleType_heart, x + random->nextFloat() * bbWidth * 2 - bbWidth, y + .5f + random->nextFloat() * bbHeight, z + random->nextFloat() * bbWidth * 2 - bbWidth, xa, ya, za);
|
||||
level->broadcastEntityEvent(shared_from_this(), EntityEvent::IN_LOVE_HEARTS);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -106,7 +103,7 @@ void Animal::checkHurtTarget(shared_ptr<Entity> target, float d)
|
||||
loveTime++;
|
||||
if (loveTime % 4 == 0)
|
||||
{
|
||||
level->addParticle(eParticleType_heart, x + random->nextFloat() * bbWidth * 2 - bbWidth, y + .5f + random->nextFloat() * bbHeight, z + random->nextFloat() * bbWidth * 2 - bbWidth, 0, 0, 0);
|
||||
level->broadcastEntityEvent(shared_from_this(), EntityEvent::IN_LOVE_HEARTS);
|
||||
}
|
||||
|
||||
if (loveTime == 20 * 3) breedWith(a);
|
||||
@@ -145,13 +142,7 @@ void Animal::breedWith(shared_ptr<Animal> target)
|
||||
offspring->setAge(-20 * 60 * 20);
|
||||
offspring->moveTo(x, y, z, yRot, xRot);
|
||||
offspring->setDespawnProtected();
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
double xa = random->nextGaussian() * 0.02;
|
||||
double ya = random->nextGaussian() * 0.02;
|
||||
double za = random->nextGaussian() * 0.02;
|
||||
level->addParticle(eParticleType_heart, x + random->nextFloat() * bbWidth * 2 - bbWidth, y + .5f + random->nextFloat() * bbHeight, z + random->nextFloat() * bbWidth * 2 - bbWidth, xa, ya, za);
|
||||
}
|
||||
level->broadcastEntityEvent(shared_from_this(), EntityEvent::IN_LOVE_HEARTS);
|
||||
level->addEntity(offspring);
|
||||
|
||||
level->addEntity(std::make_shared<ExperienceOrb>(level, x, y, z, random->nextInt(4) + 1));
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "ExperienceOrb.h"
|
||||
|
||||
#include "GenericStats.h"
|
||||
#include "EntityEvent.h"
|
||||
|
||||
BreedGoal::BreedGoal(Animal *animal, double speedModifier)
|
||||
{
|
||||
@@ -108,15 +109,8 @@ void BreedGoal::breed()
|
||||
offspring->setDespawnProtected();
|
||||
level->addEntity(offspring);
|
||||
|
||||
Random *random = animal->getRandom();
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
double xa = random->nextGaussian() * 0.02;
|
||||
double ya = random->nextGaussian() * 0.02;
|
||||
double za = random->nextGaussian() * 0.02;
|
||||
level->addParticle(eParticleType_heart, animal->x + random->nextFloat() * animal->bbWidth * 2 - animal->bbWidth, animal->y + .5f + random->nextFloat() * animal->bbHeight, animal->z + random->nextFloat()
|
||||
* animal->bbWidth * 2 - animal->bbWidth, xa, ya, za);
|
||||
}
|
||||
level->broadcastEntityEvent(animal->shared_from_this(), EntityEvent::IN_LOVE_HEARTS);
|
||||
// 4J-PB - Fix for 106869- Customer Encountered: TU12: Content: Gameplay: Breeding animals does not give any Experience Orbs.
|
||||
Random *random = animal->getRandom();
|
||||
level->addEntity(std::make_shared<ExperienceOrb>(level, animal->x, animal->y, animal->z, random->nextInt(7) + 1));
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ public:
|
||||
e_ChatDeathDragonBreath,
|
||||
e_ChatDeathAnvil,
|
||||
e_ChatDeathFallingBlock,
|
||||
e_ChatDeathFlyIntoWall,
|
||||
e_ChatDeathThorns,
|
||||
|
||||
e_ChatDeathFellAccidentLadder,
|
||||
|
||||
@@ -320,6 +320,7 @@ enum eINSTANCEOF
|
||||
eTYPE_DAYLIGHTDETECTORTILEENTITY = eTYPE_TILEENTITY | 0x10,
|
||||
eTYPE_HOPPERTILEENTITY = eTYPE_TILEENTITY | 0x11,
|
||||
eTYPE_BANNERTILEENTITY = eTYPE_TILEENTITY | 0x12,
|
||||
eTYPE_FLOWERPOTTILEENTITY = eTYPE_TILEENTITY | 0x13,
|
||||
|
||||
eTYPE_DISPENSERTILEENTITY = eTYPE_TILEENTITY | BIT_DISPENSERTILEENTITY,
|
||||
eTYPE_DROPPERTILEENTITY = eTYPE_DISPENSERTILEENTITY | 0x1,
|
||||
@@ -548,6 +549,7 @@ public:
|
||||
classes->push_back( SUBCLASS(eTYPE_DAYLIGHTDETECTORTILEENTITY )->addParent( eTYPE_TILEENTITY ) );
|
||||
classes->push_back( SUBCLASS(eTYPE_HOPPERTILEENTITY )->addParent( eTYPE_TILEENTITY ) );
|
||||
classes->push_back( SUBCLASS(eTYPE_BANNERTILEENTITY )->addParent( eTYPE_TILEENTITY ) );
|
||||
classes->push_back( SUBCLASS(eTYPE_FLOWERPOTTILEENTITY )->addParent( eTYPE_TILEENTITY ) );
|
||||
classes->push_back( SUBCLASS(eTYPE_DISPENSERTILEENTITY )->addParent( eTYPE_TILEENTITY ) );
|
||||
classes->push_back( SUBCLASS(eTYPE_DROPPERTILEENTITY )->addParent( eTYPE_DISPENSERTILEENTITY ) );
|
||||
|
||||
|
||||
@@ -569,6 +569,15 @@ void CustomLevelSource::postProcess(ChunkSource *parent, int xt, int zt)
|
||||
}
|
||||
PIXEndNamedEvent();
|
||||
|
||||
if (true)
|
||||
{
|
||||
int fx = xo + pprandom->nextInt(16) + 8;
|
||||
int fy = 40 + pprandom->nextInt(10);
|
||||
int fz = zo + pprandom->nextInt(16) + 8;
|
||||
FossilFeature fossil;
|
||||
fossil.place(level, pprandom, fx, fy, fz);
|
||||
}
|
||||
|
||||
PIXBeginNamedEvent(0,"Biome decorate");
|
||||
biome->decorate(level, pprandom, xo, zo);
|
||||
PIXEndNamedEvent();
|
||||
|
||||
@@ -22,6 +22,7 @@ DamageSource *DamageSource::dragonbreath = (new DamageSource(ChatPacket::e_ChatD
|
||||
DamageSource *DamageSource::wither = (new DamageSource(ChatPacket::e_ChatDeathWither))->bypassArmor();
|
||||
DamageSource *DamageSource::anvil = (new DamageSource(ChatPacket::e_ChatDeathAnvil));
|
||||
DamageSource *DamageSource::fallingBlock = (new DamageSource(ChatPacket::e_ChatDeathFallingBlock));
|
||||
DamageSource *DamageSource::flyIntoWall = new DamageSource(ChatPacket::e_ChatDeathFlyIntoWall);
|
||||
|
||||
DamageSource *DamageSource::mobAttack(shared_ptr<LivingEntity> mob)
|
||||
{
|
||||
|
||||
@@ -29,6 +29,7 @@ public:
|
||||
static DamageSource *wither;
|
||||
static DamageSource *anvil;
|
||||
static DamageSource *fallingBlock;
|
||||
static DamageSource *flyIntoWall;
|
||||
|
||||
static DamageSource *mobAttack(shared_ptr<LivingEntity> mob);
|
||||
static DamageSource *playerAttack(shared_ptr<Player> player);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "stdafx.h"
|
||||
#include "net.minecraft.world.entity.h"
|
||||
#include "net.minecraft.world.entity.player.h"
|
||||
#include "net.minecraft.world.entity.item.h"
|
||||
#include "net.minecraft.world.item.enchantment.h"
|
||||
#include "net.minecraft.world.level.h"
|
||||
@@ -146,9 +147,18 @@ void Explosion::explode()
|
||||
if(canDamage) e->hurt(DamageSource::explosion(this), static_cast<int>((pow * pow + pow) / 2 * 8 * r + 1));
|
||||
|
||||
double kbPower = ProtectionEnchantment::getExplosionKnockbackAfterDampener(e, pow);
|
||||
e->xd += xa *kbPower;
|
||||
e->yd += ya *kbPower;
|
||||
e->zd += za *kbPower;
|
||||
bool isCreativeFlying = false;
|
||||
if (e->instanceof(eTYPE_PLAYER))
|
||||
{
|
||||
shared_ptr<Player> p = dynamic_pointer_cast<Player>(e);
|
||||
if (p && p->abilities.flying) isCreativeFlying = true;
|
||||
}
|
||||
if (!isCreativeFlying)
|
||||
{
|
||||
e->xd += xa * kbPower;
|
||||
e->yd += ya * kbPower;
|
||||
e->zd += za * kbPower;
|
||||
}
|
||||
|
||||
|
||||
if (e->instanceof(eTYPE_PLAYER))
|
||||
|
||||
@@ -19,6 +19,25 @@ FireworksItem::FireworksItem(int id) : Item(id)
|
||||
{
|
||||
}
|
||||
|
||||
shared_ptr<ItemInstance> FireworksItem::use(shared_ptr<ItemInstance> instance, Level *level, shared_ptr<Player> player)
|
||||
{
|
||||
if (player->isElytraFlying() && player->m_elytraRocketCooldown == 0)
|
||||
{
|
||||
player->m_elytraRocketCooldown = 20;
|
||||
player->startFireworkBoost(instance);
|
||||
player->playSound(eSoundType_FIREWORKS_LAUNCH, 3.0f, 1.0f);
|
||||
if (!level->isClientSide)
|
||||
{
|
||||
shared_ptr<FireworksRocketEntity> rocket(new FireworksRocketEntity(level, player->x, player->y, player->z, instance));
|
||||
level->addEntity(rocket);
|
||||
if (!player->abilities.instabuild)
|
||||
instance->count--;
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
bool FireworksItem::useOn(shared_ptr<ItemInstance> instance, shared_ptr<Player> player, Level *level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, bool bTestUseOnOnly)
|
||||
{
|
||||
// 4J-JEV: Fix for xb1 #173493 - CU7: Content: UI: Missing tooltip for Firework Rocket.
|
||||
|
||||
@@ -27,5 +27,6 @@ public:
|
||||
FireworksItem(int id);
|
||||
|
||||
bool useOn(shared_ptr<ItemInstance> instance, shared_ptr<Player> player, Level *level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, bool bTestUseOnOnly=false);
|
||||
virtual shared_ptr<ItemInstance> use(shared_ptr<ItemInstance> instance, Level *level, shared_ptr<Player> player);
|
||||
void appendHoverText(shared_ptr<ItemInstance> itemInstance, shared_ptr<Player> player, vector<HtmlString> *lines, bool advanced);
|
||||
};
|
||||
@@ -4,14 +4,20 @@
|
||||
#include "net.minecraft.world.level.h"
|
||||
#include "net.minecraft.world.level.tile.h"
|
||||
#include "FlowerPotTile.h"
|
||||
#include "FlowerPotTileEntity.h"
|
||||
|
||||
FlowerPotTile::FlowerPotTile(int id) : Tile(id, Material::decoration, isSolidRender() )
|
||||
FlowerPotTile::FlowerPotTile(int id) : BaseEntityTile(id, Material::decoration, isSolidRender())
|
||||
{
|
||||
setLightBlock(0);
|
||||
updateDefaultShape();
|
||||
sendTileData();
|
||||
}
|
||||
|
||||
shared_ptr<TileEntity> FlowerPotTile::newTileEntity(Level *level)
|
||||
{
|
||||
return std::make_shared<FlowerPotTileEntity>();
|
||||
}
|
||||
|
||||
void FlowerPotTile::createBlockStateDefinition()
|
||||
{
|
||||
if (!m_blockStateDefinition)
|
||||
@@ -71,6 +77,15 @@ bool FlowerPotTile::use(Level *level, int x, int y, int z, shared_ptr<Player> pl
|
||||
{
|
||||
level->setData(x, y, z, type, Tile::UPDATE_CLIENTS);
|
||||
|
||||
shared_ptr<TileEntity> teBase = level->getTileEntity(x, y, z);
|
||||
shared_ptr<FlowerPotTileEntity> te = teBase ? std::dynamic_pointer_cast<FlowerPotTileEntity>(teBase) : nullptr;
|
||||
if (te == nullptr)
|
||||
{
|
||||
te = std::make_shared<FlowerPotTileEntity>();
|
||||
level->setTileEntity(x, y, z, te);
|
||||
}
|
||||
te->setFlowerItem(item->getItem()->id, item->getAuxValue());
|
||||
|
||||
if (!player->abilities.instabuild)
|
||||
{
|
||||
if (--item->count <= 0)
|
||||
@@ -87,30 +102,24 @@ bool FlowerPotTile::use(Level *level, int x, int y, int z, shared_ptr<Player> pl
|
||||
|
||||
int FlowerPotTile::cloneTileId(Level *level, int x, int y, int z)
|
||||
{
|
||||
shared_ptr<ItemInstance> item = getItemFromType(level->getData(x, y, z));
|
||||
shared_ptr<TileEntity> te = level->getTileEntity(x, y, z);
|
||||
shared_ptr<FlowerPotTileEntity> fpte = te ? std::dynamic_pointer_cast<FlowerPotTileEntity>(te) : nullptr;
|
||||
if (fpte && fpte->hasFlower())
|
||||
return fpte->getFlowerItemId();
|
||||
|
||||
if (item == nullptr)
|
||||
{
|
||||
return Item::flower_pot_Id;
|
||||
}
|
||||
else
|
||||
{
|
||||
return item->id;
|
||||
}
|
||||
shared_ptr<ItemInstance> item = getItemFromType(level->getData(x, y, z));
|
||||
return item ? item->id : Item::flower_pot_Id;
|
||||
}
|
||||
|
||||
int FlowerPotTile::cloneTileData(Level *level, int x, int y, int z)
|
||||
{
|
||||
shared_ptr<ItemInstance> item = getItemFromType(level->getData(x, y, z));
|
||||
shared_ptr<TileEntity> te = level->getTileEntity(x, y, z);
|
||||
shared_ptr<FlowerPotTileEntity> fpte = te ? std::dynamic_pointer_cast<FlowerPotTileEntity>(te) : nullptr;
|
||||
if (fpte && fpte->hasFlower())
|
||||
return fpte->getFlowerAuxValue();
|
||||
|
||||
if (item == nullptr)
|
||||
{
|
||||
return Item::flower_pot_Id;
|
||||
}
|
||||
else
|
||||
{
|
||||
return item->getAuxValue();
|
||||
}
|
||||
shared_ptr<ItemInstance> item = getItemFromType(level->getData(x, y, z));
|
||||
return item ? item->getAuxValue() : 0;
|
||||
}
|
||||
|
||||
bool FlowerPotTile::useOwnCloneData()
|
||||
@@ -133,15 +142,26 @@ void FlowerPotTile::neighborChanged(Level *level, int x, int y, int z, int type)
|
||||
}
|
||||
}
|
||||
|
||||
void FlowerPotTile::onRemove(Level *level, int x, int y, int z, int id, int data)
|
||||
{
|
||||
if (data > 0)
|
||||
{
|
||||
shared_ptr<TileEntity> te = level->getTileEntity(x, y, z);
|
||||
shared_ptr<FlowerPotTileEntity> fpte = te ? std::dynamic_pointer_cast<FlowerPotTileEntity>(te) : nullptr;
|
||||
shared_ptr<ItemInstance> item;
|
||||
if (fpte && fpte->hasFlower())
|
||||
item = std::make_shared<ItemInstance>(fpte->getFlowerItemId(), 1, fpte->getFlowerAuxValue());
|
||||
else
|
||||
item = getItemFromType(data);
|
||||
if (item != nullptr)
|
||||
popResource(level, x, y, z, item);
|
||||
}
|
||||
BaseEntityTile::onRemove(level, x, y, z, id, data);
|
||||
}
|
||||
|
||||
void FlowerPotTile::spawnResources(Level *level, int x, int y, int z, int data, float odds, int playerBonusLevel)
|
||||
{
|
||||
Tile::spawnResources(level, x, y, z, data, odds, playerBonusLevel);
|
||||
|
||||
if (data > 0)
|
||||
{
|
||||
shared_ptr<ItemInstance> item = getItemFromType(data);
|
||||
if (item != nullptr) popResource(level, x, y, z, item);
|
||||
}
|
||||
}
|
||||
|
||||
int FlowerPotTile::getResource(int data, Random *random, int playerBonusLevel)
|
||||
@@ -154,7 +174,15 @@ shared_ptr<ItemInstance> FlowerPotTile::getItemFromType(int type)
|
||||
switch (type)
|
||||
{
|
||||
case TYPE_FLOWER_RED:
|
||||
return std::make_shared<ItemInstance>(Tile::rose);
|
||||
return std::make_shared<ItemInstance>(Tile::rose, 1, 0);
|
||||
case TYPE_FLOWER_BLUE_ORCHID:
|
||||
return std::make_shared<ItemInstance>(Tile::rose, 1, Rose::BLUE_ORCHID);
|
||||
case TYPE_FLOWER_ALLIUM:
|
||||
return std::make_shared<ItemInstance>(Tile::rose, 1, Rose::ALLIUM);
|
||||
case TYPE_FLOWER_AZURE_BLUET:
|
||||
return std::make_shared<ItemInstance>(Tile::rose, 1, Rose::AZURE_BLUET);
|
||||
case TYPE_FLOWER_OXEYE_DAISY:
|
||||
return std::make_shared<ItemInstance>(Tile::rose, 1, Rose::OXEYE_DAISY);
|
||||
case TYPE_FLOWER_YELLOW:
|
||||
return std::make_shared<ItemInstance>(Tile::flower);
|
||||
case TYPE_CACTUS:
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "Tile.h"
|
||||
#include "BaseEntityTile.h"
|
||||
|
||||
class FlowerPotTile : public Tile
|
||||
class FlowerPotTile : public BaseEntityTile
|
||||
{
|
||||
public:
|
||||
static const int TYPE_FLOWER_RED = 1;
|
||||
@@ -16,8 +16,13 @@ public:
|
||||
static const int TYPE_CACTUS = 9;
|
||||
static const int TYPE_DEAD_BUSH = 10;
|
||||
static const int TYPE_FERN = 11;
|
||||
static const int TYPE_FLOWER_BLUE_ORCHID = 12;
|
||||
static const int TYPE_FLOWER_ALLIUM = 13;
|
||||
static const int TYPE_FLOWER_AZURE_BLUET = 14;
|
||||
static const int TYPE_FLOWER_OXEYE_DAISY = 15;
|
||||
|
||||
FlowerPotTile(int id);
|
||||
shared_ptr<TileEntity> newTileEntity(Level *level);
|
||||
virtual void createBlockStateDefinition() override;
|
||||
virtual int defaultBlockState() override;
|
||||
virtual int convertBlockStateToLegacyData(BlockState *state) override;
|
||||
@@ -34,6 +39,7 @@ public:
|
||||
bool useOwnCloneData();
|
||||
bool mayPlace(Level *level, int x, int y, int z);
|
||||
void neighborChanged(Level *level, int x, int y, int z, int type);
|
||||
void onRemove(Level *level, int x, int y, int z, int id, int data);
|
||||
using Tile::spawnResources;
|
||||
void spawnResources(Level *level, int x, int y, int z, int data, float odds, int playerBonusLevel);
|
||||
int getResource(int data, Random *random, int playerBonusLevel);
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
#include "stdafx.h"
|
||||
#include "com.mojang.nbt.h"
|
||||
#include "net.minecraft.network.packet.h"
|
||||
#include "FlowerPotTileEntity.h"
|
||||
#include "TileEntityDataPacket.h"
|
||||
|
||||
FlowerPotTileEntity::FlowerPotTileEntity() : flowerItemId(-1), flowerAuxValue(0)
|
||||
{
|
||||
}
|
||||
|
||||
void FlowerPotTileEntity::setFlowerItem(int itemId, int auxValue)
|
||||
{
|
||||
flowerItemId = itemId;
|
||||
flowerAuxValue = auxValue;
|
||||
}
|
||||
|
||||
int FlowerPotTileEntity::getFlowerItemId() const
|
||||
{
|
||||
return flowerItemId;
|
||||
}
|
||||
|
||||
int FlowerPotTileEntity::getFlowerAuxValue() const
|
||||
{
|
||||
return flowerAuxValue;
|
||||
}
|
||||
|
||||
bool FlowerPotTileEntity::hasFlower() const
|
||||
{
|
||||
return flowerItemId >= 0;
|
||||
}
|
||||
|
||||
void FlowerPotTileEntity::save(CompoundTag *tag)
|
||||
{
|
||||
TileEntity::save(tag);
|
||||
tag->putInt(L"Item", flowerItemId);
|
||||
tag->putInt(L"Data", flowerAuxValue);
|
||||
}
|
||||
|
||||
void FlowerPotTileEntity::load(CompoundTag *tag)
|
||||
{
|
||||
TileEntity::load(tag);
|
||||
flowerItemId = tag->getInt(L"Item");
|
||||
flowerAuxValue = tag->getInt(L"Data");
|
||||
}
|
||||
|
||||
shared_ptr<Packet> FlowerPotTileEntity::getUpdatePacket()
|
||||
{
|
||||
CompoundTag *tag = new CompoundTag();
|
||||
save(tag);
|
||||
return std::make_shared<TileEntityDataPacket>(x, y, z, TileEntityDataPacket::TYPE_FLOWER_POT, tag);
|
||||
}
|
||||
|
||||
shared_ptr<TileEntity> FlowerPotTileEntity::clone()
|
||||
{
|
||||
shared_ptr<FlowerPotTileEntity> e = std::make_shared<FlowerPotTileEntity>();
|
||||
TileEntity::clone(e);
|
||||
e->flowerItemId = flowerItemId;
|
||||
e->flowerAuxValue = flowerAuxValue;
|
||||
return e;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
#include "TileEntity.h"
|
||||
|
||||
class FlowerPotTileEntity : public TileEntity
|
||||
{
|
||||
public:
|
||||
eINSTANCEOF GetType() { return eTYPE_FLOWERPOTTILEENTITY; }
|
||||
static TileEntity *create() { return new FlowerPotTileEntity(); }
|
||||
|
||||
private:
|
||||
int flowerItemId;
|
||||
int flowerAuxValue;
|
||||
|
||||
public:
|
||||
FlowerPotTileEntity();
|
||||
void setFlowerItem(int itemId, int auxValue);
|
||||
int getFlowerItemId() const;
|
||||
int getFlowerAuxValue() const;
|
||||
bool hasFlower() const;
|
||||
|
||||
void save(CompoundTag *tag);
|
||||
void load(CompoundTag *tag);
|
||||
shared_ptr<Packet> getUpdatePacket();
|
||||
virtual shared_ptr<TileEntity> clone();
|
||||
};
|
||||
@@ -25,7 +25,7 @@ const float FoodConstants::FOOD_SATURATION_MAX = 1.0f;
|
||||
const float FoodConstants::FOOD_SATURATION_SUPERNATURAL = 1.2f;
|
||||
|
||||
// some exhaustion guidelines
|
||||
const float FoodConstants::EXHAUSTION_HEAL = 3.0f;
|
||||
const float FoodConstants::EXHAUSTION_HEAL = 4.0f;
|
||||
const float FoodConstants::EXHAUSTION_JUMP = .2f;
|
||||
const float FoodConstants::EXHAUSTION_SPRINT_JUMP = FoodConstants::EXHAUSTION_JUMP * 4;
|
||||
const float FoodConstants::EXHAUSTION_MINE = .025f;
|
||||
|
||||
@@ -68,7 +68,8 @@ void FoodData::tick(shared_ptr<Player> player)
|
||||
else if (player->level->getGameRules()->getBoolean(GameRules::RULE_NATURAL_REGENERATION) && foodLevel >= FoodConstants::HEAL_LEVEL && player->isHurt())
|
||||
{
|
||||
tickTimer++;
|
||||
if (tickTimer >= FoodConstants::HEALTH_TICK_COUNT)
|
||||
int threshold = (saturationLevel > 0.0f) ? 10 : FoodConstants::HEALTH_TICK_COUNT;
|
||||
if (tickTimer >= threshold)
|
||||
{
|
||||
player->heal(1);
|
||||
addExhaustion(FoodConstants::EXHAUSTION_HEAL);
|
||||
|
||||
@@ -0,0 +1,235 @@
|
||||
#include "stdafx.h"
|
||||
#include "net.minecraft.world.level.h"
|
||||
#include "net.minecraft.world.level.tile.h"
|
||||
#include "RotatedPillarTile.h"
|
||||
#include "FossilFeature.h"
|
||||
|
||||
struct FossilBlock
|
||||
{
|
||||
signed char x, y, z;
|
||||
signed char data;
|
||||
};
|
||||
|
||||
struct FossilStructure
|
||||
{
|
||||
int width, height, length;
|
||||
const FossilBlock *blocks;
|
||||
int blockCount;
|
||||
};
|
||||
|
||||
static const int AXIS_Y = RotatedPillarTile::FACING_Y;
|
||||
static const int AXIS_X = RotatedPillarTile::FACING_X;
|
||||
static const int AXIS_Z = RotatedPillarTile::FACING_Z;
|
||||
static const int COAL = -1;
|
||||
|
||||
static const FossilBlock skull01[] = {
|
||||
{1,1,0,AXIS_Y},{4,1,0,AXIS_Y},{1,2,0,AXIS_Y},{2,2,0,AXIS_Y},{3,2,0,AXIS_Y},{4,2,0,AXIS_Y},
|
||||
{2,3,0,AXIS_X},{3,3,0,AXIS_X},
|
||||
{1,0,1,AXIS_X},{2,0,1,AXIS_X},{3,0,1,AXIS_X},{4,0,1,AXIS_X},
|
||||
{0,1,1,AXIS_Y},{5,1,1,AXIS_Y},{0,2,1,AXIS_Y},{5,2,1,AXIS_Y},{0,3,1,AXIS_Y},{5,3,1,AXIS_Y},
|
||||
{1,4,1,AXIS_X},{2,4,1,AXIS_X},{3,4,1,AXIS_X},{4,4,1,AXIS_X},
|
||||
{1,0,2,AXIS_X},{2,0,2,AXIS_X},{3,0,2,AXIS_X},{4,0,2,AXIS_X},
|
||||
{0,1,2,AXIS_Z},{5,1,2,AXIS_Z},{0,2,2,AXIS_Z},{5,2,2,AXIS_Z},{0,3,2,AXIS_Z},{5,3,2,AXIS_Z},
|
||||
{1,4,2,AXIS_X},{2,4,2,AXIS_X},{3,4,2,AXIS_X},{4,4,2,AXIS_X},
|
||||
{1,0,3,AXIS_X},{2,0,3,AXIS_X},{3,0,3,AXIS_X},{4,0,3,AXIS_X},
|
||||
{0,1,3,AXIS_Z},{5,1,3,AXIS_Z},{0,2,3,AXIS_Z},{5,2,3,AXIS_Z},{0,3,3,AXIS_Z},{5,3,3,AXIS_Z},
|
||||
{1,4,3,AXIS_X},{2,4,3,AXIS_X},{3,4,3,AXIS_X},{4,4,3,AXIS_X},
|
||||
{1,0,4,AXIS_X},{4,0,4,AXIS_X},
|
||||
{0,1,4,AXIS_Z},{5,1,4,AXIS_Z},{0,2,4,AXIS_Z},{5,2,4,AXIS_Z},{0,3,4,AXIS_Z},{5,3,4,AXIS_Z},
|
||||
{1,4,4,AXIS_X},{2,4,4,AXIS_X},{3,4,4,AXIS_X},{4,4,4,AXIS_X},
|
||||
{1,0,5,AXIS_X},{4,0,5,AXIS_X},
|
||||
{0,1,5,AXIS_Y},{5,1,5,AXIS_Y},{0,2,5,AXIS_Y},{5,2,5,AXIS_Y},{0,3,5,AXIS_Y},{5,3,5,AXIS_Y},
|
||||
{1,4,5,AXIS_X},{2,4,5,AXIS_X},{3,4,5,AXIS_X},{4,4,5,AXIS_X},
|
||||
{1,1,6,AXIS_Y},{2,1,6,AXIS_X},{3,1,6,AXIS_X},{4,1,6,AXIS_Y},
|
||||
{1,2,6,AXIS_Y},{2,2,6,AXIS_X},{3,2,6,AXIS_X},{4,2,6,AXIS_Y},
|
||||
{1,3,6,AXIS_Y},{2,3,6,AXIS_X},{3,3,6,AXIS_X},{4,3,6,AXIS_Y},
|
||||
};
|
||||
|
||||
static const FossilBlock skull02[] = {
|
||||
{1,1,0,AXIS_Y},{5,1,0,AXIS_Y},{1,2,0,AXIS_Y},{2,2,0,AXIS_X},{3,2,0,AXIS_X},{4,2,0,AXIS_X},{5,2,0,AXIS_Y},
|
||||
{1,3,0,AXIS_Y},{3,3,0,AXIS_Y},{5,3,0,AXIS_Y},{2,4,0,AXIS_X},{4,4,0,AXIS_X},
|
||||
{1,0,1,AXIS_X},{2,0,1,AXIS_X},{3,0,1,AXIS_X},{4,0,1,AXIS_X},{5,0,1,AXIS_X},
|
||||
{0,1,1,AXIS_Y},{6,1,1,AXIS_Y},{0,2,1,AXIS_Y},{6,2,1,AXIS_Y},{0,3,1,AXIS_Y},{6,3,1,AXIS_Y},
|
||||
{1,4,1,AXIS_X},{2,4,1,AXIS_X},{3,4,1,AXIS_X},{4,4,1,AXIS_X},{5,4,1,AXIS_X},
|
||||
{1,0,2,AXIS_X},{2,0,2,AXIS_X},{3,0,2,AXIS_X},{4,0,2,AXIS_X},{5,0,2,AXIS_X},
|
||||
{0,1,2,AXIS_Z},{6,1,2,AXIS_Z},{0,2,2,AXIS_Z},{6,2,2,AXIS_Z},{0,3,2,AXIS_Z},{6,3,2,AXIS_Z},
|
||||
{1,4,2,AXIS_X},{2,4,2,AXIS_X},{3,4,2,AXIS_X},{4,4,2,AXIS_X},{5,4,2,AXIS_X},
|
||||
{1,0,3,AXIS_X},{2,0,3,AXIS_X},{3,0,3,AXIS_X},{4,0,3,AXIS_X},{5,0,3,AXIS_X},
|
||||
{0,1,3,AXIS_Y},{6,1,3,AXIS_Y},{0,2,3,AXIS_Y},{6,2,3,AXIS_Y},{0,3,3,AXIS_Y},{6,3,3,AXIS_Y},
|
||||
{1,4,3,AXIS_X},{2,4,3,AXIS_X},{3,4,3,AXIS_X},{4,4,3,AXIS_X},{5,4,3,AXIS_X},
|
||||
{1,1,4,AXIS_Y},{2,1,4,AXIS_X},{3,1,4,AXIS_X},{4,1,4,AXIS_X},{5,1,4,AXIS_Y},
|
||||
{1,2,4,AXIS_Y},{2,2,4,AXIS_X},{3,2,4,AXIS_X},{4,2,4,AXIS_X},{5,2,4,AXIS_Y},
|
||||
{1,3,4,AXIS_Y},{2,3,4,AXIS_X},{3,3,4,AXIS_X},{4,3,4,AXIS_X},{5,3,4,AXIS_Y},
|
||||
};
|
||||
|
||||
static const FossilBlock skull03[] = {
|
||||
{0,0,0,AXIS_Y},{4,0,0,AXIS_Y},
|
||||
{0,1,0,AXIS_Y},{1,1,0,AXIS_X},{2,1,0,AXIS_X},{3,1,0,AXIS_X},{4,1,0,AXIS_Y},
|
||||
{0,2,0,AXIS_Y},{2,2,0,AXIS_Y},{4,2,0,AXIS_Y},
|
||||
{0,3,0,AXIS_X},{1,3,0,AXIS_X},{2,3,0,AXIS_X},{3,3,0,AXIS_X},{4,3,0,AXIS_X},
|
||||
{1,0,1,AXIS_X},{2,0,1,AXIS_X},{3,0,1,AXIS_X},
|
||||
{0,1,1,AXIS_Z},{4,1,1,AXIS_Z},{0,2,1,AXIS_Z},{4,2,1,AXIS_Z},
|
||||
{1,3,1,AXIS_X},{2,3,1,AXIS_X},{3,3,1,AXIS_X},
|
||||
{1,0,2,AXIS_X},{2,0,2,AXIS_X},{3,0,2,AXIS_X},
|
||||
{0,1,2,AXIS_Z},{4,1,2,AXIS_Z},{0,2,2,AXIS_Z},{4,2,2,AXIS_Z},
|
||||
{1,3,2,AXIS_X},{2,3,2,AXIS_X},{3,3,2,AXIS_X},
|
||||
{1,0,3,AXIS_X},{2,0,3,AXIS_X},{3,0,3,AXIS_X},
|
||||
{0,1,3,AXIS_Z},{4,1,3,AXIS_Z},{0,2,3,AXIS_Z},{4,2,3,AXIS_Z},
|
||||
{1,3,3,AXIS_X},{2,3,3,AXIS_X},{3,3,3,AXIS_X},
|
||||
{1,0,4,AXIS_X},{2,0,4,AXIS_X},{3,0,4,AXIS_X},
|
||||
{0,1,4,AXIS_Y},{1,1,4,AXIS_X},{2,1,4,AXIS_X},{3,1,4,AXIS_X},{4,1,4,AXIS_Y},
|
||||
{0,2,4,AXIS_Y},{1,2,4,AXIS_X},{2,2,4,AXIS_X},{3,2,4,AXIS_X},{4,2,4,AXIS_Y},
|
||||
};
|
||||
|
||||
static const FossilBlock skull04[] = {
|
||||
{0,0,0,AXIS_Y},{3,0,0,AXIS_Y},
|
||||
{0,1,0,AXIS_Y},{1,1,0,AXIS_X},{2,1,0,AXIS_X},{3,1,0,AXIS_Y},
|
||||
{0,2,0,AXIS_Y},{3,2,0,AXIS_Y},
|
||||
{0,3,0,AXIS_X},{1,3,0,AXIS_X},{2,3,0,AXIS_X},{3,3,0,AXIS_X},
|
||||
{1,0,1,AXIS_X},{2,0,1,AXIS_X},
|
||||
{0,1,1,AXIS_Y},{3,1,1,AXIS_Y},{0,2,1,AXIS_Y},{3,2,1,AXIS_Y},
|
||||
{1,3,1,AXIS_X},{2,3,1,AXIS_X},
|
||||
{1,0,2,AXIS_X},{2,0,2,AXIS_X},
|
||||
{0,1,2,AXIS_Y},{3,1,2,AXIS_Y},{0,2,2,AXIS_Y},{3,2,2,AXIS_Y},
|
||||
{1,3,2,AXIS_X},{2,3,2,AXIS_X},
|
||||
{1,1,3,AXIS_Y},{2,1,3,AXIS_Y},{1,2,3,AXIS_Y},{2,2,3,AXIS_Y},
|
||||
};
|
||||
|
||||
static const FossilBlock spine01[] = {
|
||||
{1,2,0,AXIS_Z},
|
||||
{0,0,1,AXIS_Y},{2,0,1,AXIS_Y},{0,1,1,AXIS_Y},{2,1,1,AXIS_Y},{1,2,1,AXIS_Z},
|
||||
{1,2,2,AXIS_Z},
|
||||
{0,0,3,AXIS_Y},{2,0,3,AXIS_Y},{0,1,3,AXIS_Y},{2,1,3,AXIS_Y},{1,2,3,AXIS_Z},
|
||||
{1,2,4,AXIS_Z},
|
||||
{0,0,5,AXIS_Y},{2,0,5,AXIS_Y},{0,1,5,AXIS_Y},{2,1,5,AXIS_Y},{1,2,5,AXIS_Z},
|
||||
{1,2,6,AXIS_Z},
|
||||
{0,0,7,AXIS_Y},{2,0,7,AXIS_Y},{0,1,7,AXIS_Y},{2,1,7,AXIS_Y},{1,2,7,AXIS_Z},
|
||||
{1,2,8,AXIS_Z},
|
||||
{0,0,9,AXIS_Y},{2,0,9,AXIS_Y},{0,1,9,AXIS_Y},{2,1,9,AXIS_Y},{1,2,9,AXIS_Z},
|
||||
{1,2,10,AXIS_Z},
|
||||
{0,0,11,AXIS_Y},{2,0,11,AXIS_Y},{0,1,11,AXIS_Y},{2,1,11,AXIS_Y},{1,2,11,AXIS_Z},
|
||||
{1,2,12,AXIS_Z},
|
||||
};
|
||||
|
||||
static const FossilBlock spine02[] = {
|
||||
{2,3,0,AXIS_Z},
|
||||
{1,0,1,AXIS_X},{3,0,1,AXIS_X},{0,1,1,AXIS_Y},{4,1,1,AXIS_Y},{0,2,1,AXIS_Y},{4,2,1,AXIS_Y},
|
||||
{1,3,1,AXIS_X},{2,3,1,AXIS_Z},{3,3,1,AXIS_X},
|
||||
{2,3,2,AXIS_Z},
|
||||
{1,0,3,AXIS_X},{3,0,3,AXIS_X},{0,1,3,AXIS_Y},{4,1,3,AXIS_Y},{0,2,3,AXIS_Y},{4,2,3,AXIS_Y},
|
||||
{1,3,3,AXIS_X},{2,3,3,AXIS_Z},{3,3,3,AXIS_X},
|
||||
{2,3,4,AXIS_Z},
|
||||
{1,0,5,AXIS_X},{3,0,5,AXIS_X},{0,1,5,AXIS_Y},{4,1,5,AXIS_Y},{0,2,5,AXIS_Y},{4,2,5,AXIS_Y},
|
||||
{1,3,5,AXIS_X},{2,3,5,AXIS_Z},{3,3,5,AXIS_X},
|
||||
{2,3,6,AXIS_Z},
|
||||
{1,0,7,AXIS_X},{3,0,7,AXIS_X},{0,1,7,AXIS_Y},{4,1,7,AXIS_Y},{0,2,7,AXIS_Y},{4,2,7,AXIS_Y},
|
||||
{1,3,7,AXIS_X},{2,3,7,AXIS_Z},{3,3,7,AXIS_X},
|
||||
{2,3,8,AXIS_Z},
|
||||
{1,0,9,AXIS_X},{3,0,9,AXIS_X},{0,1,9,AXIS_Y},{4,1,9,AXIS_Y},{0,2,9,AXIS_Y},{4,2,9,AXIS_Y},
|
||||
{1,3,9,AXIS_X},{2,3,9,AXIS_Z},{3,3,9,AXIS_X},
|
||||
{2,3,10,AXIS_Z},
|
||||
{1,0,11,AXIS_X},{3,0,11,AXIS_X},{0,1,11,AXIS_Y},{4,1,11,AXIS_Y},{0,2,11,AXIS_Y},{4,2,11,AXIS_Y},
|
||||
{1,3,11,AXIS_X},{2,3,11,AXIS_Z},{3,3,11,AXIS_X},
|
||||
{2,3,12,AXIS_Z},
|
||||
};
|
||||
|
||||
static const FossilBlock spine03[] = {
|
||||
{3,3,0,AXIS_Z},
|
||||
{0,0,1,AXIS_Y},{1,0,1,AXIS_X},{5,0,1,AXIS_X},{6,0,1,AXIS_Y},
|
||||
{0,1,1,AXIS_Y},{6,1,1,AXIS_Y},{0,2,1,AXIS_Y},{6,2,1,AXIS_Y},
|
||||
{0,3,1,AXIS_X},{1,3,1,AXIS_X},{2,3,1,AXIS_X},{3,3,1,AXIS_Z},{4,3,1,AXIS_X},{5,3,1,AXIS_X},{6,3,1,AXIS_X},
|
||||
{3,3,2,AXIS_Z},
|
||||
{0,0,3,AXIS_Y},{1,0,3,AXIS_X},{5,0,3,AXIS_X},{6,0,3,AXIS_Y},
|
||||
{0,1,3,AXIS_Y},{6,1,3,AXIS_Y},{0,2,3,AXIS_Y},{6,2,3,AXIS_Y},
|
||||
{0,3,3,AXIS_X},{1,3,3,AXIS_X},{2,3,3,AXIS_X},{3,3,3,AXIS_Z},{4,3,3,AXIS_X},{5,3,3,AXIS_X},{6,3,3,AXIS_X},
|
||||
{3,3,4,AXIS_Z},
|
||||
{0,0,5,AXIS_Y},{1,0,5,AXIS_X},{5,0,5,AXIS_X},{6,0,5,AXIS_Y},
|
||||
{0,1,5,AXIS_Y},{6,1,5,AXIS_Y},{0,2,5,AXIS_Y},{6,2,5,AXIS_Y},
|
||||
{0,3,5,AXIS_X},{1,3,5,AXIS_X},{2,3,5,AXIS_X},{3,3,5,AXIS_Z},{4,3,5,AXIS_X},{5,3,5,AXIS_X},{6,3,5,AXIS_X},
|
||||
{3,3,6,AXIS_Z},
|
||||
{0,0,7,AXIS_Y},{1,0,7,AXIS_X},{5,0,7,AXIS_X},{6,0,7,AXIS_Y},
|
||||
{0,1,7,AXIS_Y},{6,1,7,AXIS_Y},{0,2,7,AXIS_Y},{6,2,7,AXIS_Y},
|
||||
{0,3,7,AXIS_X},{1,3,7,AXIS_X},{2,3,7,AXIS_X},{3,3,7,AXIS_Z},{4,3,7,AXIS_X},{5,3,7,AXIS_X},{6,3,7,AXIS_X},
|
||||
{3,3,8,AXIS_Z},
|
||||
{0,0,9,AXIS_Y},{1,0,9,AXIS_X},{5,0,9,AXIS_X},{6,0,9,AXIS_Y},
|
||||
{0,1,9,AXIS_Y},{6,1,9,AXIS_Y},{0,2,9,AXIS_Y},{6,2,9,AXIS_Y},
|
||||
{0,3,9,AXIS_X},{1,3,9,AXIS_X},{2,3,9,AXIS_X},{3,3,9,AXIS_Z},{4,3,9,AXIS_X},{5,3,9,AXIS_X},{6,3,9,AXIS_X},
|
||||
{3,3,10,AXIS_Z},
|
||||
{0,0,11,AXIS_Y},{1,0,11,AXIS_X},{5,0,11,AXIS_X},{6,0,11,AXIS_Y},
|
||||
{0,1,11,AXIS_Y},{6,1,11,AXIS_Y},{0,2,11,AXIS_Y},{6,2,11,AXIS_Y},
|
||||
{0,3,11,AXIS_X},{1,3,11,AXIS_X},{2,3,11,AXIS_X},{3,3,11,AXIS_Z},{4,3,11,AXIS_X},{5,3,11,AXIS_X},{6,3,11,AXIS_X},
|
||||
{3,3,12,AXIS_Z},
|
||||
};
|
||||
|
||||
static const FossilBlock spine04[] = {
|
||||
{4,4,0,AXIS_Z},
|
||||
{1,0,1,AXIS_X},{2,0,1,AXIS_X},{6,0,1,AXIS_X},{7,0,1,AXIS_X},
|
||||
{0,1,1,AXIS_Y},{8,1,1,AXIS_Y},{0,2,1,AXIS_Y},{8,2,1,AXIS_Y},{0,3,1,AXIS_Y},{8,3,1,AXIS_Y},
|
||||
{0,4,1,AXIS_X},{1,4,1,AXIS_X},{2,4,1,AXIS_X},{3,4,1,AXIS_X},{4,4,1,AXIS_Z},{5,4,1,AXIS_X},{6,4,1,AXIS_X},{7,4,1,AXIS_X},{8,4,1,AXIS_X},
|
||||
{4,4,2,AXIS_Z},
|
||||
{1,0,3,AXIS_X},{2,0,3,AXIS_X},{6,0,3,AXIS_X},{7,0,3,AXIS_X},
|
||||
{0,1,3,AXIS_Y},{8,1,3,AXIS_Y},{0,2,3,AXIS_Y},{8,2,3,AXIS_Y},{0,3,3,AXIS_Y},{8,3,3,AXIS_Y},
|
||||
{0,4,3,AXIS_X},{1,4,3,AXIS_X},{2,4,3,AXIS_X},{3,4,3,AXIS_X},{4,4,3,AXIS_Z},{5,4,3,AXIS_X},{6,4,3,AXIS_X},{7,4,3,AXIS_X},{8,4,3,AXIS_X},
|
||||
{4,4,4,AXIS_Z},
|
||||
{1,0,5,AXIS_X},{2,0,5,AXIS_X},{6,0,5,AXIS_X},{7,0,5,AXIS_X},
|
||||
{0,1,5,AXIS_Y},{8,1,5,AXIS_Y},{0,2,5,AXIS_Y},{8,2,5,AXIS_Y},{0,3,5,AXIS_Y},{8,3,5,AXIS_Y},
|
||||
{0,4,5,AXIS_X},{1,4,5,AXIS_X},{2,4,5,AXIS_X},{3,4,5,AXIS_X},{4,4,5,AXIS_Z},{5,4,5,AXIS_X},{6,4,5,AXIS_X},{7,4,5,AXIS_X},{8,4,5,AXIS_X},
|
||||
{4,4,6,AXIS_Z},
|
||||
{1,0,7,AXIS_X},{2,0,7,AXIS_X},{6,0,7,AXIS_X},{7,0,7,AXIS_X},
|
||||
{0,1,7,AXIS_Y},{8,1,7,AXIS_Y},{0,2,7,AXIS_Y},{8,2,7,AXIS_Y},{0,3,7,AXIS_Y},{8,3,7,AXIS_Y},
|
||||
{0,4,7,AXIS_X},{1,4,7,AXIS_X},{2,4,7,AXIS_X},{3,4,7,AXIS_X},{4,4,7,AXIS_Z},{5,4,7,AXIS_X},{6,4,7,AXIS_X},{7,4,7,AXIS_X},{8,4,7,AXIS_X},
|
||||
{4,4,8,AXIS_Z},
|
||||
{1,0,9,AXIS_X},{2,0,9,AXIS_X},{6,0,9,AXIS_X},{7,0,9,AXIS_X},
|
||||
{0,1,9,AXIS_Y},{8,1,9,AXIS_Y},{0,2,9,AXIS_Y},{8,2,9,AXIS_Y},{0,3,9,AXIS_Y},{8,3,9,AXIS_Y},
|
||||
{0,4,9,AXIS_X},{1,4,9,AXIS_X},{2,4,9,AXIS_X},{3,4,9,AXIS_X},{4,4,9,AXIS_Z},{5,4,9,AXIS_X},{6,4,9,AXIS_X},{7,4,9,AXIS_X},{8,4,9,AXIS_X},
|
||||
{4,4,10,AXIS_Z},
|
||||
{1,0,11,AXIS_X},{2,0,11,AXIS_X},{6,0,11,AXIS_X},{7,0,11,AXIS_X},
|
||||
{0,1,11,AXIS_Y},{8,1,11,AXIS_Y},{0,2,11,AXIS_Y},{8,2,11,AXIS_Y},{0,3,11,AXIS_Y},{8,3,11,AXIS_Y},
|
||||
{0,4,11,AXIS_X},{1,4,11,AXIS_X},{2,4,11,AXIS_X},{3,4,11,AXIS_X},{4,4,11,AXIS_Z},{5,4,11,AXIS_X},{6,4,11,AXIS_X},{7,4,11,AXIS_X},{8,4,11,AXIS_X},
|
||||
{4,4,12,AXIS_Z},
|
||||
};
|
||||
|
||||
static const FossilStructure skullStructures[4] = {
|
||||
{6, 5, 7, skull01, (int)(sizeof(skull01)/sizeof(skull01[0]))},
|
||||
{7, 5, 5, skull02, (int)(sizeof(skull02)/sizeof(skull02[0]))},
|
||||
{5, 4, 5, skull03, (int)(sizeof(skull03)/sizeof(skull03[0]))},
|
||||
{4, 4, 4, skull04, (int)(sizeof(skull04)/sizeof(skull04[0]))},
|
||||
};
|
||||
|
||||
static const FossilStructure spineStructures[4] = {
|
||||
{3, 3, 13, spine01, (int)(sizeof(spine01)/sizeof(spine01[0]))},
|
||||
{5, 4, 13, spine02, (int)(sizeof(spine02)/sizeof(spine02[0]))},
|
||||
{7, 4, 13, spine03, (int)(sizeof(spine03)/sizeof(spine03[0]))},
|
||||
{9, 5, 13, spine04, (int)(sizeof(spine04)/sizeof(spine04[0]))},
|
||||
};
|
||||
|
||||
bool FossilFeature::place(Level *level, Random *random, int x, int y, int z)
|
||||
{
|
||||
bool useSpine = random->nextInt(2) == 0;
|
||||
bool useCoal = random->nextInt(2) == 0;
|
||||
int variant = random->nextInt(4);
|
||||
|
||||
const FossilStructure &s = useSpine ? spineStructures[variant] : skullStructures[variant];
|
||||
|
||||
int ox = x - s.width / 2;
|
||||
int oy = y;
|
||||
int oz = z - s.length / 2;
|
||||
|
||||
for (int i = 0; i < s.blockCount; i++)
|
||||
{
|
||||
const FossilBlock &b = s.blocks[i];
|
||||
int bx = ox + b.x;
|
||||
int by = oy + b.y;
|
||||
int bz = oz + b.z;
|
||||
|
||||
if (by < 1 || by >= Level::maxBuildHeight)
|
||||
continue;
|
||||
|
||||
if (useCoal)
|
||||
level->setTileAndData(bx, by, bz, Tile::coal_ore_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
else
|
||||
level->setTileAndData(bx, by, bz, Tile::bone_block_Id, b.data, Tile::UPDATE_CLIENTS);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "Feature.h"
|
||||
|
||||
class FossilFeature : public Feature
|
||||
{
|
||||
public:
|
||||
bool place(Level *level, Random *random, int x, int y, int z) override;
|
||||
};
|
||||
@@ -487,6 +487,15 @@ void HellRandomLevelSource::postProcess(ChunkSource *parent, int xt, int zt)
|
||||
FlowerFeature(Tile::mushroom_red_Id).place(level, pprandom, x, y, z);
|
||||
}
|
||||
|
||||
OreFeature magmaFeature(Tile::magma_Id, 0, 160, Tile::netherrack_Id);
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int x = xo + pprandom->nextInt(16);
|
||||
int y = pprandom->nextInt(9) + 27;
|
||||
int z = zo + pprandom->nextInt(16);
|
||||
magmaFeature.place(level, pprandom, x, y, z);
|
||||
}
|
||||
|
||||
OreFeature quartzFeature(Tile::quartz_ore_Id, 0, 13, Tile::netherrack_Id);
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
|
||||
@@ -19,6 +19,7 @@ bool HugeMushroomFeature::place(Level *level, Random *random, int x, int y, int
|
||||
if (forcedType >= 0) type = forcedType;
|
||||
|
||||
int treeHeight = random->nextInt(3) + 4;
|
||||
if (random->nextBoolean()) treeHeight *= 2;
|
||||
|
||||
bool free = true;
|
||||
if (y < 1 || y + treeHeight + 1 >= Level::maxBuildHeight) return false;
|
||||
|
||||
@@ -0,0 +1,218 @@
|
||||
#include "stdafx.h"
|
||||
#include "net.minecraft.world.level.h"
|
||||
#include "net.minecraft.world.level.tile.h"
|
||||
#include "net.minecraft.world.level.tile.entity.h"
|
||||
#include "Biome.h"
|
||||
#include "Item.h"
|
||||
#include "ItemInstance.h"
|
||||
#include "WeighedTreasure.h"
|
||||
#include "Villager.h"
|
||||
#include "Zombie.h"
|
||||
#include "IglooFeature.h"
|
||||
|
||||
bool IglooFeature::place(Level *level, Random *random, int x, int y, int z)
|
||||
{
|
||||
while (y > 2 && level->isEmptyTile(x, y - 1, z))
|
||||
y--;
|
||||
|
||||
Biome *biome = level->getBiome(x, z);
|
||||
if (biome != Biome::iceFlats && biome != Biome::iceMountains &&
|
||||
biome != Biome::coldTaiga && biome != Biome::coldTaigaHills)
|
||||
return false;
|
||||
|
||||
for (int dx = -3; dx <= 3; dx++)
|
||||
for (int dz = -3; dz <= 3; dz++)
|
||||
if (abs(dx) + abs(dz) < 6)
|
||||
level->setTileAndData(x + dx, y, z + dz, Tile::snow_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
|
||||
for (int dy = 1; dy <= 2; dy++)
|
||||
{
|
||||
for (int dx = -3; dx <= 3; dx++)
|
||||
{
|
||||
for (int dz = -3; dz <= 3; dz++)
|
||||
{
|
||||
bool onPerimeter = (abs(dx) == 3 || abs(dz) == 3) && abs(dx) + abs(dz) < 6;
|
||||
if (!onPerimeter)
|
||||
continue;
|
||||
if (dx == 0 && dz == 3)
|
||||
continue;
|
||||
if ((dx == 3 || dx == -3) && dz == 0 && dy == 1)
|
||||
level->setTileAndData(x + dx, y + dy, z + dz, Tile::ice_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
else
|
||||
level->setTileAndData(x + dx, y + dy, z + dz, Tile::snow_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
level->setTileAndData(x, y + 3, z + 3, Tile::snow_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
|
||||
level->setTileAndData(x - 1, y, z + 4, Tile::snow_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
level->setTileAndData(x, y, z + 4, Tile::snow_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
level->setTileAndData(x + 1, y, z + 4, Tile::snow_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
level->setTileAndData(x - 1, y + 1, z + 4, Tile::snow_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
level->setTileAndData(x + 1, y + 1, z + 4, Tile::snow_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
level->setTileAndData(x - 1, y + 2, z + 4, Tile::snow_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
level->setTileAndData(x + 1, y + 2, z + 4, Tile::snow_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
level->setTileAndData(x, y + 3, z + 4, Tile::snow_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
|
||||
for (int dx = -2; dx <= 2; dx++)
|
||||
for (int dz = -2; dz <= 2; dz++)
|
||||
if (abs(dx) == 2 || abs(dz) == 2)
|
||||
level->setTileAndData(x + dx, y + 3, z + dz, Tile::snow_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
|
||||
for (int dx = -1; dx <= 1; dx++)
|
||||
for (int dz = -1; dz <= 1; dz++)
|
||||
level->setTileAndData(x + dx, y + 4, z + dz, Tile::snow_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
|
||||
for (int dy = 1; dy <= 2; dy++)
|
||||
for (int dx = -2; dx <= 2; dx++)
|
||||
for (int dz = -2; dz <= 2; dz++)
|
||||
level->setTileAndData(x + dx, y + dy, z + dz, 0, 0, Tile::UPDATE_CLIENTS);
|
||||
|
||||
for (int dx = -1; dx <= 1; dx++)
|
||||
for (int dz = -1; dz <= 1; dz++)
|
||||
level->setTileAndData(x + dx, y + 3, z + dz, 0, 0, Tile::UPDATE_CLIENTS);
|
||||
|
||||
for (int dx = -1; dx <= 1; dx++)
|
||||
for (int dz = -1; dz <= 1; dz++)
|
||||
level->setTileAndData(x + dx, y + 1, z + dz, Tile::carpet_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
|
||||
level->setTileAndData(x - 1, y + 1, z - 2, Tile::carpet_Id, 8, Tile::UPDATE_CLIENTS);
|
||||
level->setTileAndData(x, y + 1, z - 2, Tile::carpet_Id, 8, Tile::UPDATE_CLIENTS);
|
||||
level->setTileAndData(x + 1, y + 1, z - 2, Tile::carpet_Id, 8, Tile::UPDATE_CLIENTS);
|
||||
|
||||
level->setTileAndData(x + 2, y + 1, z + 1, Tile::furnace_Id, 4, Tile::UPDATE_CLIENTS);
|
||||
level->setTileAndData(x + 2, y + 1, z, Tile::redstone_torch_Id, 5, Tile::UPDATE_CLIENTS);
|
||||
level->setTileAndData(x + 2, y + 1, z - 1, Tile::crafting_table_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
|
||||
level->setTileAndData(x - 2, y + 1, z, Tile::bed_Id, 2, Tile::UPDATE_CLIENTS);
|
||||
level->setTileAndData(x - 2, y + 1, z - 1, Tile::bed_Id, 2 | 8, Tile::UPDATE_CLIENTS);
|
||||
|
||||
level->setTileAndData(x - 2, y + 1, z - 2, Tile::snow_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
level->setTileAndData(x + 2, y + 1, z - 2, Tile::snow_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
level->setTileAndData(x - 2, y + 1, z + 2, Tile::snow_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
level->setTileAndData(x + 2, y + 1, z + 2, Tile::snow_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
level->setTileAndData(x - 2, y + 2, z - 2, Tile::snow_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
level->setTileAndData(x + 2, y + 2, z - 2, Tile::snow_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
level->setTileAndData(x - 2, y + 2, z + 2, Tile::snow_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
level->setTileAndData(x + 2, y + 2, z + 2, Tile::snow_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
|
||||
if (random->nextInt(2) == 0)
|
||||
placeBasement(level, random, x, y, z);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void IglooFeature::placeBasement(Level *level, Random *random, int x, int y, int z)
|
||||
{
|
||||
int by = y - 9;
|
||||
int rz = z + 2;
|
||||
|
||||
for (int dx = -3; dx <= 3; dx++)
|
||||
{
|
||||
for (int dz = -4; dz <= 4; dz++)
|
||||
{
|
||||
for (int dy = 0; dy <= 4; dy++)
|
||||
{
|
||||
bool isWall = abs(dx) == 3 || abs(dz) == 4 || dy == 0 || dy == 4;
|
||||
if (isWall)
|
||||
{
|
||||
int data = 0;
|
||||
if (random->nextInt(5) == 0)
|
||||
data = 2;
|
||||
else if (random->nextInt(4) == 0)
|
||||
data = 1;
|
||||
level->setTileAndData(x + dx, by + dy, rz + dz, Tile::stonebrick_Id, data, Tile::UPDATE_CLIENTS);
|
||||
}
|
||||
else
|
||||
{
|
||||
level->setTileAndData(x + dx, by + dy, rz + dz, 0, 0, Tile::UPDATE_CLIENTS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
level->setTileAndData(x, y, z - 1, Tile::trapdoor_Id, 4, Tile::UPDATE_CLIENTS);
|
||||
|
||||
for (int i = 1; i <= 5; i++)
|
||||
level->setTileAndData(x, y - i, z - 1, Tile::ladder_Id, 3, Tile::UPDATE_CLIENTS);
|
||||
|
||||
for (int dy = 1; dy <= 3; dy++)
|
||||
level->setTileAndData(x, by + dy, z - 1, Tile::ladder_Id, 3, Tile::UPDATE_CLIENTS);
|
||||
|
||||
level->setTileAndData(x + 2, by + 1, rz - 2, Tile::chest_Id, 4, Tile::UPDATE_CLIENTS);
|
||||
auto chestEntity = dynamic_pointer_cast<ChestTileEntity>(level->getTileEntity(x + 2, by + 1, rz - 2));
|
||||
if (chestEntity)
|
||||
{
|
||||
static WeighedTreasure *iglooTreasure[] = {
|
||||
new WeighedTreasure(Item::coal_Id, 0, 1, 4, 15),
|
||||
new WeighedTreasure(Item::apple_Id, 0, 1, 3, 15),
|
||||
new WeighedTreasure(Item::wheat_Id, 0, 2, 3, 10),
|
||||
new WeighedTreasure(Item::gold_nugget_Id, 0, 1, 3, 10),
|
||||
new WeighedTreasure(Item::rotten_flesh_Id,0, 1, 1, 10),
|
||||
new WeighedTreasure(Item::stone_axe_Id, 0, 1, 1, 2),
|
||||
new WeighedTreasure(Item::emerald_Id, 0, 1, 1, 1),
|
||||
};
|
||||
WeighedTreasureArray treasureArray(iglooTreasure, 7);
|
||||
int rolls = 2 + random->nextInt(7);
|
||||
WeighedTreasure::addChestItems(random, treasureArray, chestEntity, rolls);
|
||||
chestEntity->setItem(0, make_shared<ItemInstance>(Item::golden_apple_Id, 1, 0));
|
||||
}
|
||||
|
||||
level->setTileAndData(x - 2, by + 2, rz - 2, Tile::brewing_stand_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
auto brewEntity = dynamic_pointer_cast<BrewingStandTileEntity>(level->getTileEntity(x - 2, by + 2, rz - 2));
|
||||
if (brewEntity)
|
||||
brewEntity->setItem(1, make_shared<ItemInstance>(Item::potion_Id, 1, 16392));
|
||||
level->setTileAndData(x - 2, by + 1, rz, Tile::cauldron_Id, 2, Tile::UPDATE_CLIENTS);
|
||||
|
||||
level->setTileAndData(x - 2, by + 1, rz - 3, Tile::spruce_stairs_Id, 7, Tile::UPDATE_CLIENTS);
|
||||
level->setTileAndData(x - 2, by + 1, rz - 2, Tile::wooden_slab_Id, 9, Tile::UPDATE_CLIENTS);
|
||||
level->setTileAndData(x - 2, by + 1, rz - 1, Tile::spruce_stairs_Id, 6, Tile::UPDATE_CLIENTS);
|
||||
|
||||
level->setTileAndData(x + 2, by + 1, rz - 1, Tile::carpet_Id, 14, Tile::UPDATE_CLIENTS);
|
||||
level->setTileAndData(x + 2, by + 1, rz, Tile::carpet_Id, 14, Tile::UPDATE_CLIENTS);
|
||||
level->setTileAndData(x + 2, by + 1, rz + 1, Tile::carpet_Id, 14, Tile::UPDATE_CLIENTS);
|
||||
|
||||
for (int cdx = -2; cdx <= 2; cdx++)
|
||||
{
|
||||
bool isBar = (cdx % 2 != 0);
|
||||
level->setTileAndData(x + cdx, by + 1, rz + 2, isBar ? Tile::iron_bars_Id : Tile::stonebrick_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
level->setTileAndData(x + cdx, by + 2, rz + 2, isBar ? Tile::iron_bars_Id : Tile::stonebrick_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
level->setTileAndData(x + cdx, by + 3, rz + 2, Tile::stonebrick_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
}
|
||||
|
||||
for (int dy = 1; dy <= 3; dy++)
|
||||
{
|
||||
level->setTileAndData(x - 2, by + dy, rz + 3, Tile::stonebrick_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
level->setTileAndData(x, by + dy, rz + 3, Tile::stonebrick_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
level->setTileAndData(x + 2, by + dy, rz + 3, Tile::stonebrick_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
}
|
||||
|
||||
level->setTileAndData(x + 2, by + 3, rz + 1, Tile::web_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
|
||||
level->setTileAndData(x - 1, by + 3, z - 1, Tile::torch_Id, 3, Tile::UPDATE_CLIENTS);
|
||||
level->setTileAndData(x + 1, by + 3, z - 1, Tile::torch_Id, 3, Tile::UPDATE_CLIENTS);
|
||||
level->setTileAndData(x, by + 3, rz + 1, Tile::torch_Id, 4, Tile::UPDATE_CLIENTS);
|
||||
level->setTileAndData(x, by + 2, rz + 1, Tile::wall_standing_sign_Id, 2, Tile::UPDATE_CLIENTS);
|
||||
auto signEntity = dynamic_pointer_cast<SignTileEntity>(level->getTileEntity(x, by + 2, rz + 1));
|
||||
if (signEntity)
|
||||
{
|
||||
wstring empty = L"";
|
||||
wstring line1 = L"<----";
|
||||
wstring line2 = L"---->";
|
||||
signEntity->SetMessage(0, empty);
|
||||
signEntity->SetMessage(1, line1);
|
||||
signEntity->SetMessage(2, line2);
|
||||
signEntity->SetMessage(3, empty);
|
||||
}
|
||||
level->setTileAndData(x - 2, by + 2, rz - 3, Tile::flower_pot_Id, 9, Tile::UPDATE_CLIENTS);
|
||||
|
||||
auto zombieVillager = std::make_shared<Zombie>(level);
|
||||
zombieVillager->setVillager(true);
|
||||
zombieVillager->moveTo(x - 1 + 0.5, by + 1, rz + 3 + 0.5, 0, 0);
|
||||
level->addEntity(zombieVillager);
|
||||
|
||||
auto villager = std::make_shared<Villager>(level);
|
||||
villager->moveTo(x + 1 + 0.5, by + 1, rz + 3 + 0.5, 0, 0);
|
||||
level->addEntity(villager);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "Feature.h"
|
||||
|
||||
class IglooFeature : public Feature
|
||||
{
|
||||
public:
|
||||
bool place(Level *level, Random *random, int x, int y, int z) override;
|
||||
|
||||
private:
|
||||
void placeBasement(Level *level, Random *random, int x, int y, int z);
|
||||
};
|
||||
@@ -753,23 +753,28 @@ void LivingEntity::removeEffect(int effectId)
|
||||
void LivingEntity::onEffectAdded(MobEffectInstance *effect)
|
||||
{
|
||||
effectsDirty = true;
|
||||
if (!level->isClientSide) MobEffect::effects[effect->getId()]->addAttributeModifiers(dynamic_pointer_cast<LivingEntity>(shared_from_this()), getAttributes(), effect->getAmplifier());
|
||||
int _id0 = effect->getId();
|
||||
if (!level->isClientSide && _id0 >= 0 && _id0 < MobEffect::NUM_EFFECTS && MobEffect::effects[_id0])
|
||||
MobEffect::effects[_id0]->addAttributeModifiers(dynamic_pointer_cast<LivingEntity>(shared_from_this()), getAttributes(), effect->getAmplifier());
|
||||
}
|
||||
|
||||
void LivingEntity::onEffectUpdated(MobEffectInstance *effect, bool doRefreshAttributes)
|
||||
{
|
||||
effectsDirty = true;
|
||||
if (doRefreshAttributes && !level->isClientSide)
|
||||
int _id1 = effect->getId();
|
||||
if (doRefreshAttributes && !level->isClientSide && _id1 >= 0 && _id1 < MobEffect::NUM_EFFECTS && MobEffect::effects[_id1])
|
||||
{
|
||||
MobEffect::effects[effect->getId()]->removeAttributeModifiers(dynamic_pointer_cast<LivingEntity>(shared_from_this()), getAttributes(), effect->getAmplifier());
|
||||
MobEffect::effects[effect->getId()]->addAttributeModifiers(dynamic_pointer_cast<LivingEntity>(shared_from_this()), getAttributes(), effect->getAmplifier());
|
||||
MobEffect::effects[_id1]->removeAttributeModifiers(dynamic_pointer_cast<LivingEntity>(shared_from_this()), getAttributes(), effect->getAmplifier());
|
||||
MobEffect::effects[_id1]->addAttributeModifiers(dynamic_pointer_cast<LivingEntity>(shared_from_this()), getAttributes(), effect->getAmplifier());
|
||||
}
|
||||
}
|
||||
|
||||
void LivingEntity::onEffectRemoved(MobEffectInstance *effect)
|
||||
{
|
||||
effectsDirty = true;
|
||||
if (!level->isClientSide) MobEffect::effects[effect->getId()]->removeAttributeModifiers(dynamic_pointer_cast<LivingEntity>(shared_from_this()), getAttributes(), effect->getAmplifier());
|
||||
int _id2 = effect->getId();
|
||||
if (!level->isClientSide && _id2 >= 0 && _id2 < MobEffect::NUM_EFFECTS && MobEffect::effects[_id2])
|
||||
MobEffect::effects[_id2]->removeAttributeModifiers(dynamic_pointer_cast<LivingEntity>(shared_from_this()), getAttributes(), effect->getAmplifier());
|
||||
}
|
||||
|
||||
void LivingEntity::heal(float heal)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "stdafx.h"
|
||||
#include "net.minecraft.world.level.levelgen.structure.h"
|
||||
#include "net.minecraft.world.level.biome.h"
|
||||
#include "JavaMath.h"
|
||||
#include "Mth.h"
|
||||
|
||||
@@ -37,7 +38,16 @@ bool MineShaftFeature::isFeatureChunk(int x, int z, bool bIsSuperflat)
|
||||
forcePlacement = levelGenOptions->isFeatureChunk(x,z,eFeature_Mineshaft);
|
||||
}
|
||||
|
||||
return forcePlacement || (random->nextDouble() < chance && random->nextInt(80) < max(abs(x), abs(z)));
|
||||
double effectiveChance = chance;
|
||||
if (level != nullptr)
|
||||
{
|
||||
Biome *b = level->getBiome(x * 16, z * 16);
|
||||
if (b == Biome::mesa || b == Biome::mesaPlateauF || b == Biome::mesaPlateau ||
|
||||
b == Biome::mesaBryce || b == Biome::mesaPlateauFM || b == Biome::mesaPlateauM)
|
||||
effectiveChance = 0.9;
|
||||
}
|
||||
|
||||
return forcePlacement || (random->nextDouble() < effectiveChance && random->nextInt(80) < max(abs(x), abs(z)));
|
||||
}
|
||||
|
||||
StructureStart *MineShaftFeature::createStructureStart(int x, int z)
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
#include "stdafx.h"
|
||||
#include "net.minecraft.world.effect.h"
|
||||
|
||||
static MobEffect *safeEffect(int id)
|
||||
{
|
||||
if (id < 0 || id >= MobEffect::NUM_EFFECTS) return nullptr;
|
||||
return MobEffect::effects[id];
|
||||
}
|
||||
|
||||
void MobEffectInstance::_init(int id, int duration, int amplifier)
|
||||
{
|
||||
this->id = id;
|
||||
@@ -104,7 +110,8 @@ bool MobEffectInstance::tick(shared_ptr<LivingEntity> target)
|
||||
{
|
||||
if (duration > 0)
|
||||
{
|
||||
if (MobEffect::effects[id]->isDurationEffectTick(duration, amplifier))
|
||||
MobEffect *effect = safeEffect(id);
|
||||
if (effect && effect->isDurationEffectTick(duration, amplifier))
|
||||
{
|
||||
applyEffect(target);
|
||||
}
|
||||
@@ -122,19 +129,22 @@ void MobEffectInstance::applyEffect(shared_ptr<LivingEntity> mob)
|
||||
{
|
||||
if (duration > 0)
|
||||
{
|
||||
MobEffect::effects[id]->applyEffectTick(mob, amplifier);
|
||||
MobEffect *effect = safeEffect(id);
|
||||
if (effect) effect->applyEffectTick(mob, amplifier);
|
||||
}
|
||||
}
|
||||
|
||||
int MobEffectInstance::getDescriptionId()
|
||||
{
|
||||
return MobEffect::effects[id]->getDescriptionId();
|
||||
MobEffect *effect = safeEffect(id);
|
||||
return effect ? effect->getDescriptionId() : 0;
|
||||
}
|
||||
|
||||
// 4J Added
|
||||
int MobEffectInstance::getPostfixDescriptionId()
|
||||
{
|
||||
return MobEffect::effects[id]->getPostfixDescriptionId();
|
||||
MobEffect *effect = safeEffect(id);
|
||||
return effect ? effect->getPostfixDescriptionId() : 0;
|
||||
}
|
||||
|
||||
int MobEffectInstance::hashCode()
|
||||
@@ -182,6 +192,7 @@ CompoundTag *MobEffectInstance::save(CompoundTag *tag)
|
||||
MobEffectInstance *MobEffectInstance::load(CompoundTag *tag)
|
||||
{
|
||||
int id = tag->getByte(L"Id");
|
||||
if (id < 0 || id >= MobEffect::NUM_EFFECTS) return nullptr;
|
||||
int amplifier = tag->getByte(L"Amplifier");
|
||||
int duration = tag->getInt(L"Duration");
|
||||
boolean ambient = tag->getBoolean(L"Ambient");
|
||||
|
||||
@@ -32,8 +32,6 @@ void OreRecipies::_init()
|
||||
ADD_OBJECT(map[7],Tile::hayBlock);
|
||||
ADD_OBJECT(map[7],new ItemInstance(Item::wheat, 9));
|
||||
|
||||
ADD_OBJECT(map[8],Tile::slimeBlock);
|
||||
ADD_OBJECT(map[8],new ItemInstance(Item::slime_ball, 9));
|
||||
}
|
||||
void OreRecipies::addRecipes(Recipes *r)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#define MAX_ORE_RECIPES 9
|
||||
#define MAX_ORE_RECIPES 8
|
||||
|
||||
class OreRecipies
|
||||
{
|
||||
|
||||
@@ -80,5 +80,12 @@ void PlainsBiome::decorate(Level* level, Random* rand, int xo, int zo)
|
||||
DOUBLE_PLANT_GENERATOR->place(level, rand, j1, l1, k1);
|
||||
}
|
||||
}
|
||||
if (rand->nextInt(10) == 0)
|
||||
decorator->treeCount = 1;
|
||||
else
|
||||
decorator->treeCount = 0;
|
||||
|
||||
Biome::decorate(level, rand, xo, zo);
|
||||
|
||||
decorator->treeCount = -999;
|
||||
}
|
||||
+52
-18
@@ -91,6 +91,9 @@ void Player::_init()
|
||||
m_elytraImpactYd = 0.0f;
|
||||
m_wasElytraFlying = false;
|
||||
m_elytraFallProtectTicks = 0;
|
||||
m_elytraMaxY = 0.0f;
|
||||
m_fireworkBoostTicks = 0;
|
||||
m_elytraRocketCooldown = 0;
|
||||
|
||||
takeXpDelay = 0;
|
||||
experienceLevel = totalExperience = 0;
|
||||
@@ -1016,6 +1019,7 @@ void Player::aiStep()
|
||||
{
|
||||
if (jumpTriggerTime > 0) jumpTriggerTime--;
|
||||
if (m_elytraFallProtectTicks > 0) m_elytraFallProtectTicks--;
|
||||
if (m_elytraRocketCooldown > 0) m_elytraRocketCooldown--;
|
||||
|
||||
|
||||
if (level->difficulty == Difficulty::PEACEFUL && getHealth() < getMaxHealth() && level->getGameRules()->getBoolean(GameRules::RULE_NATURAL_REGENERATION))
|
||||
@@ -1025,7 +1029,7 @@ void Player::aiStep()
|
||||
inventory->tick();
|
||||
oBob = bob;
|
||||
|
||||
if (jumping && !onGround && yd < 0.0 && !isElytraFlying() && !abilities.flying && jumpTriggerTime == 0)
|
||||
if (jumping && !onGround && yd < 0.0 && fallDistance > 0.0f && !isElytraFlying() && !abilities.flying && jumpTriggerTime == 0)
|
||||
{
|
||||
shared_ptr<ItemInstance> chestItem = inventory->armor[LivingEntity::SLOT_CHEST - 1];
|
||||
if (chestItem != nullptr && chestItem->getItem() != nullptr)
|
||||
@@ -1044,20 +1048,12 @@ void Player::aiStep()
|
||||
{
|
||||
ticksElytraFlying++;
|
||||
|
||||
if (!level->isClientSide && ticksElytraFlying % 20 == 0)
|
||||
{
|
||||
shared_ptr<ItemInstance> chestItem = inventory->armor[LivingEntity::SLOT_CHEST - 1];
|
||||
if (chestItem != nullptr && dynamic_cast<ElytraItem*>(chestItem->getItem()) != nullptr)
|
||||
{
|
||||
chestItem->hurtAndBreak(1, dynamic_pointer_cast<LivingEntity>(shared_from_this()));
|
||||
if (!ElytraItem::isFlyEnabled(chestItem))
|
||||
setElytraFlying(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
setElytraFlying(false);
|
||||
}
|
||||
}
|
||||
shared_ptr<ItemInstance> chestItem = inventory->armor[LivingEntity::SLOT_CHEST - 1];
|
||||
if (chestItem == nullptr
|
||||
|| chestItem->count <= 0
|
||||
|| dynamic_cast<ElytraItem*>(chestItem->getItem()) == nullptr
|
||||
|| !ElytraItem::isFlyEnabled(chestItem))
|
||||
setElytraFlying(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -2171,6 +2167,8 @@ void Player::travel(float xa, float ya)
|
||||
double preHorizSpeed = Mth::sqrt(xd * xd + zd * zd);
|
||||
|
||||
|
||||
if ((float)y > m_elytraMaxY) m_elytraMaxY = (float)y;
|
||||
|
||||
if (yd > -0.5)
|
||||
fallDistance = 1.0f;
|
||||
|
||||
@@ -2217,10 +2215,19 @@ void Player::travel(float xa, float ya)
|
||||
if (jumping && abilities.instabuild)
|
||||
yd += (double)abilities.getFlyingSpeed() * 3.0;
|
||||
|
||||
if (m_fireworkBoostTicks > 0)
|
||||
{
|
||||
Vec3 *look = getLookAngle();
|
||||
xd += look->x * 0.1 + (look->x * 1.5 - xd) * 0.5;
|
||||
yd += look->y * 0.1 + (look->y * 1.5 - yd) * 0.5;
|
||||
zd += look->z * 0.1 + (look->z * 1.5 - zd) * 0.5;
|
||||
m_fireworkBoostTicks--;
|
||||
}
|
||||
|
||||
m_elytraImpactYd = (float)yd;
|
||||
move(xd, yd, zd);
|
||||
|
||||
if (horizontalCollision && !verticalCollision)
|
||||
if (horizontalCollision)
|
||||
{
|
||||
double postHorizSpeed = Mth::sqrt(xd * xd + zd * zd);
|
||||
double speedLost = preHorizSpeed - postHorizSpeed;
|
||||
@@ -2428,6 +2435,14 @@ void Player::causeFallDamage(float distance)
|
||||
{
|
||||
if (abilities.mayfly) return;
|
||||
|
||||
if (isElytraFlying())
|
||||
{
|
||||
int dmg = Mth::ceil(distance - 3.0f);
|
||||
if (dmg > 0)
|
||||
onElytraFallDamage(dmg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (distance >= 2)
|
||||
{
|
||||
distanceFall += static_cast<int>(Math::round(distance * 100.0));
|
||||
@@ -2835,9 +2850,26 @@ bool Player::isElytraFlying()
|
||||
return getPlayerFlag(FLAG_ELYTRA_FLYING);
|
||||
}
|
||||
|
||||
void Player::startFireworkBoost(shared_ptr<ItemInstance> firework)
|
||||
{
|
||||
int flight = 0;
|
||||
if (firework != nullptr && firework->hasTag())
|
||||
{
|
||||
CompoundTag *fw = firework->getTag()->getCompound(FireworksItem::TAG_FIREWORKS);
|
||||
if (fw != nullptr && fw->contains(FireworksItem::TAG_FLIGHT))
|
||||
flight = fw->getByte(FireworksItem::TAG_FLIGHT);
|
||||
}
|
||||
m_fireworkBoostTicks = (SharedConstants::TICKS_PER_SECOND / 2) * (flight + 1) + random->nextInt(6) + random->nextInt(7);
|
||||
}
|
||||
|
||||
void Player::onElytraKineticDamage(float damage)
|
||||
{
|
||||
hurt(DamageSource::fall, damage);
|
||||
hurt(DamageSource::flyIntoWall, damage);
|
||||
}
|
||||
|
||||
void Player::onElytraFallDamage(int amount)
|
||||
{
|
||||
hurt(DamageSource::fall, (float)amount);
|
||||
}
|
||||
|
||||
void Player::setElytraFlying(bool flying)
|
||||
@@ -2848,6 +2880,7 @@ void Player::setElytraFlying(bool flying)
|
||||
m_wasElytraFlying = false;
|
||||
setSize(0.6f, 0.6f);
|
||||
fallDistance = 0.0f;
|
||||
m_elytraMaxY = (float)y;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2855,8 +2888,9 @@ void Player::setElytraFlying(bool flying)
|
||||
|
||||
m_wasElytraFlying = true;
|
||||
m_elytraFallProtectTicks = 60;
|
||||
m_fireworkBoostTicks = 0;
|
||||
m_elytraRocketCooldown = 0;
|
||||
setSize(0.6f, 1.8f);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -88,10 +88,18 @@ public:
|
||||
float m_elytraImpactYd;
|
||||
bool m_wasElytraFlying;
|
||||
int m_elytraFallProtectTicks;
|
||||
float m_elytraMaxY;
|
||||
|
||||
public:
|
||||
int m_fireworkBoostTicks;
|
||||
int m_elytraRocketCooldown;
|
||||
public:
|
||||
void startFireworkBoost(shared_ptr<ItemInstance> firework);
|
||||
bool isElytraFlying();
|
||||
virtual void setElytraFlying(bool flying);
|
||||
|
||||
virtual void onElytraKineticDamage(float damage);
|
||||
virtual void onElytraFallDamage(int amount);
|
||||
|
||||
public:
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ PlayerAbilitiesPacket::PlayerAbilitiesPacket()
|
||||
_isFlying = false;
|
||||
_canFly = false;
|
||||
instabuild = false;
|
||||
_noPhysics = false;
|
||||
flyingSpeed = 0.0f;
|
||||
walkingSpeed = 0.0f;
|
||||
}
|
||||
@@ -19,6 +20,7 @@ PlayerAbilitiesPacket::PlayerAbilitiesPacket(Abilities *abilities)
|
||||
setFlying(abilities->flying);
|
||||
setCanFly(abilities->mayfly);
|
||||
setInstabuild(abilities->instabuild);
|
||||
setNoPhysics(abilities->spectatorMode);
|
||||
setFlyingSpeed(abilities->getFlyingSpeed());
|
||||
setWalkingSpeed(abilities->getWalkingSpeed());
|
||||
}
|
||||
@@ -31,6 +33,7 @@ void PlayerAbilitiesPacket::read(DataInputStream *dis)
|
||||
setFlying((bitfield & FLAG_FLYING) > 0);
|
||||
setCanFly((bitfield & FLAG_CAN_FLY) > 0);
|
||||
setInstabuild((bitfield & FLAG_INSTABUILD) > 0);
|
||||
setNoPhysics((bitfield & FLAG_NOPHYSICS) > 0);
|
||||
setFlyingSpeed(dis->readFloat());
|
||||
setWalkingSpeed(dis->readFloat());
|
||||
}
|
||||
@@ -43,6 +46,7 @@ void PlayerAbilitiesPacket::write(DataOutputStream *dos)
|
||||
if (isFlying()) bitfield |= FLAG_FLYING;
|
||||
if (canFly()) bitfield |= FLAG_CAN_FLY;
|
||||
if (canInstabuild()) bitfield |= FLAG_INSTABUILD;
|
||||
if (isNoPhysics()) bitfield |= FLAG_NOPHYSICS;
|
||||
|
||||
dos->writeByte(bitfield);
|
||||
dos->writeFloat(flyingSpeed);
|
||||
@@ -124,6 +128,16 @@ void PlayerAbilitiesPacket::setWalkingSpeed(float walkingSpeed)
|
||||
this->walkingSpeed = walkingSpeed;
|
||||
}
|
||||
|
||||
bool PlayerAbilitiesPacket::isNoPhysics()
|
||||
{
|
||||
return _noPhysics;
|
||||
}
|
||||
|
||||
void PlayerAbilitiesPacket::setNoPhysics(bool noPhysics)
|
||||
{
|
||||
_noPhysics = noPhysics;
|
||||
}
|
||||
|
||||
bool PlayerAbilitiesPacket::canBeInvalidated()
|
||||
{
|
||||
return true;
|
||||
|
||||
@@ -11,11 +11,13 @@ private:
|
||||
static const int FLAG_FLYING = 1 << 1;
|
||||
static const int FLAG_CAN_FLY = 1 << 2;
|
||||
static const int FLAG_INSTABUILD = 1 << 3;
|
||||
static const int FLAG_NOPHYSICS = 1 << 4;
|
||||
|
||||
bool invulnerable;
|
||||
bool _isFlying;
|
||||
bool _canFly;
|
||||
bool instabuild;
|
||||
bool _noPhysics;
|
||||
float flyingSpeed;
|
||||
float walkingSpeed;
|
||||
|
||||
@@ -40,6 +42,8 @@ public:
|
||||
void setFlyingSpeed(float flySpeed);
|
||||
float getWalkingSpeed();
|
||||
void setWalkingSpeed(float walkingSpeed);
|
||||
bool isNoPhysics();
|
||||
void setNoPhysics(bool noPhysics);
|
||||
bool canBeInvalidated();
|
||||
bool isInvalidatedBy(shared_ptr<Packet> packet);
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@ const int PlayerActionPacket::STOP_DESTROY_BLOCK = 2;
|
||||
const int PlayerActionPacket::DROP_ALL_ITEMS = 3;
|
||||
const int PlayerActionPacket::DROP_ITEM = 4;
|
||||
const int PlayerActionPacket::RELEASE_USE_ITEM = 5;
|
||||
const int PlayerActionPacket::ELYTRA_IMPACT = 6;
|
||||
const int PlayerActionPacket::ELYTRA_FALL_DAMAGE = 7;
|
||||
|
||||
PlayerActionPacket::PlayerActionPacket()
|
||||
{
|
||||
|
||||
@@ -12,6 +12,8 @@ public:
|
||||
static const int DROP_ALL_ITEMS;
|
||||
static const int DROP_ITEM;
|
||||
static const int RELEASE_USE_ITEM;
|
||||
static const int ELYTRA_IMPACT;
|
||||
static const int ELYTRA_FALL_DAMAGE;
|
||||
|
||||
int x, y, z, face, action;
|
||||
|
||||
|
||||
@@ -392,7 +392,7 @@ vector<pair<int, int> > *PotionItem::getUniquePotionValues()
|
||||
int effectsHashCode = 1;
|
||||
for(auto& effect : *effects)
|
||||
{
|
||||
effectsHashCode = 31*effectsHashCode + (effect ? 0 : effect->hashCode());
|
||||
effectsHashCode = 31*effectsHashCode + (effect ? effect->hashCode() : 0);
|
||||
delete effect;
|
||||
}
|
||||
|
||||
|
||||
@@ -782,6 +782,24 @@ void RandomLevelSource::postProcess(ChunkSource *parent, int xt, int zt)
|
||||
}
|
||||
PIXEndNamedEvent();
|
||||
|
||||
if (pprandom->nextInt(64) == 0)
|
||||
{
|
||||
int fx = xo + pprandom->nextInt(16) + 8;
|
||||
int fy = 40 + pprandom->nextInt(10);
|
||||
int fz = zo + pprandom->nextInt(16) + 8;
|
||||
FossilFeature fossil;
|
||||
fossil.place(level, pprandom, fx, fy, fz);
|
||||
}
|
||||
|
||||
if (pprandom->nextInt(48) == 0)
|
||||
{
|
||||
int ix = xo + pprandom->nextInt(16) + 8;
|
||||
int iy = level->maxBuildHeight;
|
||||
int iz = zo + pprandom->nextInt(16) + 8;
|
||||
IglooFeature igloo;
|
||||
igloo.place(level, pprandom, ix, iy, iz);
|
||||
}
|
||||
|
||||
PIXBeginNamedEvent(0,"Biome decorate");
|
||||
biome->decorate(level, pprandom, xo, zo);
|
||||
PIXEndNamedEvent();
|
||||
|
||||
@@ -517,6 +517,58 @@ void Recipes::_compileRecipes()
|
||||
L'#', Tile::snow,
|
||||
L'S');
|
||||
|
||||
addShapedRecipy(new ItemInstance(Tile::red_nether_brick, 1), //
|
||||
L"sscicig",
|
||||
L"WB", //
|
||||
L"BW", //
|
||||
|
||||
L'W', Item::netherwart_seeds, L'B', new ItemInstance(Item::nether_brick_Id, 1, 0),
|
||||
L'S');
|
||||
|
||||
addShapedRecipy(new ItemInstance(Tile::end_bricks, 4), //
|
||||
L"ssctg",
|
||||
L"##", //
|
||||
L"##", //
|
||||
|
||||
L'#', Tile::endStone,
|
||||
L'S');
|
||||
|
||||
addShapedRecipy(new ItemInstance(Tile::nether_wart_block, 1), //
|
||||
L"ssscig",
|
||||
L"###", //
|
||||
L"###", //
|
||||
L"###", //
|
||||
|
||||
L'#', Item::netherwart_seeds,
|
||||
L'D');
|
||||
|
||||
addShapedRecipy(new ItemInstance((Tile*)Tile::magma, 1), //
|
||||
L"sscig",
|
||||
L"##", //
|
||||
L"##", //
|
||||
|
||||
L'#', Item::magma_cream,
|
||||
L'D');
|
||||
|
||||
addShapedRecipy(new ItemInstance(Tile::slimeBlock, 1), //
|
||||
L"ssscig",
|
||||
L"###", //
|
||||
L"###", //
|
||||
L"###", //
|
||||
|
||||
L'#', Item::slime_ball,
|
||||
L'D');
|
||||
|
||||
addShapedRecipy(new ItemInstance(Item::slime_ball, 9), //
|
||||
L"sctg",
|
||||
L"#", //
|
||||
|
||||
L'#', Tile::slimeBlock,
|
||||
L'D');
|
||||
|
||||
|
||||
|
||||
|
||||
addShapedRecipy(new ItemInstance(Tile::clay, 1), //
|
||||
L"sscig",
|
||||
L"##", //
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "net.minecraft.world.item.h"
|
||||
#include "net.minecraft.world.level.tile.h"
|
||||
#include "DyePowderItem.h"
|
||||
#include "Recipy.h"
|
||||
#include "Recipes.h"
|
||||
#include "StructureRecipies.h"
|
||||
@@ -16,6 +17,20 @@ void StructureRecipies::addRecipes(Recipes *r)
|
||||
L'S');
|
||||
|
||||
|
||||
r->addShapedRecipy(new ItemInstance((Tile*)Tile::bone_block, 1), //
|
||||
L"sssczg",
|
||||
L"###", //
|
||||
L"###", //
|
||||
L"###", //
|
||||
|
||||
L'#', new ItemInstance(Item::dye, 1, DyePowderItem::WHITE),
|
||||
L'S');
|
||||
|
||||
r->addShapelessRecipy(new ItemInstance(Item::dye, 9, DyePowderItem::WHITE), //
|
||||
L"tg",
|
||||
(Tile*)Tile::bone_block,
|
||||
L'D');
|
||||
|
||||
r->addShapedRecipy(new ItemInstance(Tile::sandStone, 4, SandStoneTile::TYPE_SMOOTHSIDE), //
|
||||
L"ssczg",
|
||||
L"##", //
|
||||
|
||||
@@ -111,6 +111,7 @@ void ThrownPotion::onHit(HitResult *res)
|
||||
for(auto& effect : *mobEffects)
|
||||
{
|
||||
int id = effect->getId();
|
||||
if (id < 0 || id >= MobEffect::NUM_EFFECTS || !MobEffect::effects[id]) continue;
|
||||
if (MobEffect::effects[id]->isInstantenous())
|
||||
{
|
||||
MobEffect::effects[id]->applyInstantenousEffect(getOwner(), e, effect->getAmplifier(), scale);
|
||||
|
||||
@@ -576,7 +576,7 @@ void Tile::staticCtor()
|
||||
Tile::log2 = (new TreeTile2(162))->setDestroyTime(2.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"log")->setDescriptionId(IDS_TILE_LOG)->sendTileData()->setUseDescriptionId(IDS_DESC_LOG);
|
||||
Tile::woodStairsAcacia = (new StairTile(163, Tile::wood, TreeTile::ACACIA_TRUNK))->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, Item::eMaterial_acaciawood)->setIconName(L"stairsWoodAcacia")->setDescriptionId(IDS_TILE_STAIRS_ACACIAWOOD)->sendTileData()->setUseDescriptionId(IDS_DESC_STAIRS);
|
||||
Tile::woodStairsDark = (new StairTile(164, Tile::wood, TreeTile::DARK_TRUNK))->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, Item::eMaterial_darkwood)->setIconName(L"stairsWoodDark")->setDescriptionId(IDS_TILE_STAIRS_DARKWOOD)->sendTileData()->setUseDescriptionId(IDS_DESC_STAIRS);
|
||||
Tile::slimeBlock = (new SlimeTile(165))->setSoundType(SOUND_SLIME)->setIconName(L"slime")->setDescriptionId(IDS_TILE_SLIME_BLOCK)->setUseDescriptionId(IDS_DESC_SLIME_BLOCK)->disableMipmap();
|
||||
Tile::slimeBlock = (new SlimeTile(165))->setBaseItemTypeAndMaterial(Item::eBaseItemType_block, Item::eMaterial_slime)->setSoundType(SOUND_SLIME)->setIconName(L"slime")->setDescriptionId(IDS_TILE_SLIME_BLOCK)->setUseDescriptionId(IDS_DESC_SLIME_BLOCK)->disableMipmap();
|
||||
Tile::barrier = (new BarrierTile(166, Material::stone, false)) ->setIndestructible()->setExplodeable(6000000)->setSoundType(Tile::SOUND_STONE)->setIconName(L"barrier")->setDescriptionId(IDS_TILE_BARRIER)->setNotCollectStatistics()->setUseDescriptionId(IDS_DESC_BARRIER);
|
||||
Tile::iron_trapdoor = (new TrapDoorTile(167, Material::metal))->setBaseItemTypeAndMaterial(Item::eBaseItemType_door, Item::eMaterial_trap)->setDestroyTime(5.0f)->setSoundType(Tile::SOUND_METAL)->setIconName(L"iron_trapdoor")->setDescriptionId(IDS_TILE_IRON_TRAPDOOR)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_TRAPDOOR);
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ void TileEntity::staticCtor()
|
||||
TileEntity::setId(HopperTileEntity::create, eTYPE_HOPPERTILEENTITY, L"Hopper");
|
||||
TileEntity::setId(ComparatorTileEntity::create, eTYPE_COMPARATORTILEENTITY, L"Comparator");
|
||||
TileEntity::setId(BannerTileEntity::create, eTYPE_BANNERTILEENTITY, L"Banner");
|
||||
TileEntity::setId(FlowerPotTileEntity::create, eTYPE_FLOWERPOTTILEENTITY, L"FlowerPot");
|
||||
}
|
||||
|
||||
void TileEntity::setId(tileEntityCreateFn createFn, eINSTANCEOF clas, wstring id)
|
||||
|
||||
@@ -13,6 +13,7 @@ public:
|
||||
static const int TYPE_BEACON = 3;
|
||||
static const int TYPE_SKULL = 4;
|
||||
static const int TYPE_BANNER = 5;
|
||||
static const int TYPE_FLOWER_POT = 6;
|
||||
|
||||
int x, y, z;
|
||||
int type;
|
||||
|
||||
@@ -14,6 +14,10 @@ void VillageFeature::staticCtor()
|
||||
{
|
||||
allowedBiomes.push_back( Biome::plains );
|
||||
allowedBiomes.push_back( Biome::desert );
|
||||
allowedBiomes.push_back( Biome::savanna );
|
||||
allowedBiomes.push_back( Biome::savannaPlateau );
|
||||
allowedBiomes.push_back( Biome::savannaM );
|
||||
allowedBiomes.push_back( Biome::savannaPlateauM );
|
||||
}
|
||||
|
||||
void VillageFeature::_init(int iXZSize)
|
||||
|
||||
@@ -268,6 +268,7 @@ VillagePieces::VillagePiece::VillagePiece()
|
||||
heightPosition = -1;
|
||||
spawnedVillagerCount = 0;
|
||||
isDesertVillage = false;
|
||||
isAcaciaVillage = false;
|
||||
startPiece = nullptr;
|
||||
// for reflection
|
||||
}
|
||||
@@ -276,11 +277,13 @@ VillagePieces::VillagePiece::VillagePiece(StartPiece *startPiece, int genDepth)
|
||||
{
|
||||
heightPosition = -1;
|
||||
isDesertVillage = false;
|
||||
isAcaciaVillage = false;
|
||||
spawnedVillagerCount = 0;
|
||||
this->startPiece = startPiece;
|
||||
if (startPiece != nullptr)
|
||||
{
|
||||
this->isDesertVillage = startPiece->isDesertVillage;
|
||||
this->isAcaciaVillage = startPiece->isAcaciaVillage;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,6 +292,7 @@ void VillagePieces::VillagePiece::addAdditonalSaveData(CompoundTag *tag)
|
||||
tag->putInt(L"HPos", heightPosition);
|
||||
tag->putInt(L"VCount", spawnedVillagerCount);
|
||||
tag->putBoolean(L"Desert", isDesertVillage);
|
||||
tag->putBoolean(L"Acacia", isAcaciaVillage);
|
||||
}
|
||||
|
||||
void VillagePieces::VillagePiece::readAdditonalSaveData(CompoundTag *tag)
|
||||
@@ -296,6 +300,7 @@ void VillagePieces::VillagePiece::readAdditonalSaveData(CompoundTag *tag)
|
||||
heightPosition = tag->getInt(L"HPos");
|
||||
spawnedVillagerCount = tag->getInt(L"VCount");
|
||||
isDesertVillage = tag->getBoolean(L"Desert");
|
||||
isAcaciaVillage = tag->getBoolean(L"Acacia");
|
||||
}
|
||||
|
||||
StructurePiece *VillagePieces::VillagePiece::generateHouseNorthernLeft(StartPiece *startPiece, list<StructurePiece *> *pieces, Random *random, int yOff, int zOff)
|
||||
@@ -413,29 +418,30 @@ int VillagePieces::VillagePiece::biomeBlock(int tile, int data)
|
||||
if (isDesertVillage)
|
||||
{
|
||||
if (tile == Tile::log_Id)
|
||||
{
|
||||
return Tile::sandstone_Id;
|
||||
}
|
||||
else if (tile == Tile::cobblestone_Id)
|
||||
{
|
||||
return Tile::sandstone_Id;
|
||||
}
|
||||
else if (tile == Tile::planks_Id)
|
||||
{
|
||||
return Tile::sandstone_Id;
|
||||
}
|
||||
else if (tile == Tile::oak_stairs_Id)
|
||||
{
|
||||
return Tile::sandstone_stairs_Id;
|
||||
}
|
||||
else if (tile == Tile::stone_stairs_Id)
|
||||
{
|
||||
return Tile::sandstone_stairs_Id;
|
||||
}
|
||||
else if (tile == Tile::gravel_Id)
|
||||
{
|
||||
return Tile::sandstone_Id;
|
||||
}
|
||||
}
|
||||
else if (isAcaciaVillage)
|
||||
{
|
||||
if (tile == Tile::log_Id)
|
||||
return Tile::log2_Id;
|
||||
else if (tile == Tile::planks_Id)
|
||||
return Tile::planks_Id;
|
||||
else if (tile == Tile::oak_stairs_Id)
|
||||
return Tile::acacia_stairs_Id;
|
||||
else if (tile == Tile::fence_Id)
|
||||
return Tile::acacia_fence_Id;
|
||||
else if (tile == Tile::fence_gate_Id)
|
||||
return Tile::acacia_fence_gate_Id;
|
||||
}
|
||||
return tile;
|
||||
}
|
||||
@@ -445,17 +451,18 @@ int VillagePieces::VillagePiece::biomeData(int tile, int data)
|
||||
if (isDesertVillage)
|
||||
{
|
||||
if (tile == Tile::log_Id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (tile == Tile::cobblestone_Id)
|
||||
{
|
||||
return SandStoneTile::TYPE_DEFAULT;
|
||||
}
|
||||
else if (tile == Tile::planks_Id)
|
||||
{
|
||||
return SandStoneTile::TYPE_SMOOTHSIDE;
|
||||
}
|
||||
}
|
||||
else if (isAcaciaVillage)
|
||||
{
|
||||
if (tile == Tile::log_Id)
|
||||
return (data & 0xC) | 0;
|
||||
else if (tile == Tile::planks_Id)
|
||||
return 4;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
@@ -580,6 +587,8 @@ VillagePieces::StartPiece::StartPiece(BiomeSource *biomeSource, int genDepth, Ra
|
||||
|
||||
Biome *biome = biomeSource->getBiome(west, north);
|
||||
isDesertVillage = biome == Biome::desert || biome == Biome::desertHills;
|
||||
isAcaciaVillage = biome == Biome::savanna || biome == Biome::savannaPlateau ||
|
||||
biome == Biome::savannaM || biome == Biome::savannaPlateauM;
|
||||
}
|
||||
|
||||
VillagePieces::StartPiece::~StartPiece()
|
||||
@@ -718,8 +727,21 @@ bool VillagePieces::StraightRoad::postProcess(Level *level, Random *random, Boun
|
||||
if (chunkBB->isInside(x, 64, z))
|
||||
{
|
||||
int y = level->getTopSolidBlock(x, z) - 1;
|
||||
level->setTileAndData(x, y, z, roadTile, 0, Tile::UPDATE_CLIENTS);
|
||||
// level->setTileAndData(x, y - 1, z, baseTile, 0, Tile::UPDATE_CLIENTS);
|
||||
int tileAtY = level->getTile(x, y, z);
|
||||
if (tileAtY == Tile::water_Id || tileAtY == Tile::flowing_water_Id)
|
||||
{
|
||||
level->setTileAndData(x, y, z, Tile::planks_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
int fill = y - 1;
|
||||
while (fill >= 0 && (level->getTile(x, fill, z) == Tile::water_Id || level->getTile(x, fill, z) == Tile::flowing_water_Id))
|
||||
{
|
||||
level->setTileAndData(x, fill, z, Tile::planks_Id, 0, Tile::UPDATE_CLIENTS);
|
||||
fill--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
level->setTileAndData(x, y, z, roadTile, 0, Tile::UPDATE_CLIENTS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ private:
|
||||
private:
|
||||
int spawnedVillagerCount;
|
||||
bool isDesertVillage;
|
||||
bool isAcaciaVillage;
|
||||
protected:
|
||||
StartPiece *startPiece;
|
||||
|
||||
@@ -124,6 +125,7 @@ public:
|
||||
// these fields are only used in generation step and aren't serialized :{
|
||||
BiomeSource *biomeSource;
|
||||
bool isDesertVillage;
|
||||
bool isAcaciaVillage;
|
||||
|
||||
int villageSize;
|
||||
bool isLibraryAdded;
|
||||
|
||||
@@ -1500,6 +1500,10 @@ set(_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/EndPodiumFeature.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/Feature.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/Feature.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/FossilFeature.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/FossilFeature.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/IglooFeature.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/IglooFeature.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/FlowerFeature.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/FlowerFeature.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/GroundBushFeature.cpp"
|
||||
@@ -1866,6 +1870,8 @@ set(_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_LEVEL_TILE
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/FireTile.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/FlowerPotTile.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/FlowerPotTile.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/FlowerPotTileEntity.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/FlowerPotTileEntity.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/FurnaceTile.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/FurnaceTile.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/GlassTile.cpp"
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
#include "RoofTreeFeature.h"
|
||||
|
||||
#include "DesertWellFeature.h"
|
||||
#include "FossilFeature.h"
|
||||
#include "IglooFeature.h"
|
||||
#include "MegaTreeFeature.h"
|
||||
#include "VinesFeature.h"
|
||||
#include "GroundBushFeature.h"
|
||||
|
||||
@@ -22,3 +22,4 @@
|
||||
#include "EnderChestTileEntity.h"
|
||||
#include "ItemFrame.h"
|
||||
#include "BannerTileEntity.h"
|
||||
#include "FlowerPotTileEntity.h"
|
||||
|
||||
Reference in New Issue
Block a user