the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 486 lines 14 kB view raw
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