the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at master 1588 lines 50 kB view raw
1#include "stdafx.h" 2#include "Gui.h" 3#include "ItemRenderer.h" 4#include "GameRenderer.h" 5#include "Options.h" 6#include "MultiplayerLocalPlayer.h" 7#include "Textures.h" 8#include "TextureAtlas.h" 9#include "GameMode.h" 10#include "Lighting.h" 11#include "ChatScreen.h" 12#include "MultiPlayerLevel.h" 13#include "..\Minecraft.World\JavaMath.h" 14#include "..\Minecraft.World\net.minecraft.world.entity.player.h" 15#include "..\Minecraft.World\net.minecraft.world.effect.h" 16#include "..\Minecraft.World\net.minecraft.world.food.h" 17#include "..\Minecraft.World\net.minecraft.world.item.h" 18#include "..\Minecraft.World\net.minecraft.world.level.h" 19#include "..\Minecraft.World\LevelData.h" 20#include "..\Minecraft.World\net.minecraft.world.level.tile.h" 21#include "..\Minecraft.World\System.h" 22#include "..\Minecraft.World\Language.h" 23#include "EntityRenderDispatcher.h" 24#include "..\Minecraft.World\Dimension.h" 25#include "..\Minecraft.World\net.minecraft.world.entity.boss.enderdragon.h" 26#include "EnderDragonRenderer.h" 27#include "..\Minecraft.World\net.minecraft.h" 28#include "..\Minecraft.World\net.minecraft.world.h" 29#include "..\Minecraft.World\LevelChunk.h" 30#include "..\Minecraft.World\Biome.h" 31 32ResourceLocation Gui::PUMPKIN_BLUR_LOCATION = ResourceLocation(TN__BLUR__MISC_PUMPKINBLUR); 33 34#define RENDER_HUD 0 35//#ifndef _XBOX 36//#undef RENDER_HUD 37//#define RENDER_HUD 1 38//#endif 39 40float Gui::currentGuiBlendFactor = 1.0f; // 4J added 41float Gui::currentGuiScaleFactor = 1.0f; // 4J added 42ItemRenderer *Gui::itemRenderer = new ItemRenderer(); 43 44Gui::Gui(Minecraft *minecraft) 45{ 46 // 4J - initialisers added 47 random = new Random(); 48 tickCount = 0; 49 overlayMessageTime = 0; 50 animateOverlayMessageColor = false; 51 progress = 0.0f; 52 tbr = 1.0f; 53 fAlphaIncrementPerCent=255.0f/100.0f; 54 55 this->minecraft = minecraft; 56 57 lastTickA = 0.0f; 58} 59 60void Gui::render(float a, bool mouseFree, int xMouse, int yMouse) 61{ 62 // 4J Stu - I have copied this code for XUI_BaseScene. If/when it gets changed it should be broken out 63 // 4J - altered to force full screen mode to 3X scaling, and any split screen modes to 2X scaling. This is so that the further scaling by 0.5 that 64 // happens in split screen modes results in a final scaling of 1 rather than 1.5. 65 int splitYOffset;// = 20; // This offset is applied when doing the 2X scaling above to move the gui out of the way of the tool tips 66 int guiScale;// = ( minecraft->player->m_iScreenSection == C4JRender::VIEWPORT_TYPE_FULLSCREEN ? 3 : 2 ); 67 int iPad=minecraft->player->GetXboxPad(); 68 int iWidthOffset=0,iHeightOffset=0; // used to get the interface looking right on a 2 player split screen game 69 70 // 4J-PB - selected the gui scale based on the slider settings 71 if(minecraft->player->m_iScreenSection == C4JRender::VIEWPORT_TYPE_FULLSCREEN) 72 { 73 guiScale=app.GetGameSettings(iPad,eGameSetting_UISize) + 2; 74 } 75 else 76 { 77 guiScale=app.GetGameSettings(iPad,eGameSetting_UISizeSplitscreen) + 2; 78 } 79 80 81 ScreenSizeCalculator ssc(minecraft->options, minecraft->width, minecraft->height, guiScale ); 82 int screenWidth = ssc.getWidth(); 83 int screenHeight = ssc.getHeight(); 84 int iSafezoneXHalf=0,iSafezoneYHalf=0,iSafezoneTopYHalf=0; 85 int iTooltipsYOffset=0; 86 int quickSelectWidth=182; 87 int quickSelectHeight=22; 88 float fScaleFactorWidth=1.0f,fScaleFactorHeight=1.0f; 89 bool bTwoPlayerSplitscreen=false; 90 currentGuiScaleFactor = (float) guiScale; // Keep static copy of scale so we know how gui coordinates map to physical pixels - this is also affected by the viewport 91 92 switch(guiScale) 93 { 94 case 3: 95 splitYOffset = 0; 96 break; 97 case 4: 98 splitYOffset = -5; 99 break; 100 default: // 2 101 splitYOffset = 10; 102 break; 103 } 104 105 // Check which screen section this player is in 106 switch(minecraft->player->m_iScreenSection) 107 { 108 case C4JRender::VIEWPORT_TYPE_FULLSCREEN: 109 // single player 110 iSafezoneXHalf = screenWidth/20; // 5% 111 iSafezoneYHalf = screenHeight/20; // 5% 112 iSafezoneTopYHalf = iSafezoneYHalf; 113 iTooltipsYOffset=40+splitYOffset; 114 break; 115 case C4JRender::VIEWPORT_TYPE_SPLIT_TOP: 116 iSafezoneXHalf = screenWidth/10; // 5% (need to treat the whole screen is 2x this screen) 117 iSafezoneYHalf = splitYOffset; 118 iSafezoneTopYHalf = screenHeight/10; 119 fScaleFactorWidth=0.5f; 120 iWidthOffset=(int)((float)screenWidth*(1.0f - fScaleFactorWidth)); 121 iTooltipsYOffset=44; 122 bTwoPlayerSplitscreen=true; 123 currentGuiScaleFactor *= 0.5f; 124 break; 125 case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM: 126 iSafezoneXHalf = screenWidth/10; // 5% (need to treat the whole screen is 2x this screen) 127 iSafezoneYHalf = splitYOffset + screenHeight/10;// 5% (need to treat the whole screen is 2x this screen) 128 iSafezoneTopYHalf = 0; 129 fScaleFactorWidth=0.5f; 130 iWidthOffset=(int)((float)screenWidth*(1.0f - fScaleFactorWidth)); 131 iTooltipsYOffset=44; 132 bTwoPlayerSplitscreen=true; 133 currentGuiScaleFactor *= 0.5f; 134 break; 135 case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT: 136 iSafezoneXHalf = screenWidth/10; // 5% (the whole screen is 2x this screen) 137 iSafezoneYHalf = splitYOffset + screenHeight/10;// 5% (need to treat the whole screen is 2x this screen) 138 iSafezoneTopYHalf = screenHeight/10; 139 fScaleFactorHeight=0.5f; 140 iHeightOffset=screenHeight; 141 iTooltipsYOffset=44; 142 bTwoPlayerSplitscreen=true; 143 currentGuiScaleFactor *= 0.5f; 144 break; 145 case C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT: 146 iSafezoneXHalf = 0; 147 iSafezoneYHalf = splitYOffset + screenHeight/10;// 5% (need to treat the whole screen is 2x this screen) 148 iSafezoneTopYHalf = splitYOffset + screenHeight/10; 149 fScaleFactorHeight=0.5f; 150 iHeightOffset=screenHeight; 151 iTooltipsYOffset=44; 152 bTwoPlayerSplitscreen=true; 153 currentGuiScaleFactor *= 0.5f; 154 break; 155 case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT: 156 iSafezoneXHalf = screenWidth/10; // 5% (the whole screen is 2x this screen) 157 iSafezoneYHalf = splitYOffset; 158 iSafezoneTopYHalf = screenHeight/10; 159 iTooltipsYOffset=44; 160 currentGuiScaleFactor *= 0.5f; 161 break; 162 case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT: 163 iSafezoneXHalf = 0; 164 iSafezoneYHalf = splitYOffset; // 5% 165 iSafezoneTopYHalf = screenHeight/10; 166 iTooltipsYOffset=44; 167 currentGuiScaleFactor *= 0.5f; 168 break; 169 case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT: 170 iSafezoneXHalf = screenWidth/10; // 5% (the whole screen is 2x this screen) 171 iSafezoneYHalf = splitYOffset + screenHeight/10; // 5% (the whole screen is 2x this screen) 172 iSafezoneTopYHalf = 0; 173 iTooltipsYOffset=44; 174 currentGuiScaleFactor *= 0.5f; 175 break; 176 case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT: 177 iSafezoneXHalf = 0; 178 iSafezoneYHalf = splitYOffset + screenHeight/10; // 5% (the whole screen is 2x this screen) 179 iSafezoneTopYHalf = 0; 180 iTooltipsYOffset=44; 181 currentGuiScaleFactor *= 0.5f; 182 break; 183 184 } 185 186 // 4J-PB - turn off the slot display if a xui menu is up, or if we're autosaving 187 bool bDisplayGui=!ui.GetMenuDisplayed(iPad) && !(app.GetXuiAction(iPad)==eAppAction_AutosaveSaveGameCapturedThumbnail); 188 189 // if tooltips are off, set the y offset to zero 190 if(app.GetGameSettings(iPad,eGameSetting_Tooltips)==0 && bDisplayGui) 191 { 192 switch(minecraft->player->m_iScreenSection) 193 { 194 case C4JRender::VIEWPORT_TYPE_FULLSCREEN: 195 iTooltipsYOffset=screenHeight/10; 196 break; 197 default: 198 //iTooltipsYOffset=screenHeight/10; 199 switch(guiScale) 200 { 201 case 3: 202 iTooltipsYOffset=28;//screenHeight/10; 203 break; 204 case 4: 205 iTooltipsYOffset=28;//screenHeight/10; 206 break; 207 default: // 2 208 iTooltipsYOffset=14;//screenHeight/10; 209 break; 210 } 211 break; 212 } 213 } 214 215 // 4J-PB - Turn off interface if eGameSetting_DisplayHUD is off - for screen shots/videos. 216 if ( app.GetGameSettings(iPad,eGameSetting_DisplayHUD)==0 ) 217 { 218 bDisplayGui = false; 219 } 220 221 Font *font = minecraft->font; 222 223 224 minecraft->gameRenderer->setupGuiScreen(guiScale); 225 226 227 228 glEnable(GL_BLEND); 229 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // 4J - added - this did actually get set in renderVignette but that code is currently commented out 230 231 if (Minecraft::useFancyGraphics()) 232 { 233 renderVignette(minecraft->player->getBrightness(a), screenWidth, screenHeight); 234 } 235 236 ///////////////////////////////////////////////////////////////////////////////////// 237 // Display the pumpkin screen effect 238 ///////////////////////////////////////////////////////////////////////////////////// 239 240 shared_ptr<ItemInstance> headGear = minecraft->player->inventory->getArmor(3); 241 242 // 4J-PB - changing this to be per player 243 //if (!minecraft->options->thirdPersonView && headGear != NULL && headGear->id == Tile::pumpkin_Id) renderPumpkin(screenWidth, screenHeight); 244 if ((minecraft->player->ThirdPersonView()==0) && headGear != NULL && headGear->id == Tile::pumpkin_Id) renderPumpkin(screenWidth, screenHeight); 245 if (!minecraft->player->hasEffect(MobEffect::confusion)) 246 { 247 float pt = minecraft->player->oPortalTime + (minecraft->player->portalTime - minecraft->player->oPortalTime) * a; 248 if (pt > 0) 249 { 250 renderTp(pt, screenWidth, screenHeight); 251 } 252 } 253 254 if (!minecraft->gameMode->isCutScene()) 255 { 256 if(bDisplayGui && bTwoPlayerSplitscreen) 257 { 258 // need to apply scale factors depending on the mode 259 glPushMatrix(); 260 glScalef(fScaleFactorWidth, fScaleFactorHeight, fScaleFactorWidth); 261 } 262#if RENDER_HUD 263 ///////////////////////////////////////////////////////////////////////////////////// 264 // Display the quick select background, the quick select selection, and the crosshair 265 ///////////////////////////////////////////////////////////////////////////////////// 266 267 glColor4f(1, 1, 1, 1); 268 269 // 4J - this is where to set the blend factor for gui things 270 // use the primary player's settings 271 unsigned char ucAlpha=app.GetGameSettings(ProfileManager.GetPrimaryPad(),eGameSetting_InterfaceOpacity); 272 273 // If the user has started to navigate their quickselect bar, ignore the alpha setting, and display at default value 274 float fVal=fAlphaIncrementPerCent*(float)ucAlpha; 275 if(ucAlpha<80) 276 { 277 // check if we have the timer running for the opacity 278 unsigned int uiOpacityTimer=app.GetOpacityTimer(iPad); 279 if(uiOpacityTimer!=0) 280 { 281 if(uiOpacityTimer<10) 282 { 283 float fStep=(80.0f-(float)ucAlpha)/10.0f; 284 fVal=fAlphaIncrementPerCent*(80.0f-((10.0f-(float)uiOpacityTimer)*fStep)); 285 } 286 else 287 { 288 fVal=fAlphaIncrementPerCent*80.0f; 289 } 290 } 291 else 292 { 293 fVal=fAlphaIncrementPerCent*(float)ucAlpha; 294 } 295 } 296 else 297 { 298 fVal=fAlphaIncrementPerCent*(float)ucAlpha; 299 } 300 301 RenderManager.StateSetBlendFactor(0xffffff |(((unsigned int)fVal)<<24)); 302 currentGuiBlendFactor = fVal / 255.0f; 303 // RenderManager.StateSetBlendFactor(0x40ffffff); 304 glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA); 305 306 blitOffset = -90; 307 308 ///////////////////////////////////////////////////////////////////////////////////// 309 // Display the quick select background, the quick select selection, and the crosshair 310 ///////////////////////////////////////////////////////////////////////////////////// 311 if(bDisplayGui) 312 { 313 MemSect(31); 314 minecraft->textures->bindTexture(TN_GUI_GUI); // 4J was L"/gui/gui.png" 315 MemSect(0); 316 317 shared_ptr<Inventory> inventory = minecraft->player->inventory; 318 if(bTwoPlayerSplitscreen) 319 { 320 // need to apply scale factors depending on the mode 321 322 // 4J Stu - Moved this push and scale further up as we still need to do it for the few HUD components not replaced by xui 323 //glPushMatrix(); 324 //glScalef(fScaleFactorWidth, fScaleFactorHeight, fScaleFactorWidth); 325 326 // 4J-PB - move into the safe zone, and account for 2 player splitscreen 327 blit(iWidthOffset + (screenWidth - quickSelectWidth)/2, iHeightOffset + screenHeight - iSafezoneYHalf - iTooltipsYOffset , 0, 0, 182, 22); 328 blit(iWidthOffset + (screenWidth - quickSelectWidth)/2 - 1 + inventory->selected * 20, iHeightOffset + screenHeight - iSafezoneYHalf - iTooltipsYOffset - 1, 0, 22, 24, 22); 329 } 330 else 331 { 332 blit(iWidthOffset + screenWidth / 2 - quickSelectWidth / 2, iHeightOffset + screenHeight - iSafezoneYHalf - iTooltipsYOffset , 0, 0, 182, 22); 333 blit(iWidthOffset + screenWidth / 2 - quickSelectWidth / 2 - 1 + inventory->selected * 20, iHeightOffset + screenHeight - iSafezoneYHalf - iTooltipsYOffset - 1, 0, 22, 24, 22); 334 } 335 336 337 MemSect(31); 338 minecraft->textures->bindTexture(TN_GUI_ICONS);//L"/gui/icons.png")); 339 MemSect(0); 340 glEnable(GL_BLEND); 341 RenderManager.StateSetBlendFactor(0xffffff |(((unsigned int)fVal)<<24)); 342 glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA); 343 //glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_COLOR); 344 // 4J Stu - We don't want to adjust the cursor by the safezone, we want it centred 345 if(bTwoPlayerSplitscreen) 346 { 347 blit(iWidthOffset + screenWidth / 2 - 7, (iHeightOffset + screenHeight) / 2 - 7, 0, 0, 16, 16); 348 } 349 else 350 { 351 blit(screenWidth / 2 - 7, screenHeight / 2 - 7, 0, 0, 16, 16); 352 } 353 glDisable(GL_BLEND); 354 355 // if(bTwoPlayerSplitscreen) 356 // { 357 // glPopMatrix(); 358 // } 359 360 } 361 362 bool blink = minecraft->player->invulnerableTime / 3 % 2 == 1; 363 if (minecraft->player->invulnerableTime < 10) blink = false; 364 int iHealth = minecraft->player->getHealth(); 365 int iLastHealth = minecraft->player->lastHealth; 366 random->setSeed(tickCount * 312871); 367 368 bool foodBlink = false; 369 FoodData *foodData = minecraft->player->getFoodData(); 370 int food = foodData->getFoodLevel(); 371 int oldFood = foodData->getLastFoodLevel(); 372 373// if (false) //(true) 374// { 375// renderBossHealth(); 376// } 377 378 ///////////////////////////////////////////////////////////////////////////////////// 379 // Display the experience, food, armour, health and the air bubbles 380 ///////////////////////////////////////////////////////////////////////////////////// 381 if(bDisplayGui) 382 { 383 // 4J - added blend for fading gui 384 glEnable(GL_BLEND); 385 glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA); 386 387 if (minecraft->gameMode->canHurtPlayer()) 388 { 389 int xLeft, xRight; 390 // 4J Stu - TODO Work out proper positioning for splitscreen 391 if(bTwoPlayerSplitscreen) 392 { 393 xLeft = iWidthOffset + (screenWidth - quickSelectWidth)/2; 394 xRight = iWidthOffset + (screenWidth + quickSelectWidth)/2; 395 } 396 else 397 { 398 xLeft = (screenWidth - quickSelectWidth)/2; 399 xRight = (screenWidth + quickSelectWidth) / 2; 400 } 401 402 // render experience bar 403 int xpNeededForNextLevel = minecraft->player->getXpNeededForNextLevel(); 404 if (xpNeededForNextLevel > 0) 405 { 406 int w = 182; 407 408 int progress = (int) (minecraft->player->experienceProgress * (float) (w + 1)); 409 410 int yo = screenHeight - iSafezoneYHalf - iTooltipsYOffset - 8; 411 if(bTwoPlayerSplitscreen) 412 { 413 yo+=iHeightOffset; 414 } 415 blit(xLeft, yo, 0, 64, w, 5); 416 if (progress > 0) 417 { 418 blit(xLeft, yo, 0, 69, progress, 5); 419 } 420 } 421 422 int yLine1, yLine2; 423 if(bTwoPlayerSplitscreen) 424 { 425 //yo = iHeightOffset + screenHeight - 10 - iSafezoneYHalf - iTooltipsYOffset; 426 yLine1 = iHeightOffset + screenHeight - 18 - iSafezoneYHalf - iTooltipsYOffset; 427 yLine2 = yLine1 - 10; 428 } 429 else 430 { 431 //yo = screenHeight - 10 - iSafezoneYHalf - iTooltipsYOffset; 432 yLine1 = screenHeight - 18 - iSafezoneYHalf - iTooltipsYOffset; 433 yLine2 = yLine1 - 10; 434 } 435 436 double maxHealth = minecraft->localplayers[iPad]->getAttribute(SharedMonsterAttributes.MAX_HEALTH); 437 438 double totalAbsorption = minecraft->localplayers[iPad]->getAbsorptionAmount(); 439 int numHealthRows = Mth.ceil((maxHealth + totalAbsorption) / 2 / (float) NUM_HEARTS_PER_ROW); 440 int healthRowHeight = Math.max(10 - (numHealthRows - 2), 3); 441 int yLine2 = yLine1 - (numHealthRows - 1) * healthRowHeight - 10; 442 absorption = totalAbsorption; 443 444 int armor = minecraft->player->getArmorValue(); 445 int heartOffsetIndex = -1; 446 if (minecraft->player->hasEffect(MobEffect::regeneration)) 447 { 448 heartOffsetIndex = tickCount % (int) ceil(maxHealth + 5); 449 } 450 451 // render health and armor 452 //minecraft.profiler.push("armor"); 453 for (int i = 0; i < Player::MAX_HEALTH / 2; i++) 454 { 455 if (armor > 0) 456 { 457 int xo = xLeft + i * 8; 458 if (i * 2 + 1 < armor) blit(xo, yLine2, 16 + 2 * 9, 9, 9, 9); 459 if (i * 2 + 1 == armor) blit(xo, yLine2, 16 + 1 * 9, 9, 9, 9); 460 if (i * 2 + 1 > armor) blit(xo, yLine2, 16 + 0 * 9, 9, 9, 9); 461 } 462 } 463 464 //minecraft.profiler.popPush("health"); 465 for (int i = Mth.ceil((maxHealth + totalAbsorption) / 2) - 1; i >= 0; i--) 466 { 467 int healthTexBaseX = 16; 468 if (minecraft.player.hasEffect(MobEffect.poison)) 469 { 470 healthTexBaseX += 4 * 9; 471 } 472 else if (minecraft.player.hasEffect(MobEffect.wither)) 473 { 474 healthTexBaseX += 8 * 9; 475 } 476 477 int bg = 0; 478 if (blink) bg = 1; 479 int rowIndex = Mth.ceil((i + 1) / (float) NUM_HEARTS_PER_ROW) - 1; 480 int xo = xLeft + (i % NUM_HEARTS_PER_ROW) * 8; 481 int yo = yLine1 - rowIndex * healthRowHeight; 482 if (currentHealth <= 4) 483 { 484 yo += random.nextInt(2); 485 } 486 487 if (i == heartOffsetIndex) 488 { 489 yo -= 2; 490 } 491 492 int y0 = 0; 493 494 // No hardcore on console 495 /*if (minecraft->level.getLevelData().isHardcore()) 496 { 497 y0 = 5; 498 }*/ 499 500 blit(xo, yo, 16 + bg * 9, 9 * y0, 9, 9); 501 if (blink) 502 { 503 if (i * 2 + 1 < oldHealth) blit(xo, yo, healthTexBaseX + 6 * 9, 9 * y0, 9, 9); 504 if (i * 2 + 1 == oldHealth) blit(xo, yo, healthTexBaseX + 7 * 9, 9 * y0, 9, 9); 505 } 506 507 if (absorption > 0) 508 { 509 if (absorption == totalAbsorption && totalAbsorption % 2 == 1) 510 { 511 blit(xo, yo, healthTexBaseX + 17 * 9, 9 * y0, 9, 9); 512 } 513 else 514 { 515 blit(xo, yo, healthTexBaseX + 16 * 9, 9 * y0, 9, 9); 516 } 517 absorption -= 2; 518 } 519 else 520 { 521 if (i * 2 + 1 < currentHealth) blit(xo, yo, healthTexBaseX + 4 * 9, 9 * y0, 9, 9); 522 if (i * 2 + 1 == currentHealth) blit(xo, yo, healthTexBaseX + 5 * 9, 9 * y0, 9, 9); 523 } 524 } 525 526 std::shared_ptr<Entity> riding = minecraft->localplayers[iPad].get()->riding; 527 std::shared_ptr<LivingEntity> living = dynamic_pointer_cast<LivingEntity>(riding); 528 if (riding == NULL) 529 { 530 // render food 531 for (int i = 0; i < FoodConstants::MAX_FOOD / 2; i++) 532 { 533 int yo = yLine1; 534 535 536 int texBaseX = 16; 537 int bg = 0; 538 if (minecraft->player->hasEffect(MobEffect::hunger)) 539 { 540 texBaseX += 4 * 9; 541 bg = 13; 542 } 543 544 if (minecraft->player->getFoodData()->getSaturationLevel() <= 0) 545 { 546 if ((tickCount % (food * 3 + 1)) == 0) 547 { 548 yo += random->nextInt(3) - 1; 549 } 550 } 551 552 if (foodBlink) bg = 1; 553 int xo = xRight - i * 8 - 9; 554 blit(xo, yo, 16 + bg * 9, 9 * 3, 9, 9); 555 if (foodBlink) 556 { 557 if (i * 2 + 1 < oldFood) blit(xo, yo, texBaseX + 6 * 9, 9 * 3, 9, 9); 558 if (i * 2 + 1 == oldFood) blit(xo, yo, texBaseX + 7 * 9, 9 * 3, 9, 9); 559 } 560 if (i * 2 + 1 < food) blit(xo, yo, texBaseX + 4 * 9, 9 * 3, 9, 9); 561 if (i * 2 + 1 == food) blit(xo, yo, texBaseX + 5 * 9, 9 * 3, 9, 9); 562 } 563 } 564 else if (living != nullptr) 565 { 566 // Render mount health 567 568 int riderCurrentHealth = (int) ceil(living.get()->GetHealth()); 569 float maxRiderHealth = living->GetMaxHealth(); 570 int hearts = (int) (maxRiderHealth + .5f) / 2; 571 if (hearts > 30) 572 { 573 hearts = 30; 574 } 575 576 int yo = yLine1; 577 int baseHealth = 0; 578 579 while (hearts > 0) 580 { 581 int rowHearts = min(hearts, 10); 582 hearts -= rowHearts; 583 584 for (int i = 0; i < rowHearts; i++) 585 { 586 int texBaseX = 52; 587 int bg = 0; 588 589 if (foodBlink) bg = 1; 590 int xo = xRight - i * 8 - 9; 591 blit(xo, yo, texBaseX + bg * 9, 9 * 1, 9, 9); 592 if (i * 2 + 1 + baseHealth < riderCurrentHealth) blit(xo, yo, texBaseX + 4 * 9, 9 * 1, 9, 9); 593 if (i * 2 + 1 + baseHealth == riderCurrentHealth) blit(xo, yo, texBaseX + 5 * 9, 9 * 1, 9, 9); 594 } 595 yo -= 10; 596 baseHealth += 20; 597 } 598 } 599 600 // render air bubbles 601 if (minecraft->player->isUnderLiquid(Material::water)) 602 { 603 int count = (int) ceil((minecraft->player->getAirSupply() - 2) * 10.0f / Player::TOTAL_AIR_SUPPLY); 604 int extra = (int) ceil((minecraft->player->getAirSupply()) * 10.0f / Player::TOTAL_AIR_SUPPLY) - count; 605 for (int i = 0; i < count + extra; i++) 606 { 607 // Air bubbles 608 if (i < count) blit(xRight - i * 8 - 9, yLine2, 16, 9 * 2, 9, 9); 609 else blit(xRight - i * 8 - 9, yLine2, 16 + 9, 9 * 2, 9, 9); 610 } 611 } 612 } 613 614 } 615 616 // 4J-PB - turn off the slot display if a xui menu is up 617 618 //////////////////////////// 619 // render the slot contents 620 //////////////////////////// 621 if(bDisplayGui) 622 { 623 // glDisable(GL_BLEND); 4J - removed - we want to be able to fade our gui 624 625 glEnable(GL_RESCALE_NORMAL); 626 627 Lighting::turnOnGui(); 628 629 630 int x,y; 631 632 for (int i = 0; i < 9; i++) 633 { 634 if(bTwoPlayerSplitscreen) 635 { 636 x = iWidthOffset + screenWidth / 2 - 9 * 10 + i * 20 + 2; 637 y = iHeightOffset + screenHeight - iSafezoneYHalf - iTooltipsYOffset - 16 - 3 + 22; 638 } 639 else 640 { 641 x = screenWidth / 2 - 9 * 10 + i * 20 + 2; 642 y = screenHeight - iSafezoneYHalf - iTooltipsYOffset - 16 - 3 + 22; 643 } 644 this->renderSlot(i, x, y, a); 645 } 646 Lighting::turnOff(); 647 glDisable(GL_RESCALE_NORMAL); 648 } 649#endif // RENDER_HUD 650 651 // 4J - do render of crouched player. This code is largely taken from the inventory render of the player, with some special hard-coded positions 652 // worked out by hand from the xui implementation of the crouch icon 653 654 if(app.GetGameSettings(iPad,eGameSetting_AnimatedCharacter)) 655 { 656 //int playerIdx = minecraft->player->GetXboxPad(); 657 658 static int characterDisplayTimer[4] = {0}; 659 if( !bDisplayGui ) 660 { 661 characterDisplayTimer[iPad] = 0; 662 } 663 else if( minecraft->player->isSneaking() ) 664 { 665 characterDisplayTimer[iPad] = 30; 666 } 667 else if( minecraft->player->isSprinting() ) 668 { 669 characterDisplayTimer[iPad] = 30; 670 } 671 else if( minecraft->player->abilities.flying) 672 { 673 characterDisplayTimer[iPad] = 5; // quickly get rid of the player display if they stop flying 674 } 675 else if( characterDisplayTimer[iPad] > 0 ) 676 { 677 --characterDisplayTimer[iPad]; 678 } 679 bool displayCrouch = minecraft->player->isSneaking() || ( characterDisplayTimer[iPad] > 0 ); 680 bool displaySprint = minecraft->player->isSprinting() || ( characterDisplayTimer[iPad] > 0 ); 681 bool displayFlying = minecraft->player->abilities.flying || ( characterDisplayTimer[iPad] > 0 ); 682 683 if( bDisplayGui && (displayCrouch || displaySprint || displayFlying) ) 684 { 685 EntityRenderDispatcher::instance->prepare(minecraft->level, minecraft->textures, minecraft->font, minecraft->cameraTargetPlayer, minecraft->crosshairPickMob, minecraft->options, a); 686 glEnable(GL_RESCALE_NORMAL); 687 glEnable(GL_COLOR_MATERIAL); 688 689 // 4J - TomK now using safe zone values directly instead of the magic number calculation that lived here before (which only worked for medium scale, the other two were off!) 690 int xo = iSafezoneXHalf + 10; 691 int yo = iSafezoneTopYHalf + 10; 692 693#ifdef __PSVITA__ 694 // align directly with corners, there are no safe zones on vita 695 xo = 10; 696 yo = 10; 697#endif 698 699 glPushMatrix(); 700 glTranslatef((float)xo, (float)yo, 50); 701 float ss = 12; 702 glScalef(-ss, ss, ss); 703 glRotatef(180, 0, 0, 1); 704 705 float oyr = minecraft->player->yRot; 706 float oyrO = minecraft->player->yRotO; 707 float oxr = minecraft->player->xRot; 708 int ofire = minecraft->player->onFire; 709 bool ofireflag = minecraft->player->getSharedFlag(Entity::FLAG_ONFIRE); 710 711 float xd = -40; 712 float yd = 10; 713 714 // 4J Stu - This is all based on the inventory player renderer, with changes to ensure that capes render correctly 715 // by minimising the changes to member variables of the player which are all related 716 717 glRotatef(45 + 90, 0, 1, 0); 718 Lighting::turnOn(); 719 glRotatef(-45 - 90, 0, 1, 0); 720 721 glRotatef(-(float) atan(yd / 40.0f ) * 20, 1, 0, 0); 722 float bodyRot = (minecraft->player->yBodyRotO + (minecraft->player->yBodyRot - minecraft->player->yBodyRotO)); 723 // Fixed rotation angle of degrees, adjusted by bodyRot to negate the rotation that occurs in the renderer 724 // bodyRot in the rotation below is a simplification of "180 - (180 - bodyRot)" where the first 180 is EntityRenderDispatcher::instance->playerRotY that we set below 725 // and (180 - bodyRot) is the angle of rotation that is performed within the mob renderer 726 glRotatef( bodyRot - ( (float) atan(xd / 40.0f) * 20), 0, 1, 0); 727 glColor4f(1.0f, 1.0f, 1.0f, 1.0f); 728 729 // Set head rotation to body rotation to make head static 730 minecraft->player->yRot = bodyRot; 731 minecraft->player->yRotO = minecraft->player->yRot; 732 minecraft->player->xRot = -(float) atan(yd / 40.0f) * 20; 733 734 minecraft->player->onFire = 0; 735 minecraft->player->setSharedFlag(Entity::FLAG_ONFIRE, false); 736 737 // 4J - TomK don't offset the player. it's easier to align it with the safe zones that way! 738 //glTranslatef(0, minecraft->player->heightOffset, 0); 739 glTranslatef(0, 0, 0); 740 EntityRenderDispatcher::instance->playerRotY = 180; 741 EntityRenderDispatcher::instance->isGuiRender = true; 742 EntityRenderDispatcher::instance->render(minecraft->player, 0, 0, 0, 0, 1); 743 EntityRenderDispatcher::instance->isGuiRender = false; 744 745 minecraft->player->yRot = oyr; 746 minecraft->player->yRotO = oyrO; 747 minecraft->player->xRot = oxr; 748 minecraft->player->onFire = ofire; 749 minecraft->player->setSharedFlag(Entity::FLAG_ONFIRE,ofireflag); 750 glPopMatrix(); 751 Lighting::turnOff(); 752 glDisable(GL_RESCALE_NORMAL); 753 } 754 } 755 } 756 757#if RENDER_HUD 758 // Moved so the opacity blend is applied to it 759 if (bDisplayGui && minecraft->gameMode->hasExperience() && minecraft->player->experienceLevel > 0) 760 { 761 if (true) 762 { 763 bool blink = false; 764 int col = blink ? 0xffffff : 0x80ff20; 765 wchar_t formatted[10]; 766 swprintf(formatted, 10, L"%d",minecraft->player->experienceLevel); 767 768 wstring str = formatted; 769 int x = iWidthOffset + (screenWidth - font->width(str)) / 2; 770 int y = screenHeight - iSafezoneYHalf - iTooltipsYOffset; 771 // If we're in creative mode, we don't need to offset the XP display so much 772 if (minecraft->gameMode->canHurtPlayer()) 773 { 774 y-=18; 775 } 776 else 777 { 778 y-=13; 779 } 780 781 if(bTwoPlayerSplitscreen) 782 { 783 y+=iHeightOffset; 784 } 785 //int y = screenHeight - 31 - 4; 786 font->draw(str, x + 1, y, 0x000000); 787 font->draw(str, x - 1, y, 0x000000); 788 font->draw(str, x, y + 1, 0x000000); 789 font->draw(str, x, y - 1, 0x000000); 790 // font->draw(str, x + 1, y + 1, 0x000000); 791 // font->draw(str, x - 1, y + 1, 0x000000); 792 // font->draw(str, x + 1, y - 1, 0x000000); 793 // font->draw(str, x - 1, y - 1, 0x000000); 794 font->draw(str, x, y, col); 795 } 796 } 797#endif // RENDER_HUD 798 799 // 4J - added to disable blends, which we have enabled previously to allow gui fading 800 glDisable(GL_BLEND); 801 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 802 803 // if the player is falling asleep we render a dark overlay 804 if (minecraft->player->getSleepTimer() > 0) 805 { 806 glDisable(GL_DEPTH_TEST); 807 glDisable(GL_ALPHA_TEST); 808 int timer = minecraft->player->getSleepTimer(); 809 float amount = (float) timer / (float) Player::SLEEP_DURATION; 810 if (amount > 1) 811 { 812 // waking up 813 amount = 1.0f - ((float) (timer - Player::SLEEP_DURATION) / (float) Player::WAKE_UP_DURATION); 814 } 815 816 int color = (int) (220.0f * amount) << 24 | (0x101020); 817 fill(0, 0, screenWidth/fScaleFactorWidth, screenHeight/fScaleFactorHeight, color); 818 glEnable(GL_ALPHA_TEST); 819 glEnable(GL_DEPTH_TEST); 820 } 821 822 // 4J-PB - Request from Mojang to have a red death screen 823 if (!minecraft->player->isAlive()) 824 { 825 glDisable(GL_DEPTH_TEST); 826 glDisable(GL_ALPHA_TEST); 827 int timer = minecraft->player->getDeathFadeTimer(); 828 float amount = (float) timer / (float) Player::DEATHFADE_DURATION; 829 830 int color = (int) (220.0f * amount) << 24 | (0x200000); 831 fill(0, 0, screenWidth/fScaleFactorWidth, screenHeight/fScaleFactorHeight, color); 832 glEnable(GL_ALPHA_TEST); 833 glEnable(GL_DEPTH_TEST); 834 835 } 836 837 838 // { 839 // String str = "" + minecraft.player.getFoodData().getExhaustionLevel() + ", " + minecraft.player.getFoodData().getSaturationLevel(); 840 // int x = (screenWidth - font.width(str)) / 2; 841 // int y = screenHeight - 64; 842 // font.draw(str, x + 1, y, 0xffffff); 843 // } 844 845#ifndef _FINAL_BUILD 846 MemSect(31); 847 if (minecraft->options->renderDebug) 848 { 849 glPushMatrix(); 850 if (Minecraft::warezTime > 0) glTranslatef(0, 32, 0); 851 font->drawShadow(ClientConstants::VERSION_STRING + L" (" + minecraft->fpsString + L")", iSafezoneXHalf+2, 20, 0xffffff); 852 font->drawShadow(L"Seed: " + _toString<__int64>(minecraft->level->getLevelData()->getSeed() ), iSafezoneXHalf+2, 32 + 00, 0xffffff); 853 font->drawShadow(minecraft->gatherStats1(), iSafezoneXHalf+2, 32 + 10, 0xffffff); 854 font->drawShadow(minecraft->gatherStats2(), iSafezoneXHalf+2, 32 + 20, 0xffffff); 855 font->drawShadow(minecraft->gatherStats3(), iSafezoneXHalf+2, 32 + 30, 0xffffff); 856 font->drawShadow(minecraft->gatherStats4(), iSafezoneXHalf+2, 32 + 40, 0xffffff); 857 858 // TERRAIN FEATURES 859 int iYPos=82; 860 861 if(minecraft->level->dimension->id==0) 862 { 863 wstring wfeature[eTerrainFeature_Count]; 864 865 wfeature[eTerrainFeature_Stronghold] = L"Stronghold: "; 866 wfeature[eTerrainFeature_Mineshaft] = L"Mineshaft: "; 867 wfeature[eTerrainFeature_Village] = L"Village: "; 868 wfeature[eTerrainFeature_Ravine] = L"Ravine: "; 869 870 for(int i=0;i<app.m_vTerrainFeatures.size();i++) 871 { 872 FEATURE_DATA *pFeatureData=app.m_vTerrainFeatures[i]; 873 874 wstring itemInfo = L"[" + _toString<int>( pFeatureData->x*16 ) + L", " + _toString<int>( pFeatureData->z*16 ) + L"] "; 875 wfeature[pFeatureData->eTerrainFeature] += itemInfo; 876 } 877 878 for( int i = eTerrainFeature_Stronghold; i < (int) eTerrainFeature_Count; i++ ) 879 { 880 font->drawShadow(wfeature[i], iSafezoneXHalf + 2, iYPos, 0xffffff); 881 iYPos+=10; 882 } 883 } 884 885 //font->drawShadow(minecraft->gatherStats5(), iSafezoneXHalf+2, 32 + 10, 0xffffff); 886 { 887 /* 4J - removed 888 long max = Runtime.getRuntime().maxMemory(); 889 long total = Runtime.getRuntime().totalMemory(); 890 long free = Runtime.getRuntime().freeMemory(); 891 long used = total - free; 892 String msg = "Used memory: " + (used * 100 / max) + "% (" + (used / 1024 / 1024) + "MB) of " + (max / 1024 / 1024) + "MB"; 893 drawString(font, msg, screenWidth - font.width(msg) - 2, 2, 0xe0e0e0); 894 msg = "Allocated memory: " + (total * 100 / max) + "% (" + (total / 1024 / 1024) + "MB)"; 895 drawString(font, msg, screenWidth - font.width(msg) - 2, 12, 0xe0e0e0); 896 */ 897 } 898 // 4J Stu - Moved these so that they don't overlap 899 double xBlockPos = floor(minecraft->player->x); 900 double yBlockPos = floor(minecraft->player->y); 901 double zBlockPos = floor(minecraft->player->z); 902 drawString(font, L"x: " + _toString<double>(minecraft->player->x) + L"/ Head: " + _toString<double>(xBlockPos) + L"/ Chunk: " + _toString<double>(minecraft->player->xChunk), iSafezoneXHalf+2, iYPos + 8 * 0, 0xe0e0e0); 903 drawString(font, L"y: " + _toString<double>(minecraft->player->y) + L"/ Head: " + _toString<double>(yBlockPos), iSafezoneXHalf+2, iYPos + 8 * 1, 0xe0e0e0); 904 drawString(font, L"z: " + _toString<double>(minecraft->player->z) + L"/ Head: " + _toString<double>(zBlockPos) + L"/ Chunk: " + _toString<double>(minecraft->player->zChunk), iSafezoneXHalf+2, iYPos + 8 * 2, 0xe0e0e0); 905 drawString(font, L"f: " + _toString<double>(Mth::floor(minecraft->player->yRot * 4.0f / 360.0f + 0.5) & 0x3) + L"/ yRot: " + _toString<double>(minecraft->player->yRot), iSafezoneXHalf+2, iYPos + 8 * 3, 0xe0e0e0); 906 iYPos += 8*4; 907 908 int px = Mth::floor(minecraft->player->x); 909 int py = Mth::floor(minecraft->player->y); 910 int pz = Mth::floor(minecraft->player->z); 911 if (minecraft->level != NULL && minecraft->level->hasChunkAt(px, py, pz)) 912 { 913 LevelChunk *chunkAt = minecraft->level->getChunkAt(px, pz); 914 Biome *biome = chunkAt->getBiome(px & 15, pz & 15, minecraft->level->getBiomeSource()); 915 drawString( 916 font, 917 L"b: " + biome->m_name + L" (" + _toString<int>(biome->id) + L")", iSafezoneXHalf+2, iYPos, 0xe0e0e0); 918 } 919 920 glPopMatrix(); 921 } 922 MemSect(0); 923#endif 924 925 lastTickA = a; 926 // 4J Stu - This is now displayed in a xui scene 927#if 0 928 // Jukebox CD message 929 if (overlayMessageTime > 0) 930 { 931 float t = overlayMessageTime - a; 932 int alpha = (int) (t * 256 / 20); 933 if (alpha > 255) alpha = 255; 934 if (alpha > 0) 935 { 936 glPushMatrix(); 937 938 if(bTwoPlayerSplitscreen) 939 { 940 glTranslatef((float)((screenWidth / 2)+iWidthOffset), ((float)(screenHeight+iHeightOffset)) - iTooltipsYOffset -12 -iSafezoneYHalf, 0); 941 } 942 else 943 { 944 glTranslatef(((float)screenWidth) / 2, ((float)screenHeight) - iTooltipsYOffset - 12 -iSafezoneYHalf, 0); 945 } 946 glEnable(GL_BLEND); 947 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 948 949 int col = 0xffffff; 950 if (animateOverlayMessageColor) 951 { 952 col = Color::HSBtoRGB(t / 50.0f, 0.7f, 0.6f) & 0xffffff; 953 } 954 // 4J-PB - this is the string displayed when cds are placed in a jukebox 955 font->draw(overlayMessageString,-font->width(overlayMessageString) / 2, -20, col + (alpha << 24)); 956 glDisable(GL_BLEND); 957 glPopMatrix(); 958 } 959 } 960#endif 961 962 unsigned int max = 10; 963 bool isChatting = false; 964 if (dynamic_cast<ChatScreen *>(minecraft->screen) != NULL) 965 { 966 max = 20; 967 isChatting = true; 968 } 969 970 glEnable(GL_BLEND); 971 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 972 glDisable(GL_ALPHA_TEST); 973 974// 4J Stu - We have moved the chat text to a xui 975#if 0 976 glPushMatrix(); 977 // 4J-PB we need to move this up a bit because we've moved the quick select 978 //glTranslatef(0, ((float)screenHeight) - 48, 0); 979 glTranslatef(0.0f, (float)(screenHeight - iSafezoneYHalf - iTooltipsYOffset - 16 - 3 + 22) - 24.0f, 0.0f); 980 // glScalef(1.0f / ssc.scale, 1.0f / ssc.scale, 1); 981 982 // 4J-PB - we need gui messages for each of the possible 4 splitscreen players 983 if(bDisplayGui) 984 { 985 int iPad=minecraft->player->GetXboxPad(); 986 for (unsigned int i = 0; i < guiMessages[iPad].size() && i < max; i++) 987 { 988 if (guiMessages[iPad][i].ticks < 20 * 10 || isChatting) 989 { 990 double t = guiMessages[iPad][i].ticks / (20 * 10.0); 991 t = 1 - t; 992 t = t * 10; 993 if (t < 0) t = 0; 994 if (t > 1) t = 1; 995 t = t * t; 996 int alpha = (int) (255 * t); 997 if (isChatting) alpha = 255; 998 999 if (alpha > 0) 1000 { 1001 int x = iSafezoneXHalf+2; 1002 int y = -((int)i) * 9; 1003 if(bTwoPlayerSplitscreen) 1004 { 1005 y+= iHeightOffset; 1006 } 1007 1008 wstring msg = guiMessages[iPad][i].string; 1009 // 4J-PB - fill the black bar across the whole screen, otherwise it looks odd due to the safe area 1010 this->fill(0, y - 1, screenWidth/fScaleFactorWidth, y + 8, (alpha / 2) << 24); 1011 glEnable(GL_BLEND); 1012 1013 font->drawShadow(msg, iSafezoneXHalf+4, y, 0xffffff + (alpha << 24)); 1014 } 1015 } 1016 } 1017 } 1018 glPopMatrix(); 1019#endif 1020 1021 // 4J Stu - Copied over but not used 1022#if 0 1023 if (minecraft.player instanceof MultiplayerLocalPlayer && minecraft.options.keyPlayerList.isDown) 1024 { 1025 ClientConnection connection = ((MultiplayerLocalPlayer) minecraft.player).connection; 1026 List<PlayerInfo> playerInfos = connection.playerInfos; 1027 int slots = connection.maxPlayers; 1028 1029 int rows = slots; 1030 int cols = 1; 1031 while (rows > 20) { 1032 cols++; 1033 rows = (slots + cols - 1) / cols; 1034 } 1035 1036 /* 1037 * int fakeCount = 39; while (playerInfos.size() > fakeCount) 1038 * playerInfos.remove(playerInfos.size() - 1); while (playerInfos.size() < 1039 * fakeCount) playerInfos.add(new PlayerInfo("fiddle")); 1040 */ 1041 1042 int slotWidth = 300 / cols; 1043 if (slotWidth > 150) slotWidth = 150; 1044 1045 int xxo = (screenWidth - cols * slotWidth) / 2; 1046 int yyo = 10; 1047 fill(xxo - 1, yyo - 1, xxo + slotWidth * cols, yyo + 9 * rows, 0x80000000); 1048 for (int i = 0; i < slots; i++) { 1049 int xo = xxo + i % cols * slotWidth; 1050 int yo = yyo + i / cols * 9; 1051 1052 fill(xo, yo, xo + slotWidth - 1, yo + 8, 0x20ffffff); 1053 glColor4f(1, 1, 1, 1); 1054 glEnable(GL_ALPHA_TEST); 1055 1056 if (i < playerInfos.size()) { 1057 PlayerInfo pl = playerInfos.get(i); 1058 font.drawShadow(pl.name, xo, yo, 0xffffff); 1059 minecraft.textures.bind(minecraft.textures.loadTexture("/gui/icons.png")); 1060 int xt = 0; 1061 int yt = 0; 1062 xt = 0; 1063 yt = 0; 1064 if (pl.latency < 0) yt = 5; 1065 else if (pl.latency < 150) yt = 0; 1066 else if (pl.latency < 300) yt = 1; 1067 else if (pl.latency < 600) yt = 2; 1068 else if (pl.latency < 1000) yt = 3; 1069 else yt = 4; 1070 1071 blitOffset += 100; 1072 blit(xo + slotWidth - 12, yo, 0 + xt * 10, 176 + yt * 8, 10, 8); 1073 blitOffset -= 100; 1074 } 1075 } 1076 } 1077#endif 1078 1079 if(bDisplayGui && bTwoPlayerSplitscreen) 1080 { 1081 // pop the scaled matrix 1082 glPopMatrix(); 1083 } 1084 1085 glColor4f(1, 1, 1, 1); 1086 glDisable(GL_BLEND); 1087 glEnable(GL_ALPHA_TEST); 1088} 1089 1090// Moved to the xui base scene 1091// void Gui::renderBossHealth(void) 1092// { 1093// if (EnderDragonRenderer::bossInstance == NULL) return; 1094// 1095// shared_ptr<EnderDragon> boss = EnderDragonRenderer::bossInstance; 1096// EnderDragonRenderer::bossInstance = NULL; 1097// 1098// Minecraft *pMinecraft=Minecraft::GetInstance(); 1099// 1100// Font *font = pMinecraft->font; 1101// 1102// ScreenSizeCalculator ssc(pMinecraft->options, pMinecraft->width_phys, pMinecraft->height_phys); 1103// int screenWidth = ssc.getWidth(); 1104// 1105// int w = 182; 1106// int xLeft = screenWidth / 2 - w / 2; 1107// 1108// int progress = (int) (boss->getSynchedHealth() / (float) boss->getMaxHealth() * (float) (w + 1)); 1109// 1110// int yo = 12; 1111// blit(xLeft, yo, 0, 74, w, 5); 1112// blit(xLeft, yo, 0, 74, w, 5); 1113// if (progress > 0) 1114// { 1115// blit(xLeft, yo, 0, 79, progress, 5); 1116// } 1117// 1118// wstring msg = L"Boss health - NON LOCALISED"; 1119// font->drawShadow(msg, screenWidth / 2 - font->width(msg) / 2, yo - 10, 0xff00ff); 1120// glColor4f(1, 1, 1, 1); 1121// glBindTexture(GL_TEXTURE_2D, pMinecraft->textures->loadTexture(TN_GUI_ICONS) );//"/gui/icons.png")); 1122// 1123// } 1124 1125void Gui::renderPumpkin(int w, int h) 1126{ 1127 glDisable(GL_DEPTH_TEST); 1128 glDepthMask(false); 1129 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1130 glColor4f(1, 1, 1, 1); 1131 glDisable(GL_ALPHA_TEST); 1132 1133 MemSect(31); 1134 minecraft->textures->bindTexture(&PUMPKIN_BLUR_LOCATION); 1135 MemSect(0); 1136 Tesselator *t = Tesselator::getInstance(); 1137 t->begin(); 1138 t->vertexUV((float)(0), (float)( h), (float)( -90), (float)( 0), (float)( 1)); 1139 t->vertexUV((float)(w), (float)( h), (float)( -90), (float)( 1), (float)( 1)); 1140 t->vertexUV((float)(w), (float)( 0), (float)( -90), (float)( 1), (float)( 0)); 1141 t->vertexUV((float)(0), (float)( 0), (float)( -90), (float)( 0), (float)( 0)); 1142 t->end(); 1143 glDepthMask(true); 1144 glEnable(GL_DEPTH_TEST); 1145 glEnable(GL_ALPHA_TEST); 1146 glColor4f(1, 1, 1, 1); 1147 1148} 1149 1150void Gui::renderVignette(float br, int w, int h) 1151{ 1152 br = 1 - br; 1153 if (br < 0) br = 0; 1154 if (br > 1) br = 1; 1155 tbr += (br - tbr) * 0.01f; 1156 1157#if 0 // 4J - removed - TODO put back when we have blend functions implemented 1158 glDisable(GL_DEPTH_TEST); 1159 glDepthMask(false); 1160 glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); 1161 glColor4f(tbr, tbr, tbr, 1); 1162 glBindTexture(GL_TEXTURE_2D, minecraft->textures->loadTexture(TN__BLUR__MISC_VIGNETTE));//L"%blur%/misc/vignette.png")); 1163 Tesselator *t = Tesselator::getInstance(); 1164 t->begin(); 1165 t->vertexUV((float)(0), (float)( h), (float)( -90), (float)( 0), (float)( 1)); 1166 t->vertexUV((float)(w), (float)( h), (float)( -90), (float)( 1), (float)( 1)); 1167 t->vertexUV((float)(w), (float)( 0), (float)( -90), (float)( 1), (float)( 0)); 1168 t->vertexUV((float)(0), (float)( 0), (float)( -90), (float)( 0), (float)( 0)); 1169 t->end(); 1170 glDepthMask(true); 1171 glEnable(GL_DEPTH_TEST); 1172 glColor4f(1, 1, 1, 1); 1173 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1174#endif 1175} 1176 1177void Gui::renderTp(float br, int w, int h) 1178{ 1179 if (br < 1) 1180 { 1181 br = br * br; 1182 br = br * br; 1183 br = br * 0.8f + 0.2f; 1184 } 1185 1186 glDisable(GL_ALPHA_TEST); 1187 glDisable(GL_DEPTH_TEST); 1188 glDepthMask(false); 1189 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1190 glColor4f(1, 1, 1, br); 1191 MemSect(31); 1192 minecraft->textures->bindTexture(&TextureAtlas::LOCATION_BLOCKS); 1193 MemSect(0); 1194 1195 Icon *slot = Tile::portalTile->getTexture(Facing::UP); 1196 float u0 = slot->getU0(); 1197 float v0 = slot->getV0(); 1198 float u1 = slot->getU1(); 1199 float v1 = slot->getV1(); 1200 Tesselator *t = Tesselator::getInstance(); 1201 t->begin(); 1202 t->vertexUV((float)(0), (float)( h), (float)( -90), (float)( u0), (float)( v1)); 1203 t->vertexUV((float)(w), (float)( h), (float)( -90), (float)( u1), (float)( v1)); 1204 t->vertexUV((float)(w), (float)( 0), (float)( -90), (float)( u1), (float)( v0)); 1205 t->vertexUV((float)(0), (float)( 0), (float)( -90), (float)( u0), (float)( v0)); 1206 t->end(); 1207 glDepthMask(true); 1208 glEnable(GL_DEPTH_TEST); 1209 glEnable(GL_ALPHA_TEST); 1210 glColor4f(1, 1, 1, 1); 1211 1212} 1213 1214void Gui::renderSlot(int slot, int x, int y, float a) 1215{ 1216 shared_ptr<ItemInstance> item = minecraft->player->inventory->items[slot]; 1217 if (item == NULL) return; 1218 1219 float pop = item->popTime - a; 1220 if (pop > 0) 1221 { 1222 glPushMatrix(); 1223 float squeeze = 1 + pop / (float) Inventory::POP_TIME_DURATION; 1224 glTranslatef((float)(x + 8), (float)(y + 12), 0); 1225 glScalef(1 / squeeze, (squeeze + 1) / 2, 1); 1226 glTranslatef((float)-(x + 8), (float)-(y + 12), 0); 1227 } 1228 1229 itemRenderer->renderAndDecorateItem(minecraft->font, minecraft->textures, item, x, y); 1230 1231 if (pop > 0) 1232 { 1233 glPopMatrix(); 1234 } 1235 1236 itemRenderer->renderGuiItemDecorations(minecraft->font, minecraft->textures, item, x, y); 1237 1238} 1239 1240void Gui::tick() 1241{ 1242 if (overlayMessageTime > 0) overlayMessageTime--; 1243 tickCount++; 1244 1245 for(int iPad=0;iPad<XUSER_MAX_COUNT;iPad++) 1246 { 1247 // 4J Stu - Fix for #10929 - MP LAB: Network Disconnects: Host does not receive an error message stating the client left the game when viewing the Pause Menu. 1248 // We don't show the guiMessages when a menu is up, so don't fade them out 1249 if(!ui.GetMenuDisplayed(iPad)) 1250 { 1251 AUTO_VAR(itEnd, guiMessages[iPad].end()); 1252 for (AUTO_VAR(it, guiMessages[iPad].begin()); it != itEnd; it++) 1253 { 1254 (*it).ticks++; 1255 } 1256 } 1257 } 1258} 1259 1260void Gui::clearMessages(int iPad) 1261{ 1262 if(iPad==-1) 1263 { 1264 for(int i=0;i<XUSER_MAX_COUNT;i++) 1265 { 1266 if(minecraft->localplayers[i]) 1267 { 1268 guiMessages[i].clear(); 1269 } 1270 } 1271 } 1272 else 1273 { 1274 guiMessages[iPad].clear(); 1275 } 1276} 1277 1278 1279void Gui::addMessage(const wstring& _string,int iPad,bool bIsDeathMessage) 1280{ 1281 wstring string = _string; // 4J - Take copy of input as it is const 1282 //int iScale=1; 1283 1284 //if((minecraft->player->m_iScreenSection==C4JRender::VIEWPORT_TYPE_SPLIT_TOP) || 1285 // (minecraft->player->m_iScreenSection==C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM)) 1286 //{ 1287 // iScale=2; 1288 //} 1289 1290 // while (minecraft->font->width(string) > (m_iMaxMessageWidth*iScale)) 1291 //{ 1292 // unsigned int i = 1; 1293 // while (i < string.length() && minecraft->font->width(string.substr(0, i + 1)) <= (m_iMaxMessageWidth*iScale)) 1294 // { 1295 // i++; 1296 // } 1297 // int iLast=string.find_last_of(L" ",i); 1298 1299 // // if a space was found, include the space on this line 1300 // if(iLast!=i) 1301 // { 1302 // iLast++; 1303 // } 1304 // addMessage(string.substr(0, iLast), iPad); 1305 // string = string.substr(iLast); 1306 // } 1307 1308 int maximumChars; 1309 1310 switch(minecraft->player->m_iScreenSection) 1311 { 1312 case C4JRender::VIEWPORT_TYPE_SPLIT_TOP: 1313 case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM: 1314 case C4JRender::VIEWPORT_TYPE_FULLSCREEN: 1315 if(RenderManager.IsHiDef()) 1316 { 1317 maximumChars = 105; 1318 } 1319 else 1320 { 1321 maximumChars = 55; 1322 } 1323#ifdef __PSVITA__ 1324 maximumChars = 90; 1325#endif 1326 switch(XGetLanguage()) 1327 { 1328 case XC_LANGUAGE_JAPANESE: 1329 case XC_LANGUAGE_TCHINESE: 1330 case XC_LANGUAGE_KOREAN: 1331 if(RenderManager.IsHiDef()) 1332 { 1333 maximumChars = 70; 1334 } 1335 else 1336 { 1337 maximumChars = 35; 1338 } 1339#ifdef __PSVITA__ 1340 maximumChars = 55; 1341#endif 1342 break; 1343 } 1344 break; 1345 default: 1346 maximumChars = 55; 1347 switch(XGetLanguage()) 1348 { 1349 case XC_LANGUAGE_JAPANESE: 1350 case XC_LANGUAGE_TCHINESE: 1351 case XC_LANGUAGE_KOREAN: 1352 maximumChars = 35; 1353 break; 1354 } 1355 break; 1356 } 1357 1358 1359 while (string.length() > maximumChars) 1360 { 1361 unsigned int i = 1; 1362 while (i < string.length() && (i + 1) <= maximumChars) 1363 { 1364 i++; 1365 } 1366 int iLast=(int)string.find_last_of(L" ",i); 1367 switch(XGetLanguage()) 1368 { 1369 case XC_LANGUAGE_JAPANESE: 1370 case XC_LANGUAGE_TCHINESE: 1371 case XC_LANGUAGE_KOREAN: 1372 iLast = maximumChars; 1373 break; 1374 default: 1375 iLast=(int)string.find_last_of(L" ",i); 1376 break; 1377 } 1378 1379 // if a space was found, include the space on this line 1380 if(iLast!=i) 1381 { 1382 iLast++; 1383 } 1384 addMessage(string.substr(0, iLast), iPad, bIsDeathMessage); 1385 string = string.substr(iLast); 1386 } 1387 1388 if(iPad==-1) 1389 { 1390 // add to all 1391 for(int i=0;i<XUSER_MAX_COUNT;i++) 1392 { 1393 if(minecraft->localplayers[i] && !(bIsDeathMessage && app.GetGameSettings(i,eGameSetting_DeathMessages)==0)) 1394 { 1395 guiMessages[i].insert(guiMessages[i].begin(), GuiMessage(string)); 1396 while (guiMessages[i].size() > 50) 1397 { 1398 guiMessages[i].pop_back(); 1399 } 1400 } 1401 } 1402 } 1403 else if(!(bIsDeathMessage && app.GetGameSettings(iPad,eGameSetting_DeathMessages)==0)) 1404 { 1405 guiMessages[iPad].insert(guiMessages[iPad].begin(), GuiMessage(string)); 1406 while (guiMessages[iPad].size() > 50) 1407 { 1408 guiMessages[iPad].pop_back(); 1409 } 1410 } 1411 1412 1413} 1414 1415// 4J Added 1416float Gui::getOpacity(int iPad, DWORD index) 1417{ 1418 float opacityPercentage = 0; 1419 if (guiMessages[iPad].size() > index && guiMessages[iPad][index].ticks < 20 * 10) 1420 { 1421 double t = guiMessages[iPad][index].ticks / (20 * 10.0); 1422 t = 1 - t; 1423 t = t * 10; 1424 if (t < 0) t = 0; 1425 if (t > 1) t = 1; 1426 t = t * t; 1427 opacityPercentage = t; 1428 } 1429 return opacityPercentage; 1430} 1431 1432float Gui::getJukeboxOpacity(int iPad) 1433{ 1434 float t = overlayMessageTime - lastTickA; 1435 int alpha = (int) (t * 256 / 20); 1436 if (alpha > 255) alpha = 255; 1437 alpha /= 255; 1438 1439 return alpha; 1440} 1441 1442void Gui::setNowPlaying(const wstring& string) 1443{ 1444// overlayMessageString = L"Now playing: " + string; 1445 overlayMessageString = app.GetString(IDS_NOWPLAYING) + string; 1446 overlayMessageTime = 20 * 3; 1447 animateOverlayMessageColor = true; 1448} 1449 1450void Gui::displayClientMessage(int messageId, int iPad) 1451{ 1452 //Language *language = Language::getInstance(); 1453 wstring languageString = app.GetString(messageId);//language->getElement(messageId); 1454 1455 addMessage(languageString, iPad); 1456} 1457 1458// 4J Added 1459void Gui::renderGraph(int dataLength, int dataPos, __int64 *dataA, float dataAScale, int dataAWarning, __int64 *dataB, float dataBScale, int dataBWarning) 1460{ 1461 int height = minecraft->height; 1462 // This causes us to cover xScale*dataLength pixels in the horizontal 1463 int xScale = 1; 1464 if(dataA != NULL && dataB != NULL) xScale = 2; 1465 1466 glClear(GL_DEPTH_BUFFER_BIT); 1467 glMatrixMode(GL_PROJECTION); 1468 glLoadIdentity(); 1469 glOrtho(0, (float)minecraft->width, (float)height, 0, 1000, 3000); 1470 glMatrixMode(GL_MODELVIEW); 1471 glLoadIdentity(); 1472 glTranslatef(0, 0, -2000); 1473 1474 glLineWidth(1); 1475 glDisable(GL_TEXTURE_2D); 1476 Tesselator *t = Tesselator::getInstance(); 1477 1478 t->begin(GL_LINES); 1479 for (int i = 0; i < dataLength; i++) 1480 { 1481 int col = ((i - dataPos) & (dataLength - 1)) * 255 / dataLength; 1482 int cc = col * col / 255; 1483 cc = cc * cc / 255; 1484 int cc2 = cc * cc / 255; 1485 cc2 = cc2 * cc2 / 255; 1486 1487 if( dataA != NULL ) 1488 { 1489 if (dataA[i] > dataAWarning) 1490 { 1491 t->color(0xff000000 + cc * 65536); 1492 } 1493 else 1494 { 1495 t->color(0xff000000 + cc * 256); 1496 } 1497 1498 __int64 aVal = dataA[i] / dataAScale; 1499 1500 t->vertex((float)(xScale*i + 0.5f), (float)( height - aVal + 0.5f), (float)( 0)); 1501 t->vertex((float)(xScale*i + 0.5f), (float)( height + 0.5f), (float)( 0)); 1502 } 1503 1504 if( dataB != NULL ) 1505 { 1506 if (dataB[i]>dataBWarning) 1507 { 1508 t->color(0xff000000 + cc * 65536 + cc * 256 + cc * 1); 1509 } 1510 else 1511 { 1512 t->color(0xff808080 + cc/2 * 256); 1513 } 1514 1515 __int64 bVal = dataB[i] / dataBScale; 1516 1517 t->vertex((float)(xScale*i + (xScale - 1) + 0.5f), (float)( height - bVal + 0.5f), (float)( 0)); 1518 t->vertex((float)(xScale*i + (xScale - 1) + 0.5f), (float)( height + 0.5f), (float)( 0)); 1519 } 1520 } 1521 t->end(); 1522 1523 glEnable(GL_TEXTURE_2D); 1524} 1525 1526void Gui::renderStackedGraph(int dataPos, int dataLength, int dataSources, __int64 (*func)(unsigned int dataPos, unsigned int dataSource) ) 1527{ 1528 int height = minecraft->height; 1529 1530 glClear(GL_DEPTH_BUFFER_BIT); 1531 glMatrixMode(GL_PROJECTION); 1532 glLoadIdentity(); 1533 glOrtho(0, (float)minecraft->width, (float)height, 0, 1000, 3000); 1534 glMatrixMode(GL_MODELVIEW); 1535 glLoadIdentity(); 1536 glTranslatef(0, 0, -2000); 1537 1538 glLineWidth(1); 1539 glDisable(GL_TEXTURE_2D); 1540 Tesselator *t = Tesselator::getInstance(); 1541 1542 t->begin(GL_LINES); 1543 __int64 thisVal = 0; 1544 __int64 topVal = 0; 1545 for (int i = 0; i < dataLength; i++) 1546 { 1547 thisVal = 0; 1548 topVal = 0; 1549 int col = ((i - dataPos) & (dataLength - 1)) * 255 / dataLength; 1550 int cc = col * col / 255; 1551 cc = cc * cc / 255; 1552 int cc2 = cc * cc / 255; 1553 cc2 = cc2 * cc2 / 255; 1554 1555 1556 for(unsigned int source = 0; source < dataSources; ++source ) 1557 { 1558 thisVal = func( i, source ); 1559 1560 if( thisVal > 0 ) 1561 { 1562 float vary = (float)source/dataSources; 1563 int fColour = floor(vary * 0xffffff); 1564 1565 int colour = 0xff000000 + fColour; 1566 //printf("Colour is %x\n", colour); 1567 t->color(colour); 1568 1569 t->vertex((float)(i + 0.5f), (float)( height - topVal - thisVal + 0.5f), (float)( 0)); 1570 t->vertex((float)(i + 0.5f), (float)( height - topVal + 0.5f), (float)( 0)); 1571 1572 topVal += thisVal; 1573 } 1574 } 1575 1576 // Draw some horizontals 1577 for(unsigned int horiz = 1; horiz < 7; ++horiz ) 1578 { 1579 t->color(0xff000000); 1580 1581 t->vertex((float)(0 + 0.5f), (float)( height - (horiz*100) + 0.5f), (float)( 0)); 1582 t->vertex((float)(dataLength + 0.5f), (float)( height - (horiz*100) + 0.5f), (float)( 0)); 1583 } 1584 } 1585 t->end(); 1586 1587 glEnable(GL_TEXTURE_2D); 1588}