the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
1#include "stdafx.h"
2//#include "..\Minecraft.World\JavaMath.h"
3#include "MultiplayerLocalPlayer.h"
4#include "ClientConnection.h"
5#include "..\Minecraft.World\net.minecraft.world.level.h"
6#include "..\Minecraft.World\net.minecraft.network.h"
7#include "..\Minecraft.World\Mth.h"
8#include "..\Minecraft.World\AABB.h"
9#include "..\Minecraft.World\net.minecraft.stats.h"
10#include "..\Minecraft.World\net.minecraft.world.inventory.h"
11#include "..\Minecraft.World\net.minecraft.world.level.dimension.h"
12#include "..\Minecraft.World\net.minecraft.world.effect.h"
13#include "..\Minecraft.World\LevelData.h"
14#include "..\Minecraft.World\net.minecraft.world.entity.item.h"
15#include "Input.h"
16#include "LevelRenderer.h"
17
18// 4J added for testing
19#ifdef STRESS_TEST_MOVE
20volatile bool stressTestEnabled = true;
21#endif
22
23MultiplayerLocalPlayer::MultiplayerLocalPlayer(Minecraft *minecraft, Level *level, User *user, ClientConnection *connection) : LocalPlayer(minecraft, level, user, level->dimension->id)
24{
25 // 4J - added initialisers
26 flashOnSetHealth = false;
27 xLast = yLast1 = yLast2 = zLast = 0;
28 yRotLast = xRotLast = 0;
29 lastOnGround = false;
30 lastSneaked = false;
31 lastIdle = false;
32 lastSprinting = false;
33 positionReminder = 0;
34
35 this->connection = connection;
36}
37
38bool MultiplayerLocalPlayer::hurt(DamageSource *source, float dmg)
39{
40 return false;
41}
42
43void MultiplayerLocalPlayer::heal(float heal)
44{
45}
46
47void MultiplayerLocalPlayer::tick()
48{
49 // 4J Added
50 // 4J-PB - changing this to a game host option ot hide gamertags
51 //bool bIsisPrimaryHost=g_NetworkManager.IsHost() && (ProfileManager.GetPrimaryPad()==m_iPad);
52
53 /*if((app.GetGameSettings(m_iPad,eGameSetting_PlayerVisibleInMap)!=0) != m_bShownOnMaps)
54 {
55 m_bShownOnMaps = (app.GetGameSettings(m_iPad,eGameSetting_PlayerVisibleInMap)!=0);
56 if (m_bShownOnMaps) connection->send( shared_ptr<PlayerCommandPacket>( new PlayerCommandPacket(shared_from_this(), PlayerCommandPacket::SHOW_ON_MAPS) ) );
57 else connection->send( shared_ptr<PlayerCommandPacket>( new PlayerCommandPacket(shared_from_this(), PlayerCommandPacket::HIDE_ON_MAPS) ) );
58 }*/
59
60 if (!level->hasChunkAt(Mth::floor(x), 0, Mth::floor(z))) return;
61
62 double tempX = x, tempY = y, tempZ = z;
63
64 LocalPlayer::tick();
65
66 // 4J added for testing
67#ifdef STRESS_TEST_MOVE
68 if(stressTestEnabled)
69 {
70 StressTestMove(&tempX,&tempY,&tempZ);
71 }
72#endif
73
74 //if( !minecraft->localgameModes[m_iPad]->isTutorial() || minecraft->localgameModes[m_iPad]->getTutorial()->canMoveToPosition(tempX, tempY, tempZ, x, y, z) )
75 if(minecraft->localgameModes[m_iPad]->getTutorial()->canMoveToPosition(tempX, tempY, tempZ, x, y, z))
76 {
77 if (isRiding())
78 {
79 connection->send(shared_ptr<MovePlayerPacket>(new MovePlayerPacket::Rot(yRot, xRot, onGround, abilities.flying)));
80 connection->send(shared_ptr<PlayerInputPacket>(new PlayerInputPacket(xxa, yya, input->jumping, input->sneaking)));
81 }
82 else
83 {
84 sendPosition();
85 }
86 }
87 else
88 {
89 //app.Debugprintf("Cannot move to position (%f, %f, %f), falling back to (%f, %f, %f)\n", x, y, z, tempX, y, tempZ);
90 this->setPos(tempX, y, tempZ);
91 }
92}
93
94void MultiplayerLocalPlayer::sendPosition()
95{
96 bool sprinting = isSprinting();
97 if (sprinting != lastSprinting)
98 {
99 if (sprinting) connection->send(shared_ptr<PlayerCommandPacket>( new PlayerCommandPacket(shared_from_this(), PlayerCommandPacket::START_SPRINTING)));
100 else connection->send(shared_ptr<PlayerCommandPacket>( new PlayerCommandPacket(shared_from_this(), PlayerCommandPacket::STOP_SPRINTING)));
101
102 lastSprinting = sprinting;
103 }
104
105 bool sneaking = isSneaking();
106 if (sneaking != lastSneaked)
107 {
108 if (sneaking) connection->send( shared_ptr<PlayerCommandPacket>( new PlayerCommandPacket(shared_from_this(), PlayerCommandPacket::START_SNEAKING) ) );
109 else connection->send( shared_ptr<PlayerCommandPacket>( new PlayerCommandPacket(shared_from_this(), PlayerCommandPacket::STOP_SNEAKING) ) );
110
111 lastSneaked = sneaking;
112 }
113
114 bool idle = isIdle();
115 if (idle != lastIdle)
116 {
117 if (idle) connection->send( shared_ptr<PlayerCommandPacket>( new PlayerCommandPacket(shared_from_this(), PlayerCommandPacket::START_IDLEANIM) ) );
118 else connection->send( shared_ptr<PlayerCommandPacket>( new PlayerCommandPacket(shared_from_this(), PlayerCommandPacket::STOP_IDLEANIM) ) );
119
120 lastIdle = idle;
121 }
122
123 double xdd = x - xLast;
124 double ydd1 = bb->y0 - yLast1;
125 double zdd = z - zLast;
126
127 double rydd = yRot - yRotLast;
128 double rxdd = xRot - xRotLast;
129
130 bool move = (xdd * xdd + ydd1 * ydd1 + zdd * zdd) > 0.03 * 0.03 || positionReminder >= POSITION_REMINDER_INTERVAL;
131 bool rot = rydd != 0 || rxdd != 0;
132 if (riding != NULL)
133 {
134 connection->send( shared_ptr<MovePlayerPacket>( new MovePlayerPacket::PosRot(xd, -999, -999, zd, yRot, xRot, onGround, abilities.flying) ) );
135 move = false;
136 }
137 else
138 {
139 if (move && rot)
140 {
141 connection->send( shared_ptr<MovePlayerPacket>( new MovePlayerPacket::PosRot(x, bb->y0, y, z, yRot, xRot, onGround, abilities.flying) ) );
142 }
143 else if (move)
144 {
145 connection->send( shared_ptr<MovePlayerPacket>( new MovePlayerPacket::Pos(x, bb->y0, y, z, onGround, abilities.flying) ) );
146 }
147 else if (rot)
148 {
149 connection->send( shared_ptr<MovePlayerPacket>( new MovePlayerPacket::Rot(yRot, xRot, onGround, abilities.flying) ) );
150 }
151 else
152 {
153 connection->send( shared_ptr<MovePlayerPacket>( new MovePlayerPacket(onGround, abilities.flying) ) );
154 }
155 }
156
157 positionReminder++;
158 lastOnGround = onGround;
159
160 if (move)
161 {
162 xLast = x;
163 yLast1 = bb->y0;
164 yLast2 = y;
165 zLast = z;
166 positionReminder = 0;
167 }
168 if (rot)
169 {
170 yRotLast = yRot;
171 xRotLast = xRot;
172 }
173
174}
175
176shared_ptr<ItemEntity> MultiplayerLocalPlayer::drop()
177{
178 connection->send( shared_ptr<PlayerActionPacket>( new PlayerActionPacket(PlayerActionPacket::DROP_ITEM, 0, 0, 0, 0) ) );
179 return nullptr;
180}
181
182void MultiplayerLocalPlayer::reallyDrop(shared_ptr<ItemEntity> itemEntity)
183{
184}
185
186void MultiplayerLocalPlayer::chat(const wstring& message)
187{
188 connection->send( shared_ptr<ChatPacket>( new ChatPacket(message) ) );
189}
190
191void MultiplayerLocalPlayer::swing()
192{
193 LocalPlayer::swing();
194 connection->send( shared_ptr<AnimatePacket>( new AnimatePacket(shared_from_this(), AnimatePacket::SWING) ) );
195
196}
197
198void MultiplayerLocalPlayer::respawn()
199{
200 connection->send( shared_ptr<ClientCommandPacket>( new ClientCommandPacket(ClientCommandPacket::PERFORM_RESPAWN)));
201}
202
203
204void MultiplayerLocalPlayer::actuallyHurt(DamageSource *source, float dmg)
205{
206 if (isInvulnerable()) return;
207 setHealth(getHealth() - dmg);
208}
209
210// 4J Added override to capture event for tutorial messages
211void MultiplayerLocalPlayer::completeUsingItem()
212{
213 Minecraft *pMinecraft = Minecraft::GetInstance();
214 if(useItem != NULL && pMinecraft->localgameModes[m_iPad] != NULL )
215 {
216 TutorialMode *gameMode = (TutorialMode *)pMinecraft->localgameModes[m_iPad];
217 Tutorial *tutorial = gameMode->getTutorial();
218 tutorial->completeUsingItem(useItem);
219 }
220 Player::completeUsingItem();
221}
222
223void MultiplayerLocalPlayer::onEffectAdded(MobEffectInstance *effect)
224{
225 Minecraft *pMinecraft = Minecraft::GetInstance();
226 if(pMinecraft->localgameModes[m_iPad] != NULL )
227 {
228 TutorialMode *gameMode = (TutorialMode *)pMinecraft->localgameModes[m_iPad];
229 Tutorial *tutorial = gameMode->getTutorial();
230 tutorial->onEffectChanged(MobEffect::effects[effect->getId()]);
231 }
232 Player::onEffectAdded(effect);
233}
234
235
236void MultiplayerLocalPlayer::onEffectUpdated(MobEffectInstance *effect, bool doRefreshAttributes)
237{
238 Minecraft *pMinecraft = Minecraft::GetInstance();
239 if(pMinecraft->localgameModes[m_iPad] != NULL )
240 {
241 TutorialMode *gameMode = (TutorialMode *)pMinecraft->localgameModes[m_iPad];
242 Tutorial *tutorial = gameMode->getTutorial();
243 tutorial->onEffectChanged(MobEffect::effects[effect->getId()]);
244 }
245 Player::onEffectUpdated(effect, doRefreshAttributes);
246}
247
248
249void MultiplayerLocalPlayer::onEffectRemoved(MobEffectInstance *effect)
250{
251 Minecraft *pMinecraft = Minecraft::GetInstance();
252 if(pMinecraft->localgameModes[m_iPad] != NULL )
253 {
254 TutorialMode *gameMode = (TutorialMode *)pMinecraft->localgameModes[m_iPad];
255 Tutorial *tutorial = gameMode->getTutorial();
256 tutorial->onEffectChanged(MobEffect::effects[effect->getId()],true);
257 }
258 Player::onEffectRemoved(effect);
259}
260
261void MultiplayerLocalPlayer::closeContainer()
262{
263 connection->send( shared_ptr<ContainerClosePacket>( new ContainerClosePacket(containerMenu->containerId) ) );
264 clientSideCloseContainer();
265}
266
267// close the container without sending a packet to the server
268void MultiplayerLocalPlayer::clientSideCloseContainer()
269{
270 inventory->setCarried(nullptr);
271 LocalPlayer::closeContainer();
272}
273
274void MultiplayerLocalPlayer::hurtTo(float newHealth, ETelemetryChallenges damageSource)
275{
276 if (flashOnSetHealth)
277 {
278 LocalPlayer::hurtTo(newHealth, damageSource);
279 }
280 else
281 {
282 setHealth(newHealth);
283 flashOnSetHealth = true;
284 }
285}
286
287void MultiplayerLocalPlayer::awardStat(Stat *stat, byteArray param)
288{
289 if (stat == NULL)
290 {
291 delete [] param.data;
292 return;
293 }
294
295 if (stat->awardLocallyOnly)
296 {
297 LocalPlayer::awardStat(stat, param);
298 }
299 else
300 {
301 delete [] param.data;
302 return;
303 }
304}
305
306void MultiplayerLocalPlayer::awardStatFromServer(Stat *stat, byteArray param)
307{
308 if ( stat != NULL && !stat->awardLocallyOnly )
309 {
310 LocalPlayer::awardStat(stat, param);
311 }
312 else delete [] param.data;
313}
314
315void MultiplayerLocalPlayer::onUpdateAbilities()
316{
317 connection->send(shared_ptr<PlayerAbilitiesPacket>(new PlayerAbilitiesPacket(&abilities)));
318}
319
320bool MultiplayerLocalPlayer::isLocalPlayer()
321{
322 return true;
323}
324
325void MultiplayerLocalPlayer::sendRidingJump()
326{
327 connection->send(shared_ptr<PlayerCommandPacket>(new PlayerCommandPacket(shared_from_this(), PlayerCommandPacket::RIDING_JUMP, (int) (getJumpRidingScale() * 100.0f))));
328}
329
330void MultiplayerLocalPlayer::sendOpenInventory()
331{
332 connection->send(shared_ptr<PlayerCommandPacket>(new PlayerCommandPacket(shared_from_this(), PlayerCommandPacket::OPEN_INVENTORY)));
333}
334
335void MultiplayerLocalPlayer::ride(shared_ptr<Entity> e)
336{
337 bool wasRiding = riding != NULL;
338 LocalPlayer::ride(e);
339 bool isRiding = riding != NULL;
340
341 // 4J Added
342 if(wasRiding && !isRiding)
343 {
344 setSneaking(false);
345 input->sneaking = false;
346 }
347
348 if( isRiding )
349 {
350 ETelemetryChallenges eventType = eTelemetryChallenges_Unknown;
351 if( this->riding != NULL )
352 {
353 switch(riding->GetType())
354 {
355 case eTYPE_BOAT:
356 eventType = eTelemetryInGame_Ride_Boat;
357 break;
358 case eTYPE_MINECART:
359 eventType = eTelemetryInGame_Ride_Minecart;
360 break;
361 case eTYPE_PIG:
362 eventType = eTelemetryInGame_Ride_Pig;
363 break;
364 };
365 }
366 TelemetryManager->RecordEnemyKilledOrOvercome(GetXboxPad(), 0, y, 0, 0, 0, 0, eventType);
367 }
368
369 updateRichPresence();
370
371 Minecraft *pMinecraft = Minecraft::GetInstance();
372
373 if( pMinecraft->localgameModes[m_iPad] != NULL )
374 {
375 TutorialMode *gameMode = (TutorialMode *)pMinecraft->localgameModes[m_iPad];
376 if(wasRiding && !isRiding)
377 {
378 gameMode->getTutorial()->changeTutorialState(e_Tutorial_State_Gameplay);
379 }
380 else if (!wasRiding && isRiding)
381 {
382 gameMode->getTutorial()->onRideEntity(e);
383 }
384 }
385}
386
387void MultiplayerLocalPlayer::StopSleeping()
388{
389 connection->send( shared_ptr<PlayerCommandPacket>( new PlayerCommandPacket(shared_from_this(), PlayerCommandPacket::STOP_SLEEPING) ) );
390}
391
392// 4J Added
393void MultiplayerLocalPlayer::setAndBroadcastCustomSkin(DWORD skinId)
394{
395 DWORD oldSkinIndex = getCustomSkin();
396 LocalPlayer::setCustomSkin(skinId);
397#ifndef _CONTENT_PACKAGE
398 wprintf(L"Skin for local player %ls has changed to %ls (%d)\n", name.c_str(), customTextureUrl.c_str(), getPlayerDefaultSkin() );
399#endif
400 if(getCustomSkin() != oldSkinIndex) connection->send( shared_ptr<TextureAndGeometryChangePacket>( new TextureAndGeometryChangePacket( shared_from_this(), app.GetPlayerSkinName(GetXboxPad()) ) ) );
401}
402
403void MultiplayerLocalPlayer::setAndBroadcastCustomCape(DWORD capeId)
404{
405 DWORD oldCapeIndex = getCustomCape();
406 LocalPlayer::setCustomCape(capeId);
407#ifndef _CONTENT_PACKAGE
408 wprintf(L"Cape for local player %ls has changed to %ls\n", name.c_str(), customTextureUrl2.c_str());
409#endif
410 if(getCustomCape() != oldCapeIndex) connection->send( shared_ptr<TextureChangePacket>( new TextureChangePacket( shared_from_this(), TextureChangePacket::e_TextureChange_Cape, app.GetPlayerCapeName(GetXboxPad()) ) ) );
411}
412
413// 4J added for testing. This moves the player in a repeated sequence of 2 modes:
414// Mode 0 - teleports to random location in the world, and waits for the number of chunks that are fully loaded/created to have setting for 2 seconds before changing to mode 1
415// Mode 1 - picks a random direction to move in for 200 ticks (~10 seconds), repeating for a total of 2000 ticks, before cycling back to mode 0
416// Whilst carrying out this movement pattern, this calls checkAllPresentChunks which checks the integrity of all currently loaded/created chunks round the player.
417#ifdef STRESS_TEST_MOVE
418void MultiplayerLocalPlayer::StressTestMove(double *tempX, double *tempY, double *tempZ)
419{
420 static volatile int64_t lastChangeTime = 0;
421 static volatile int64_t lastTeleportTime = 0;
422 static int lastCount = 0;
423 static int stressTestCount = 0;
424 const int dirChangeTickCount = 200;
425
426 int64_t currentTime = System::currentTimeMillis();
427
428 bool faultFound = false;
429 int count = Minecraft::GetInstance()->levelRenderer->checkAllPresentChunks(&faultFound);
430
431/*
432 if( faultFound )
433 {
434 app.DebugPrintf("Fault found\n");
435 stressTestEnabled = false;
436 }
437 */
438 if( count != lastCount )
439 {
440 lastChangeTime = currentTime;
441 lastCount = count;
442 }
443
444 static float angle = 30.0;
445 static float dx = cos(30.0);
446 static float dz = sin(30.0);
447
448#if 0
449 if( ( stressTestCount % dirChangeTickCount) == 0 )
450 {
451 int angledeg = rand() % 360;
452 angle = (((double)angledeg) / 360.0 ) * ( 2.0 * 3.141592654 );
453 dx = cos(angle);
454 dz = sin(angle);
455 }
456#endif
457
458 float nx = x + ( dx * 1.2 );
459 float nz = z + ( dz * 1.2 );
460 float ny = y;
461 if( ny < 140.0f ) ny += 0.5f;
462 if( nx > 2539.0 )
463 {
464 nx = 2539.0;
465 dx = -dx;
466 }
467 if( nz > 2539.0 )
468 {
469 nz = 2539.0;
470 dz = -dz;
471 }
472 if( nx < -2550.0 )
473 {
474 nx = -2550.0;
475 dx = -dx;
476 }
477
478 if( nz < -2550.0 )
479 {
480 nz = -2550.0;
481 dz = -dz;
482 }
483 absMoveTo(nx,ny,nz,yRot,xRot);
484 stressTestCount++;
485}
486#endif