Merge branch 'dedicated-rewrite'
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
#include "Options.h"
|
||||
#include "client/Options.h"
|
||||
#include "client/player/input/IBuildInput.h"
|
||||
#include "commands/CommandManager.hpp"
|
||||
#include "platform/input/Keyboard.h"
|
||||
#include "world/item/Item.h"
|
||||
#include "world/item/ItemInstance.h"
|
||||
@@ -180,7 +181,8 @@ Minecraft::Minecraft() :
|
||||
_powerVr(false),
|
||||
commandPort(4711),
|
||||
reserved_d1(0),reserved_d2(0),
|
||||
reserved_f1(0),reserved_f2(0), options(this)
|
||||
reserved_f1(0),reserved_f2(0), options(this),
|
||||
m_commandManager()
|
||||
{
|
||||
//#ifdef ANDROID
|
||||
|
||||
@@ -261,9 +263,10 @@ void Minecraft::selectLevel( const std::string& levelId, const std::string& leve
|
||||
|
||||
void Minecraft::setLevel(Level* level, const std::string& message /* ="" */, LocalPlayer* forceInsertPlayer /* = NULL */) {
|
||||
cameraTargetPlayer = NULL;
|
||||
LOGI("Seed is %ld\n", level->getSeed());
|
||||
|
||||
if (level != NULL) {
|
||||
LOGI("Seed is %ld\n", level->getSeed());
|
||||
|
||||
level->raknetInstance = raknetInstance;
|
||||
gameMode->initLevel(level);
|
||||
|
||||
@@ -280,6 +283,11 @@ void Minecraft::setLevel(Level* level, const std::string& message /* ="" */, Loc
|
||||
}
|
||||
}
|
||||
this->level = level;
|
||||
// So uhhh
|
||||
std::string op = options.getStringValue(OPTIONS_USERNAME);
|
||||
std::transform(op.begin(), op.end(), op.begin(), ::tolower);
|
||||
|
||||
level->ops.emplace(op);
|
||||
_hasSignaledGeneratingLevelFinished = false;
|
||||
#ifdef STANDALONE_SERVER
|
||||
const bool threadedLevelCreation = false;
|
||||
@@ -363,12 +371,12 @@ void Minecraft::prepareLevel(const std::string& title) {
|
||||
if (!level->isNew())
|
||||
level->setUpdateLights(false);
|
||||
|
||||
int Max = CHUNK_CACHE_WIDTH * CHUNK_CACHE_WIDTH;
|
||||
int Max = LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_CACHE_WIDTH;
|
||||
int pp = 0;
|
||||
for (int x = 8; x < (CHUNK_CACHE_WIDTH * CHUNK_WIDTH); x += CHUNK_WIDTH) {
|
||||
for (int z = 8; z < (CHUNK_CACHE_WIDTH * CHUNK_WIDTH); z += CHUNK_WIDTH) {
|
||||
progressStagePercentage = 100 * pp++ / Max;
|
||||
//printf("level generation progress %d\n", progressStagePercentage);
|
||||
for (int x = 8; x < (LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_WIDTH); x += LevelConstants::CHUNK_WIDTH) {
|
||||
for (int z = 8; z < (LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_WIDTH); z += LevelConstants::CHUNK_WIDTH) {
|
||||
progressStagePercentage = 100 * pp++ / Max;
|
||||
//printf("level generation progress %d\n", progressStagePercentage);
|
||||
B.start();
|
||||
level->getTile(x, 64, z);
|
||||
B.stop();
|
||||
@@ -383,9 +391,9 @@ void Minecraft::prepareLevel(const std::string& title) {
|
||||
level->setUpdateLights(true);
|
||||
|
||||
C.start();
|
||||
for (int x = 0; x < CHUNK_CACHE_WIDTH; x++)
|
||||
for (int x = 0; x < LevelConstants::CHUNK_CACHE_WIDTH; x++)
|
||||
{
|
||||
for (int z = 0; z < CHUNK_CACHE_WIDTH; z++)
|
||||
for (int z = 0; z < LevelConstants::CHUNK_CACHE_WIDTH; z++)
|
||||
{
|
||||
LevelChunk* chunk = level->getChunk(x, z);
|
||||
if (chunk && !chunk->createdFromSave)
|
||||
@@ -559,7 +567,7 @@ void Minecraft::tick(int nTick, int maxTick) {
|
||||
level->tickEntities();
|
||||
level->tick();
|
||||
#ifndef STANDALONE_SERVER
|
||||
TIMER_POP_PUSH("animateTick");
|
||||
TIMER_POP_PUSH("animateTick");
|
||||
if (player) {
|
||||
level->animateTick(Mth::floor(player->x), Mth::floor(player->y), Mth::floor(player->z));
|
||||
}
|
||||
@@ -732,6 +740,21 @@ void Minecraft::tickInput() {
|
||||
if (key == Keyboard::KEY_F3) {
|
||||
options.toggle(OPTIONS_RENDER_DEBUG);
|
||||
}
|
||||
|
||||
// TODO: replace it with client /give command :face_vomiting:
|
||||
// if (key == Keyboard::KEY_F4) {
|
||||
// player->inventory->add(new ItemInstance(Tile::redBrick));
|
||||
// player->inventory->add(new ItemInstance(Item::ironIngot, 64));
|
||||
// player->inventory->add(new ItemInstance(Item::ironIngot, 34));
|
||||
// player->inventory->add(new ItemInstance(Tile::stonecutterBench));
|
||||
// player->inventory->add(new ItemInstance(Tile::workBench));
|
||||
// player->inventory->add(new ItemInstance(Tile::furnace));
|
||||
// player->inventory->add(new ItemInstance(Tile::wood, 54));
|
||||
// player->inventory->add(new ItemInstance(Item::stick, 14));
|
||||
// player->inventory->add(new ItemInstance(Item::coal, 31));
|
||||
// player->inventory->add(new ItemInstance(Tile::sand, 6));
|
||||
|
||||
// }
|
||||
|
||||
if (key == Keyboard::KEY_F5) {
|
||||
options.toggle(OPTIONS_THIRD_PERSON_VIEW);
|
||||
@@ -1136,6 +1159,7 @@ bool Minecraft::supportNonTouchScreen() {
|
||||
}
|
||||
void Minecraft::init()
|
||||
{
|
||||
LevelChunk::ChunkBlockCount = LevelConstants::CHUNK_BLOCK_COUNT;
|
||||
#ifndef STANDALONE_SERVER
|
||||
checkGlError("Init enter");
|
||||
|
||||
@@ -1373,12 +1397,9 @@ bool Minecraft::joinMultiplayerFromString( const std::string& server )
|
||||
} else {
|
||||
ip = server;
|
||||
}
|
||||
|
||||
printf("%s \n", port.c_str());
|
||||
|
||||
|
||||
if (isLookingForMultiplayer && netCallback) {
|
||||
isLookingForMultiplayer = false;
|
||||
printf("test");
|
||||
int portNum = atoi(port.c_str());
|
||||
return raknetInstance->connect(ip.c_str(), portNum);
|
||||
}
|
||||
@@ -1686,3 +1707,11 @@ void Minecraft::optionUpdated(OptionId option, int value ) {
|
||||
setSize(width, height);
|
||||
}
|
||||
}
|
||||
|
||||
void Minecraft::addMessage(const std::string& msg) {
|
||||
#ifndef STANDALONE_SERVER
|
||||
gui.addMessage(msg);
|
||||
#else
|
||||
LOGI("%s \n", msg.c_str());
|
||||
#endif
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
#define NET_MINECRAFT_CLIENT__Minecraft_H__
|
||||
|
||||
#include "Options.h"
|
||||
#include "commands/CommandManager.hpp"
|
||||
#ifndef STANDALONE_SERVER
|
||||
#include "MouseHandler.h"
|
||||
#include "gui/Gui.h"
|
||||
@@ -128,11 +129,17 @@ public:
|
||||
void optionUpdated(OptionId option, bool value);
|
||||
void optionUpdated(OptionId option, float value);
|
||||
void optionUpdated(OptionId option, int value);
|
||||
|
||||
int getTicks() { return ticks; }
|
||||
|
||||
void addMessage(const std::string& msg);
|
||||
#ifdef __APPLE__
|
||||
bool _isSuperFast;
|
||||
bool isSuperFast() { return _isSuperFast; }
|
||||
#endif
|
||||
|
||||
CommandManager& commandManager() { return m_commandManager; }
|
||||
|
||||
protected:
|
||||
void _levelGenerated();
|
||||
|
||||
@@ -205,7 +212,8 @@ public:
|
||||
std::string externalCacheStoragePath;
|
||||
protected:
|
||||
Timer timer;
|
||||
// @note @attn @warn: this is dangerous as fuck!
|
||||
|
||||
// @note @attn @warn: this is dangerous as fuck!
|
||||
volatile bool isGeneratingLevel;
|
||||
bool _hasSignaledGeneratingLevelFinished;
|
||||
|
||||
@@ -233,6 +241,8 @@ private:
|
||||
|
||||
PerfRenderer* _perfRenderer;
|
||||
CommandServer* _commandServer;
|
||||
|
||||
CommandManager m_commandManager;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_CLIENT__Minecraft_H__*/
|
||||
|
||||
@@ -90,8 +90,12 @@ bool GameMode::useItemOn(Player* player, Level* level, ItemInstance* item, int x
|
||||
float clickY = hit.y - y;
|
||||
float clickZ = hit.z - z;
|
||||
if (level->isClientSide) {
|
||||
LOGI("%f %f %f \n", player->x, player->y, player->z);
|
||||
|
||||
item = player->inventory->getSelected();
|
||||
UseItemPacket packet(x, y, z, face, item, player->entityId, clickX, clickY, clickZ);
|
||||
UseItemPacket packet(x, y, z, face, item, player->entityId, clickX, clickY, clickZ, player->x, player->y, player->z,
|
||||
player->bb.x0, player->bb.y0, player->bb.z0, player->bb.x1, player->bb.y1, player->bb.z1);
|
||||
|
||||
minecraft->raknetInstance->send(packet);
|
||||
}
|
||||
int t = level->getTile(x, y, z);
|
||||
@@ -100,7 +104,7 @@ bool GameMode::useItemOn(Player* player, Level* level, ItemInstance* item, int x
|
||||
return true;
|
||||
|
||||
if (item == NULL) return false;
|
||||
if(isCreativeType()) {
|
||||
if (isCreativeType()) {
|
||||
int aux = item->getAuxValue();
|
||||
int count = item->count;
|
||||
bool success = item->useOn(player, level, x, y, z, face, clickX, clickY, clickZ);
|
||||
@@ -117,7 +121,8 @@ bool GameMode::useItem( Player* player, Level* level, ItemInstance* item ) {
|
||||
|
||||
ItemInstance* itemInstance = item->use(level, player);
|
||||
if(level->isClientSide) {
|
||||
UseItemPacket packet(item, player->entityId, player->aimDirection);
|
||||
UseItemPacket packet(item, player->entityId, player->aimDirection, player->x, player->y, player->z,
|
||||
player->bb.x0, player->bb.y0, player->bb.z0, player->bb.x1, player->bb.y1, player->bb.z1);
|
||||
minecraft->raknetInstance->send(packet);
|
||||
}
|
||||
if (itemInstance != item || (itemInstance != NULL && itemInstance->count != oldCount)) {
|
||||
|
||||
@@ -68,6 +68,7 @@ bool SurvivalMode::destroyBlock( int x, int y, int z, int face ) {
|
||||
minecraft->player->inventory->clearSlot(minecraft->player->inventory->selected);
|
||||
}
|
||||
}
|
||||
|
||||
if (changed && couldDestroy) {
|
||||
ItemInstance instance(t, 1, data);
|
||||
Tile::tiles[t]->playerDestroy(minecraft->level, minecraft->player, x, y, z, data);
|
||||
|
||||
@@ -755,7 +755,6 @@ void Gui::renderDebugInfo() {
|
||||
|
||||
// Position
|
||||
float px = p->x, py = p->y - p->heightOffset, pz = p->z;
|
||||
posTranslator.to(px, py, pz);
|
||||
int bx = (int)floorf(px), by = (int)floorf(py), bz = (int)floorf(pz);
|
||||
int cx = bx >> 4, cz = bz >> 4;
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "../../../network/ServerSideNetworkHandler.h"
|
||||
#include "../../../network/packet/ChatPacket.h"
|
||||
#include "../../../platform/log.h"
|
||||
#include "util/StringUtils.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <cstdlib>
|
||||
@@ -54,141 +55,37 @@ void ConsoleScreen::charPressed(char inputChar)
|
||||
_input += inputChar;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// execute: run _input as a command, print result, close screen
|
||||
// ---------------------------------------------------------------------------
|
||||
void ConsoleScreen::execute()
|
||||
{
|
||||
if (!minecraft->level) return;
|
||||
|
||||
if (_input.empty()) {
|
||||
minecraft->setScreen(NULL);
|
||||
return;
|
||||
return minecraft->setScreen(NULL);
|
||||
}
|
||||
|
||||
if (_input[0] == '/') {
|
||||
// Command
|
||||
std::string result = processCommand(_input);
|
||||
if (!result.empty())
|
||||
minecraft->gui.addMessage(result);
|
||||
_input = Util::stringTrim(_input.substr(1));
|
||||
|
||||
std::istringstream iss(minecraft->commandManager().execute(*minecraft, *minecraft->player, _input));
|
||||
for (std::string line; std::getline(iss, line); ) {
|
||||
minecraft->gui.addMessage(line);
|
||||
}
|
||||
} else {
|
||||
// Chat message: <name> message
|
||||
std::string msg = std::string("<") + minecraft->player->name + "> " + _input;
|
||||
// @ai @rewrite
|
||||
if (minecraft->netCallback && minecraft->raknetInstance->isServer()) {
|
||||
// Hosting a LAN game: displayGameMessage shows locally + broadcasts MessagePacket to clients
|
||||
static_cast<ServerSideNetworkHandler*>(minecraft->netCallback)->displayGameMessage(msg);
|
||||
static_cast<ServerSideNetworkHandler*>(minecraft->netCallback)->displayGameMessage(_input);
|
||||
} else if (minecraft->netCallback) {
|
||||
// Connected client: send ChatPacket to server; server echoes it back as MessagePacket
|
||||
ChatPacket chatPkt(msg);
|
||||
ChatPacket chatPkt(_input);
|
||||
minecraft->raknetInstance->send(chatPkt);
|
||||
} else {
|
||||
// Singleplayer: show locally only
|
||||
minecraft->gui.addMessage(msg);
|
||||
minecraft->gui.addMessage("<" + minecraft->player->name + "> " + _input);
|
||||
}
|
||||
}
|
||||
|
||||
minecraft->setScreen(NULL);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// processCommand
|
||||
// ---------------------------------------------------------------------------
|
||||
static std::string trim(const std::string& s) {
|
||||
size_t a = s.find_first_not_of(" \t");
|
||||
if (a == std::string::npos) return "";
|
||||
size_t b = s.find_last_not_of(" \t");
|
||||
return s.substr(a, b - a + 1);
|
||||
}
|
||||
|
||||
std::string ConsoleScreen::processCommand(const std::string& raw)
|
||||
{
|
||||
// strip leading '/'
|
||||
std::string line = raw;
|
||||
if (!line.empty() && line[0] == '/') line = line.substr(1);
|
||||
line = trim(line);
|
||||
|
||||
// tokenise
|
||||
std::vector<std::string> args;
|
||||
{
|
||||
std::istringstream ss(line);
|
||||
std::string tok;
|
||||
while (ss >> tok) args.push_back(tok);
|
||||
}
|
||||
|
||||
if (args.empty()) return "";
|
||||
|
||||
Level* level = minecraft->level;
|
||||
if (!level) return "No level loaded.";
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// /time ...
|
||||
// -----------------------------------------------------------------------
|
||||
if (args[0] == "time") {
|
||||
if (args.size() < 2)
|
||||
return "Usage: /time <add|set|query> ...";
|
||||
|
||||
const std::string& sub = args[1];
|
||||
|
||||
// -- time add <value> -----------------------------------------------
|
||||
if (sub == "add") {
|
||||
if (args.size() < 3) return "Usage: /time add <value>";
|
||||
long delta = std::atol(args[2].c_str());
|
||||
long newTime = level->getTime() + delta;
|
||||
level->setTime(newTime);
|
||||
std::ostringstream out;
|
||||
out << "Set the time to " << (newTime % Level::TICKS_PER_DAY);
|
||||
return out.str();
|
||||
}
|
||||
|
||||
// -- time set <value|day|night|noon|midnight> -----------------------
|
||||
if (sub == "set") {
|
||||
if (args.size() < 3) return "Usage: /time set <value|day|night|noon|midnight>";
|
||||
const std::string& val = args[2];
|
||||
|
||||
long t = -1;
|
||||
if (val == "day") t = 1000;
|
||||
else if (val == "noon") t = 6000;
|
||||
else if (val == "night") t = 13000;
|
||||
else if (val == "midnight") t = 18000;
|
||||
else {
|
||||
// numeric — accept positive integers only
|
||||
bool numeric = true;
|
||||
for (char c : val)
|
||||
if (!std::isdigit((unsigned char)c)) { numeric = false; break; }
|
||||
if (!numeric) return std::string("Unknown value: ") + val;
|
||||
t = std::atol(val.c_str());
|
||||
}
|
||||
|
||||
// Preserve the total day count so only the time-of-day changes
|
||||
long dayCount = level->getTime() / Level::TICKS_PER_DAY;
|
||||
long newTime = dayCount * Level::TICKS_PER_DAY + (t % Level::TICKS_PER_DAY);
|
||||
level->setTime(newTime);
|
||||
std::ostringstream out;
|
||||
out << "Set the time to " << t;
|
||||
return out.str();
|
||||
}
|
||||
|
||||
// -- time query <daytime|gametime|day> ------------------------------
|
||||
if (sub == "query") {
|
||||
if (args.size() < 3) return "Usage: /time query <daytime|gametime|day>";
|
||||
const std::string& what = args[2];
|
||||
|
||||
long total = level->getTime();
|
||||
long daytime = total % Level::TICKS_PER_DAY;
|
||||
long day = total / Level::TICKS_PER_DAY;
|
||||
|
||||
std::ostringstream out;
|
||||
if (what == "daytime") { out << "The time of day is " << daytime; }
|
||||
else if (what == "gametime") { out << "The game time is " << total; }
|
||||
else if (what == "day") { out << "The day is " << day; }
|
||||
else return std::string("Unknown query: ") + what;
|
||||
return out.str();
|
||||
}
|
||||
|
||||
return "Unknown sub-command. Usage: /time <add|set|query> ...";
|
||||
}
|
||||
|
||||
return std::string("Unknown command: /") + args[0];
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// render
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -25,7 +25,6 @@ public:
|
||||
|
||||
private:
|
||||
void execute();
|
||||
std::string processCommand(const std::string& cmd);
|
||||
|
||||
std::string _input;
|
||||
int _cursorBlink; // tick counter for cursor blink
|
||||
|
||||
@@ -16,7 +16,12 @@
|
||||
#include "../../../../world/level/Level.h"
|
||||
#include "../../../../world/item/DyePowderItem.h"
|
||||
#include "../../../../world/item/crafting/Recipe.h"
|
||||
#include "network/RakNetInstance.h"
|
||||
#include "network/packet/WantCreatePacket.h"
|
||||
#include "platform/input/Keyboard.h"
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
static NinePatchLayer* guiPaneFrame = NULL;
|
||||
|
||||
@@ -193,6 +198,26 @@ void PaneCraftingScreen::setupPositions() {
|
||||
}
|
||||
|
||||
void PaneCraftingScreen::tick() {
|
||||
if (minecraft->isOnline()) {
|
||||
// TODO: Make better algorithm
|
||||
static std::map<uint8_t, uint16_t> oldMap = {};
|
||||
std::map<uint8_t, uint16_t> newMap = {};
|
||||
|
||||
for (int i = Inventory::MAX_SELECTION_SIZE; i < minecraft->player->inventory->getContainerSize(); ++i) {
|
||||
auto itm = minecraft->player->inventory->getItem(i);
|
||||
|
||||
if (itm != NULL) {
|
||||
newMap[itm->id] += itm->count;
|
||||
}
|
||||
}
|
||||
|
||||
if (oldMap != newMap) {
|
||||
oldMap = newMap;
|
||||
newMap = {};
|
||||
recheckRecipes();
|
||||
}
|
||||
}
|
||||
|
||||
if (pane) pane->tick();
|
||||
}
|
||||
|
||||
@@ -439,25 +464,29 @@ void PaneCraftingScreen::craftSelectedItem()
|
||||
ItemInstance resultItem = currentItem->item;
|
||||
|
||||
if (minecraft->player) {
|
||||
if (minecraft->isOnline()) {
|
||||
WantCreatePacket packet(minecraft->player->entityId, resultItem.count, resultItem.getAuxValue(), resultItem.id);
|
||||
minecraft->raknetInstance->send(packet);
|
||||
}
|
||||
// Remove all items required for the recipe and ...
|
||||
for (unsigned int i = 0; i < currentItem->neededItems.size(); ++i) {
|
||||
CItem::ReqItem& req = currentItem->neededItems[i];
|
||||
|
||||
// If the recipe allows any aux-value as ingredients, first deplete
|
||||
// aux == 0 from inventory. Since I'm not sure if this always is
|
||||
// correct, let's only do it for ingredient sandstone for now.
|
||||
ItemInstance toRemove = req.item;
|
||||
// If the recipe allows any aux-value as ingredients, first deplete
|
||||
// aux == 0 from inventory. Since I'm not sure if this always is
|
||||
// correct, let's only do it for ingredient sandstone for now.
|
||||
ItemInstance toRemove = req.item;
|
||||
|
||||
if (Tile::sandStone->id == req.item.id
|
||||
&& Recipe::ANY_AUX_VALUE == req.item.getAuxValue()) {
|
||||
toRemove.setAuxValue(0);
|
||||
toRemove.count = minecraft->player->inventory->removeResource(toRemove, true);
|
||||
toRemove.setAuxValue(Recipe::ANY_AUX_VALUE);
|
||||
}
|
||||
if (Tile::sandStone->id == req.item.id
|
||||
&& Recipe::ANY_AUX_VALUE == req.item.getAuxValue()) {
|
||||
toRemove.setAuxValue(0);
|
||||
toRemove.count = minecraft->player->inventory->removeResource(toRemove, true);
|
||||
toRemove.setAuxValue(Recipe::ANY_AUX_VALUE);
|
||||
}
|
||||
|
||||
if (toRemove.count > 0) {
|
||||
minecraft->player->inventory->removeResource(toRemove);
|
||||
}
|
||||
if (toRemove.count > 0) {
|
||||
minecraft->player->inventory->removeResource(toRemove);
|
||||
}
|
||||
}
|
||||
// ... add the new one! (in this order, to fill empty slots better)
|
||||
// if it doesn't fit, throw it on the ground!
|
||||
|
||||
@@ -460,7 +460,7 @@ void LocalPlayer::tick() {
|
||||
{
|
||||
sentInventoryItemId = newItemId;
|
||||
sentInventoryItemData = newItemData;
|
||||
PlayerEquipmentPacket packet(entityId, newItemId, newItemData);
|
||||
PlayerEquipmentPacket packet(entityId, newItemId, newItemData, inventory->selected, inventory->getSlot(newItemId, newItemData));
|
||||
minecraft->raknetInstance->send(packet);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ LevelRenderer::LevelRenderer( Minecraft* mc)
|
||||
destroyProgress(0)
|
||||
{
|
||||
#ifdef OPENGL_ES
|
||||
int maxChunksWidth = 2 * LEVEL_WIDTH / CHUNK_SIZE + 1;
|
||||
int maxChunksWidth = 2 * LevelConstants::LEVEL_WIDTH / CHUNK_SIZE + 1;
|
||||
numListsOrBuffers = maxChunksWidth * maxChunksWidth * (128/CHUNK_SIZE) * 3;
|
||||
chunkBuffers = new GLuint[numListsOrBuffers];
|
||||
glGenBuffers2(numListsOrBuffers, chunkBuffers);
|
||||
@@ -339,15 +339,15 @@ int LevelRenderer::render( Mob* player, int layer, float alpha )
|
||||
allChanged();
|
||||
}
|
||||
|
||||
int currentFogType = mc->options.getIntValue(OPTIONS_FOG_TYPE);
|
||||
if (currentFogType != lastFogType) {
|
||||
lastFogType = currentFogType;
|
||||
|
||||
if (level && level->dimension) {
|
||||
level->dimension->FogType = currentFogType; // use new fog stuff
|
||||
}
|
||||
|
||||
allChanged();
|
||||
int currentFogType = mc->options.getIntValue(OPTIONS_FOG_TYPE);
|
||||
if (currentFogType != lastFogType) {
|
||||
lastFogType = currentFogType;
|
||||
|
||||
if (level && level->dimension) {
|
||||
level->dimension->FogType = currentFogType; // use new fog stuff
|
||||
}
|
||||
|
||||
allChanged();
|
||||
}
|
||||
bool SmoothLightState = mc->options.getBooleanValue(OPTIONS_AMBIENT_OCCLUSION);
|
||||
if (SmoothLightState != mc->useAmbientOcclusion){
|
||||
@@ -1073,56 +1073,56 @@ std::string LevelRenderer::gatherStats1() {
|
||||
// int[] toRender = new int[50000];
|
||||
// IntBuffer resultBuffer = MemoryTracker.createIntBuffer(64);
|
||||
|
||||
void LevelRenderer::generateStars() {
|
||||
// ported from java beta again,
|
||||
// converted the doubles into floats to be consistent, shouldnt affect much - shredder
|
||||
|
||||
Random random = Random(10842L);
|
||||
Tesselator& t = Tesselator::instance;
|
||||
t.begin();
|
||||
starVertexCount = 0;
|
||||
|
||||
for (int i = 0; i < 1500; i++) {
|
||||
float d = random.nextFloat() * 2.0F - 1.0F;
|
||||
float e = random.nextFloat() * 2.0F - 1.0F;
|
||||
float f = random.nextFloat() * 2.0F - 1.0F;
|
||||
float g = 0.25F + random.nextFloat() * 0.25F;
|
||||
float h = d * d + e * e + f * f;
|
||||
if (h < 1.0 && h > 0.01) {
|
||||
h = 1.0 / Mth::sqrt(h);
|
||||
d *= h;
|
||||
e *= h;
|
||||
f *= h;
|
||||
float j = d * 100.0;
|
||||
float k = e * 100.0;
|
||||
float l = f * 100.0;
|
||||
float m = Mth::atan2(d, f);
|
||||
float n = Mth::sin(m);
|
||||
float o = Mth::cos(m);
|
||||
float p = Mth::atan2(Mth::sqrt(d * d + f * f), e);
|
||||
float q = Mth::sin(p);
|
||||
float r = Mth::cos(p);
|
||||
float s = random.nextDouble() * Mth::PI * 2.0;
|
||||
float t2 = Mth::sin(s);
|
||||
float u = Mth::cos(s);
|
||||
|
||||
for (int v = 0; v < 4; v++) {
|
||||
float w = 0.0;
|
||||
float x = ((v & 2) - 1) * g;
|
||||
float y = ((v + 1 & 2) - 1) * g;
|
||||
float aa = x * u - y * t2;
|
||||
float ab = y * u + x * t2;
|
||||
float ad = aa * q + w * r;
|
||||
float ae = w * q - aa * r;
|
||||
float af = ae * n - ab * o;
|
||||
float ah = ab * n + ae * o;
|
||||
t.vertex(j + af, k + ad, l + ah);
|
||||
}
|
||||
starVertexCount += 4;
|
||||
}
|
||||
}
|
||||
|
||||
t.end(true, starBuffer);
|
||||
void LevelRenderer::generateStars() {
|
||||
// ported from java beta again,
|
||||
// converted the doubles into floats to be consistent, shouldnt affect much - shredder
|
||||
|
||||
Random random = Random(10842L);
|
||||
Tesselator& t = Tesselator::instance;
|
||||
t.begin();
|
||||
starVertexCount = 0;
|
||||
|
||||
for (int i = 0; i < 1500; i++) {
|
||||
float d = random.nextFloat() * 2.0F - 1.0F;
|
||||
float e = random.nextFloat() * 2.0F - 1.0F;
|
||||
float f = random.nextFloat() * 2.0F - 1.0F;
|
||||
float g = 0.25F + random.nextFloat() * 0.25F;
|
||||
float h = d * d + e * e + f * f;
|
||||
if (h < 1.0 && h > 0.01) {
|
||||
h = 1.0 / Mth::sqrt(h);
|
||||
d *= h;
|
||||
e *= h;
|
||||
f *= h;
|
||||
float j = d * 100.0;
|
||||
float k = e * 100.0;
|
||||
float l = f * 100.0;
|
||||
float m = Mth::atan2(d, f);
|
||||
float n = Mth::sin(m);
|
||||
float o = Mth::cos(m);
|
||||
float p = Mth::atan2(Mth::sqrt(d * d + f * f), e);
|
||||
float q = Mth::sin(p);
|
||||
float r = Mth::cos(p);
|
||||
float s = random.nextDouble() * Mth::PI * 2.0;
|
||||
float t2 = Mth::sin(s);
|
||||
float u = Mth::cos(s);
|
||||
|
||||
for (int v = 0; v < 4; v++) {
|
||||
float w = 0.0;
|
||||
float x = ((v & 2) - 1) * g;
|
||||
float y = ((v + 1 & 2) - 1) * g;
|
||||
float aa = x * u - y * t2;
|
||||
float ab = y * u + x * t2;
|
||||
float ad = aa * q + w * r;
|
||||
float ae = w * q - aa * r;
|
||||
float af = ae * n - ab * o;
|
||||
float ah = ab * n + ae * o;
|
||||
t.vertex(j + af, k + ad, l + ah);
|
||||
}
|
||||
starVertexCount += 4;
|
||||
}
|
||||
}
|
||||
|
||||
t.end(true, starBuffer);
|
||||
}
|
||||
void LevelRenderer::renderSky(float alpha) {
|
||||
if (mc->level->dimension->foggy) return;
|
||||
@@ -1155,100 +1155,100 @@ void LevelRenderer::renderSky(float alpha) {
|
||||
#ifdef OPENGL_ES
|
||||
drawArrayVT(skyBuffer, skyVertexCount);
|
||||
#endif
|
||||
glDisable(GL_FOG);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
|
||||
// re ported this again from beta 1.6.6, thanks to the mcpe 0.1 decomp team's code for some bit of help about the void layer - shredder
|
||||
|
||||
// Sunrise
|
||||
if (mc->options.getBooleanValue(OPTIONS_BEAUTIFUL_SKY)) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
Lighting::turnOff();
|
||||
float* c = level->dimension->getSunriseColor(level->getTimeOfDay(alpha), alpha);
|
||||
if (c != nullptr)
|
||||
{
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
// glShadeModel(GL_SMOOTH); //
|
||||
|
||||
glPushMatrix();
|
||||
glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
|
||||
glRotatef(level->getTimeOfDay(alpha) > 0.5f ? 180 : 0, 0.0f, 0.0f, 1.0f);
|
||||
t.begin(GL_TRIANGLE_FAN);
|
||||
t.color(c[0], c[1], c[2], c[3]);
|
||||
t.vertex(0.0f, 100.0f, 0.0f);
|
||||
t.color(c[0], c[1], c[2], 0.0f);
|
||||
|
||||
int steps = 16;
|
||||
for (int i = 0; i <= steps; i++)
|
||||
{
|
||||
float a = i * 3.1415927f * 2.0f / steps;
|
||||
float sin = Mth::sin(a);
|
||||
float cos = Mth::cos(a);
|
||||
t.vertex((sin * 120.0f), (cos * 120.0f), (-cos * 40.0f * c[3]));
|
||||
}
|
||||
|
||||
t.draw();
|
||||
glPopMatrix();
|
||||
// glShadeModel(GL_FLAT); //
|
||||
}
|
||||
|
||||
// gets the time of day and rotates the sun and moon png based on the time
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
glDisable(GL_FOG);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
|
||||
// re ported this again from beta 1.6.6, thanks to the mcpe 0.1 decomp team's code for some bit of help about the void layer - shredder
|
||||
|
||||
// Sunrise
|
||||
if (mc->options.getBooleanValue(OPTIONS_BEAUTIFUL_SKY)) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
Lighting::turnOff();
|
||||
float* c = level->dimension->getSunriseColor(level->getTimeOfDay(alpha), alpha);
|
||||
if (c != nullptr)
|
||||
{
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
// glShadeModel(GL_SMOOTH); //
|
||||
|
||||
glPushMatrix();
|
||||
glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
|
||||
glRotatef(level->getTimeOfDay(alpha) > 0.5f ? 180 : 0, 0.0f, 0.0f, 1.0f);
|
||||
t.begin(GL_TRIANGLE_FAN);
|
||||
t.color(c[0], c[1], c[2], c[3]);
|
||||
t.vertex(0.0f, 100.0f, 0.0f);
|
||||
t.color(c[0], c[1], c[2], 0.0f);
|
||||
|
||||
int steps = 16;
|
||||
for (int i = 0; i <= steps; i++)
|
||||
{
|
||||
float a = i * 3.1415927f * 2.0f / steps;
|
||||
float sin = Mth::sin(a);
|
||||
float cos = Mth::cos(a);
|
||||
t.vertex((sin * 120.0f), (cos * 120.0f), (-cos * 40.0f * c[3]));
|
||||
}
|
||||
|
||||
t.draw();
|
||||
glPopMatrix();
|
||||
// glShadeModel(GL_FLAT); //
|
||||
}
|
||||
|
||||
// gets the time of day and rotates the sun and moon png based on the time
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
glPushMatrix();
|
||||
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
glTranslatef(sc.x, sc.y, sc.z);
|
||||
glRotatef(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glRotatef(level->getTimeOfDay(alpha) * 360.0f, 1.0f, 0.0f, 0.0f);
|
||||
|
||||
float ss = 30.0f;
|
||||
|
||||
|
||||
textures->loadAndBindTexture("terrain/sun.png");
|
||||
t.begin();
|
||||
t.vertexUV(-ss, 100.0f, -ss, 0.0f, 0.0f);
|
||||
t.vertexUV(ss, 100.0f, -ss, 1.0f, 0.0f);
|
||||
t.vertexUV(ss, 100.0f, ss, 1.0f, 1.0f);
|
||||
t.vertexUV(-ss, 100.0f, ss, 0.0f, 1.0f);
|
||||
t.draw();
|
||||
|
||||
ss = 20.0f;
|
||||
textures->loadAndBindTexture("terrain/moon.png");
|
||||
t.begin();
|
||||
t.vertexUV(-ss, -100.0f, ss, 1.0f, 1.0f);
|
||||
t.vertexUV(ss, -100.0f, ss, 0.0f, 1.0f);
|
||||
t.vertexUV(ss, -100.0f, -ss, 0.0f, 0.0f);
|
||||
t.vertexUV(-ss, -100.0f, -ss, 1.0f, 0.0f);
|
||||
t.draw();
|
||||
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
float a = level->getStarBrightness(alpha);
|
||||
if (a > 0.0f)
|
||||
{
|
||||
glColor4f(a, a, a, a);
|
||||
drawArrayVT(starBuffer, starVertexCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
glEnable(GL_FOG);
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
glTranslatef(sc.x, sc.y, sc.z);
|
||||
glRotatef(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glRotatef(level->getTimeOfDay(alpha) * 360.0f, 1.0f, 0.0f, 0.0f);
|
||||
|
||||
float ss = 30.0f;
|
||||
|
||||
|
||||
textures->loadAndBindTexture("terrain/sun.png");
|
||||
t.begin();
|
||||
t.vertexUV(-ss, 100.0f, -ss, 0.0f, 0.0f);
|
||||
t.vertexUV(ss, 100.0f, -ss, 1.0f, 0.0f);
|
||||
t.vertexUV(ss, 100.0f, ss, 1.0f, 1.0f);
|
||||
t.vertexUV(-ss, 100.0f, ss, 0.0f, 1.0f);
|
||||
t.draw();
|
||||
|
||||
ss = 20.0f;
|
||||
textures->loadAndBindTexture("terrain/moon.png");
|
||||
t.begin();
|
||||
t.vertexUV(-ss, -100.0f, ss, 1.0f, 1.0f);
|
||||
t.vertexUV(ss, -100.0f, ss, 0.0f, 1.0f);
|
||||
t.vertexUV(ss, -100.0f, -ss, 0.0f, 0.0f);
|
||||
t.vertexUV(-ss, -100.0f, -ss, 1.0f, 0.0f);
|
||||
t.draw();
|
||||
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
float a = level->getStarBrightness(alpha);
|
||||
if (a > 0.0f)
|
||||
{
|
||||
glColor4f(a, a, a, a);
|
||||
drawArrayVT(starBuffer, starVertexCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
glEnable(GL_FOG);
|
||||
glPopMatrix();
|
||||
|
||||
// ported over void plane (the blue bottom plane seen in java) because pocket edition lacks it @TODO test if it's buggy - shredder
|
||||
|
||||
// glColor3f(sc.x * 0.2f + 0.04f, sc.y * 0.2f + 0.04f, sc.z * 0.6f + 0.1f);
|
||||
glColor4f(sc.x * 0.2f + 0.04f, sc.y * 0.2f + 0.04f, sc.z * 0.6f + 0.1f, 1.0f);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
if(mc->options.getBooleanValue(OPTIONS_BETA_SKY)){
|
||||
drawArrayVT(voidBuffer, voidVertexCount);
|
||||
}
|
||||
|
||||
// glColor3f(sc.x * 0.2f + 0.04f, sc.y * 0.2f + 0.04f, sc.z * 0.6f + 0.1f);
|
||||
glColor4f(sc.x * 0.2f + 0.04f, sc.y * 0.2f + 0.04f, sc.z * 0.6f + 0.1f, 1.0f);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
if(mc->options.getBooleanValue(OPTIONS_BETA_SKY)){
|
||||
drawArrayVT(voidBuffer, voidVertexCount);
|
||||
}
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
// @TODO shredder - should not enable or disable depth mask if using legacy sky because mcpe sky rendering is awful and will render clouds above terrain
|
||||
@@ -1311,194 +1311,195 @@ void LevelRenderer::renderClouds( float alpha ) {
|
||||
glEnable(GL_CULL_FACE);
|
||||
}
|
||||
|
||||
void LevelRenderer::renderAdvancedClouds(float alpha) {
|
||||
|
||||
// ported from java beta, tesselation code for the 3d clouds, renders broken if mcpe sky rendering option is used - shredder
|
||||
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
float px = mc->player->xOld + (mc->player->x - mc->player->xOld) * alpha;
|
||||
float py = mc->player->yOld + (mc->player->y - mc->player->yOld) * alpha;
|
||||
float pz = mc->player->zOld + (mc->player->z - mc->player->zOld) * alpha;
|
||||
|
||||
Tesselator& t = Tesselator::instance;
|
||||
float ss = 12.0f;
|
||||
float h = 4.0f;
|
||||
|
||||
float cloudTime = (float)ticks + alpha;
|
||||
|
||||
float xo = (px + cloudTime * 0.03f) / ss;
|
||||
float zo = pz / ss + 0.33f;
|
||||
|
||||
float yy = 108.0f - py + 0.33f;
|
||||
|
||||
int xWraps = Mth::floor(xo / 2048.0);
|
||||
int zWraps = Mth::floor(zo / 2048.0);
|
||||
xo -= xWraps * 2048;
|
||||
zo -= zWraps * 2048;
|
||||
|
||||
textures->loadAndBindTexture("environment/clouds.png");
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
Vec3 cc = level->getCloudColor(alpha);
|
||||
float cr = cc.x;
|
||||
float cg = cc.y;
|
||||
float cb = cc.z;
|
||||
|
||||
float uvScale = 1.0f / 256.0f;
|
||||
float uo = (float)Mth::floor(xo) * uvScale;
|
||||
float vo = (float)Mth::floor(zo) * uvScale;
|
||||
|
||||
float xOffs = (float)(xo - Mth::floor(xo));
|
||||
float zOffs = (float)(zo - Mth::floor(zo));
|
||||
|
||||
int D = 8;
|
||||
int radius = 3;
|
||||
float e = 1.0f / 1024.0f;
|
||||
|
||||
glPushMatrix();
|
||||
glScalef(ss, 1.0f, ss);
|
||||
|
||||
for (int pass = 0; pass < 2; pass++) {
|
||||
|
||||
if (pass == 0) glColorMask(false, false, false, false);
|
||||
else glColorMask(true, true, true, true);
|
||||
|
||||
for (int xPos = -radius + 1; xPos <= radius; xPos++) {
|
||||
for (int zPos = -radius + 1; zPos <= radius; zPos++) {
|
||||
t.begin();
|
||||
float xx = (float)(xPos * D);
|
||||
float zz = (float)(zPos * D);
|
||||
float xp = xx - xOffs;
|
||||
float zp = zz - zOffs;
|
||||
|
||||
|
||||
if (yy > -h - 1.0f) {
|
||||
t.color(cr * 0.7f, cg * 0.7f, cb * 0.7f, 0.8f);
|
||||
t.normal(0.0f, -1.0f, 0.0f);
|
||||
t.vertexUV(xp + 0, yy + 0, zp + D, (xx + 0) * uvScale + uo, (zz + D) * uvScale + vo);
|
||||
t.vertexUV(xp + D, yy + 0, zp + D, (xx + D) * uvScale + uo, (zz + D) * uvScale + vo);
|
||||
t.vertexUV(xp + D, yy + 0, zp + 0, (xx + D) * uvScale + uo, (zz + 0) * uvScale + vo);
|
||||
t.vertexUV(xp + 0, yy + 0, zp + 0, (xx + 0) * uvScale + uo, (zz + 0) * uvScale + vo);
|
||||
}
|
||||
|
||||
|
||||
if (yy <= h + 1.0f) {
|
||||
t.color(cr, cg, cb, 0.8f);
|
||||
t.normal(0.0f, 1.0f, 0.0f);
|
||||
t.vertexUV(xp + 0, yy + h - e, zp + D, (xx + 0) * uvScale + uo, (zz + D) * uvScale + vo);
|
||||
t.vertexUV(xp + D, yy + h - e, zp + D, (xx + D) * uvScale + uo, (zz + D) * uvScale + vo);
|
||||
t.vertexUV(xp + D, yy + h - e, zp + 0, (xx + D) * uvScale + uo, (zz + 0) * uvScale + vo);
|
||||
t.vertexUV(xp + 0, yy + h - e, zp + 0, (xx + 0) * uvScale + uo, (zz + 0) * uvScale + vo);
|
||||
}
|
||||
|
||||
t.color(cr * 0.9f, cg * 0.9f, cb * 0.9f, 0.8f);
|
||||
|
||||
|
||||
if (xPos > -1) {
|
||||
t.normal(-1.0f, 0.0f, 0.0f);
|
||||
for (int i = 0; i < D; i++) {
|
||||
t.vertexUV(xp + i + 0, yy + 0, zp + D, (xx + i + 0.5f) * uvScale + uo, (zz + D) * uvScale + vo);
|
||||
t.vertexUV(xp + i + 0, yy + h, zp + D, (xx + i + 0.5f) * uvScale + uo, (zz + D) * uvScale + vo);
|
||||
t.vertexUV(xp + i + 0, yy + h, zp + 0, (xx + i + 0.5f) * uvScale + uo, (zz + 0) * uvScale + vo);
|
||||
t.vertexUV(xp + i + 0, yy + 0, zp + 0, (xx + i + 0.5f) * uvScale + uo, (zz + 0) * uvScale + vo);
|
||||
}
|
||||
}
|
||||
if (xPos <= 1) {
|
||||
t.normal(1.0f, 0.0f, 0.0f);
|
||||
for (int i = 0; i < D; i++) {
|
||||
t.vertexUV(xp + i + 1 - e, yy + 0, zp + D, (xx + i + 0.5f) * uvScale + uo, (zz + D) * uvScale + vo);
|
||||
t.vertexUV(xp + i + 1 - e, yy + h, zp + D, (xx + i + 0.5f) * uvScale + uo, (zz + D) * uvScale + vo);
|
||||
t.vertexUV(xp + i + 1 - e, yy + h, zp + 0, (xx + i + 0.5f) * uvScale + uo, (zz + 0) * uvScale + vo);
|
||||
t.vertexUV(xp + i + 1 - e, yy + 0, zp + 0, (xx + i + 0.5f) * uvScale + uo, (zz + 0) * uvScale + vo);
|
||||
}
|
||||
}
|
||||
|
||||
t.color(cr * 0.8f, cg * 0.8f, cb * 0.8f, 0.8f);
|
||||
|
||||
|
||||
if (zPos > -1) {
|
||||
t.normal(0.0f, 0.0f, -1.0f);
|
||||
for (int i = 0; i < D; i++) {
|
||||
t.vertexUV(xp + 0, yy + h, zp + i + 0, (xx + 0) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo);
|
||||
t.vertexUV(xp + D, yy + h, zp + i + 0, (xx + D) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo);
|
||||
t.vertexUV(xp + D, yy + 0, zp + i + 0, (xx + D) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo);
|
||||
t.vertexUV(xp + 0, yy + 0, zp + i + 0, (xx + 0) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo);
|
||||
}
|
||||
}
|
||||
if (zPos <= 1) {
|
||||
t.normal(0.0f, 0.0f, 1.0f);
|
||||
for (int i = 0; i < D; i++) {
|
||||
t.vertexUV(xp + 0, yy + h, zp + i + 1 - e, (xx + 0) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo);
|
||||
t.vertexUV(xp + D, yy + h, zp + i + 1 - e, (xx + D) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo);
|
||||
t.vertexUV(xp + D, yy + 0, zp + i + 1 - e, (xx + D) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo);
|
||||
t.vertexUV(xp + 0, yy + 0, zp + i + 1 - e, (xx + 0) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo);
|
||||
}
|
||||
}
|
||||
t.endOverrideAndDraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_CULL_FACE);
|
||||
void LevelRenderer::renderAdvancedClouds(float alpha) {
|
||||
|
||||
// ported from java beta, tesselation code for the 3d clouds, renders broken if mcpe sky rendering option is used - shredder
|
||||
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
float px = mc->player->xOld + (mc->player->x - mc->player->xOld) * alpha;
|
||||
float py = mc->player->yOld + (mc->player->y - mc->player->yOld) * alpha;
|
||||
float pz = mc->player->zOld + (mc->player->z - mc->player->zOld) * alpha;
|
||||
|
||||
Tesselator& t = Tesselator::instance;
|
||||
float ss = 12.0f;
|
||||
float h = 4.0f;
|
||||
|
||||
float cloudTime = (float)ticks + alpha;
|
||||
|
||||
float xo = (px + cloudTime * 0.03f) / ss;
|
||||
float zo = pz / ss + 0.33f;
|
||||
|
||||
float yy = 108.0f - py + 0.33f;
|
||||
|
||||
int xWraps = Mth::floor(xo / 2048.0);
|
||||
int zWraps = Mth::floor(zo / 2048.0);
|
||||
xo -= xWraps * 2048;
|
||||
zo -= zWraps * 2048;
|
||||
|
||||
textures->loadAndBindTexture("environment/clouds.png");
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
Vec3 cc = level->getCloudColor(alpha);
|
||||
float cr = cc.x;
|
||||
float cg = cc.y;
|
||||
float cb = cc.z;
|
||||
|
||||
float uvScale = 1.0f / 256.0f;
|
||||
float uo = (float)Mth::floor(xo) * uvScale;
|
||||
float vo = (float)Mth::floor(zo) * uvScale;
|
||||
|
||||
float xOffs = (float)(xo - Mth::floor(xo));
|
||||
float zOffs = (float)(zo - Mth::floor(zo));
|
||||
|
||||
int D = 8;
|
||||
int radius = 3;
|
||||
float e = 1.0f / 1024.0f;
|
||||
|
||||
glPushMatrix();
|
||||
glScalef(ss, 1.0f, ss);
|
||||
|
||||
for (int pass = 0; pass < 2; pass++) {
|
||||
|
||||
if (pass == 0) glColorMask(false, false, false, false);
|
||||
else glColorMask(true, true, true, true);
|
||||
|
||||
for (int xPos = -radius + 1; xPos <= radius; xPos++) {
|
||||
for (int zPos = -radius + 1; zPos <= radius; zPos++) {
|
||||
t.begin();
|
||||
float xx = (float)(xPos * D);
|
||||
float zz = (float)(zPos * D);
|
||||
float xp = xx - xOffs;
|
||||
float zp = zz - zOffs;
|
||||
|
||||
|
||||
if (yy > -h - 1.0f) {
|
||||
t.color(cr * 0.7f, cg * 0.7f, cb * 0.7f, 0.8f);
|
||||
t.normal(0.0f, -1.0f, 0.0f);
|
||||
t.vertexUV(xp + 0, yy + 0, zp + D, (xx + 0) * uvScale + uo, (zz + D) * uvScale + vo);
|
||||
t.vertexUV(xp + D, yy + 0, zp + D, (xx + D) * uvScale + uo, (zz + D) * uvScale + vo);
|
||||
t.vertexUV(xp + D, yy + 0, zp + 0, (xx + D) * uvScale + uo, (zz + 0) * uvScale + vo);
|
||||
t.vertexUV(xp + 0, yy + 0, zp + 0, (xx + 0) * uvScale + uo, (zz + 0) * uvScale + vo);
|
||||
}
|
||||
|
||||
|
||||
if (yy <= h + 1.0f) {
|
||||
t.color(cr, cg, cb, 0.8f);
|
||||
t.normal(0.0f, 1.0f, 0.0f);
|
||||
t.vertexUV(xp + 0, yy + h - e, zp + D, (xx + 0) * uvScale + uo, (zz + D) * uvScale + vo);
|
||||
t.vertexUV(xp + D, yy + h - e, zp + D, (xx + D) * uvScale + uo, (zz + D) * uvScale + vo);
|
||||
t.vertexUV(xp + D, yy + h - e, zp + 0, (xx + D) * uvScale + uo, (zz + 0) * uvScale + vo);
|
||||
t.vertexUV(xp + 0, yy + h - e, zp + 0, (xx + 0) * uvScale + uo, (zz + 0) * uvScale + vo);
|
||||
}
|
||||
|
||||
t.color(cr * 0.9f, cg * 0.9f, cb * 0.9f, 0.8f);
|
||||
|
||||
|
||||
if (xPos > -1) {
|
||||
t.normal(-1.0f, 0.0f, 0.0f);
|
||||
for (int i = 0; i < D; i++) {
|
||||
t.vertexUV(xp + i + 0, yy + 0, zp + D, (xx + i + 0.5f) * uvScale + uo, (zz + D) * uvScale + vo);
|
||||
t.vertexUV(xp + i + 0, yy + h, zp + D, (xx + i + 0.5f) * uvScale + uo, (zz + D) * uvScale + vo);
|
||||
t.vertexUV(xp + i + 0, yy + h, zp + 0, (xx + i + 0.5f) * uvScale + uo, (zz + 0) * uvScale + vo);
|
||||
t.vertexUV(xp + i + 0, yy + 0, zp + 0, (xx + i + 0.5f) * uvScale + uo, (zz + 0) * uvScale + vo);
|
||||
}
|
||||
}
|
||||
if (xPos <= 1) {
|
||||
t.normal(1.0f, 0.0f, 0.0f);
|
||||
for (int i = 0; i < D; i++) {
|
||||
t.vertexUV(xp + i + 1 - e, yy + 0, zp + D, (xx + i + 0.5f) * uvScale + uo, (zz + D) * uvScale + vo);
|
||||
t.vertexUV(xp + i + 1 - e, yy + h, zp + D, (xx + i + 0.5f) * uvScale + uo, (zz + D) * uvScale + vo);
|
||||
t.vertexUV(xp + i + 1 - e, yy + h, zp + 0, (xx + i + 0.5f) * uvScale + uo, (zz + 0) * uvScale + vo);
|
||||
t.vertexUV(xp + i + 1 - e, yy + 0, zp + 0, (xx + i + 0.5f) * uvScale + uo, (zz + 0) * uvScale + vo);
|
||||
}
|
||||
}
|
||||
|
||||
t.color(cr * 0.8f, cg * 0.8f, cb * 0.8f, 0.8f);
|
||||
|
||||
|
||||
if (zPos > -1) {
|
||||
t.normal(0.0f, 0.0f, -1.0f);
|
||||
for (int i = 0; i < D; i++) {
|
||||
t.vertexUV(xp + 0, yy + h, zp + i + 0, (xx + 0) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo);
|
||||
t.vertexUV(xp + D, yy + h, zp + i + 0, (xx + D) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo);
|
||||
t.vertexUV(xp + D, yy + 0, zp + i + 0, (xx + D) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo);
|
||||
t.vertexUV(xp + 0, yy + 0, zp + i + 0, (xx + 0) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo);
|
||||
}
|
||||
}
|
||||
if (zPos <= 1) {
|
||||
t.normal(0.0f, 0.0f, 1.0f);
|
||||
for (int i = 0; i < D; i++) {
|
||||
t.vertexUV(xp + 0, yy + h, zp + i + 1 - e, (xx + 0) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo);
|
||||
t.vertexUV(xp + D, yy + h, zp + i + 1 - e, (xx + D) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo);
|
||||
t.vertexUV(xp + D, yy + 0, zp + i + 1 - e, (xx + D) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo);
|
||||
t.vertexUV(xp + 0, yy + 0, zp + i + 1 - e, (xx + 0) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo);
|
||||
}
|
||||
}
|
||||
t.endOverrideAndDraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_CULL_FACE);
|
||||
}
|
||||
|
||||
void LevelRenderer::playSound(const std::string& name, float x, float y, float z, float volume, float pitch) {
|
||||
// @todo: deny sounds here if sound is off (rather than waiting 'til SoundEngine)
|
||||
float dd = 16;
|
||||
|
||||
if (volume > 1) dd *= volume;
|
||||
if (mc->cameraTargetPlayer->distanceToSqr(x, y, z) < dd * dd) {
|
||||
mc->soundEngine->play(name, x, y, z, volume, pitch);
|
||||
}
|
||||
if (volume > 1) dd *= volume;
|
||||
if (mc->cameraTargetPlayer != NULL && mc->cameraTargetPlayer->distanceToSqr(x, y, z) < dd * dd) {
|
||||
mc->soundEngine->play(name, x, y, z, volume, pitch);
|
||||
}
|
||||
}
|
||||
|
||||
void LevelRenderer::addParticle(const std::string& name, float x, float y, float z, float xa, float ya, float za, int data) {
|
||||
if (mc->cameraTargetPlayer != NULL) {
|
||||
float xd = mc->cameraTargetPlayer->x - x;
|
||||
float yd = mc->cameraTargetPlayer->y - y;
|
||||
float zd = mc->cameraTargetPlayer->z - z;
|
||||
float distanceSquared = xd * xd + yd * yd + zd * zd;
|
||||
|
||||
float xd = mc->cameraTargetPlayer->x - x;
|
||||
float yd = mc->cameraTargetPlayer->y - y;
|
||||
float zd = mc->cameraTargetPlayer->z - z;
|
||||
float distanceSquared = xd * xd + yd * yd + zd * zd;
|
||||
//Particle* p = NULL;
|
||||
//if (name == "hugeexplosion") p = new HugeExplosionSeedParticle(level, x, y, z, xa, ya, za);
|
||||
//else if (name == "largeexplode") p = new HugeExplosionParticle(textures, level, x, y, z, xa, ya, za);
|
||||
|
||||
//Particle* p = NULL;
|
||||
//if (name == "hugeexplosion") p = new HugeExplosionSeedParticle(level, x, y, z, xa, ya, za);
|
||||
//else if (name == "largeexplode") p = new HugeExplosionParticle(textures, level, x, y, z, xa, ya, za);
|
||||
//if (p) {
|
||||
// if (distanceSquared < 32 * 32) {
|
||||
// mc->particleEngine->add(p);
|
||||
// } else { delete p; }
|
||||
// return;
|
||||
//}
|
||||
|
||||
//if (p) {
|
||||
// if (distanceSquared < 32 * 32) {
|
||||
// mc->particleEngine->add(p);
|
||||
// } else { delete p; }
|
||||
// return;
|
||||
//}
|
||||
const float particleDistance = 16;
|
||||
if (distanceSquared > particleDistance * particleDistance) return;
|
||||
|
||||
const float particleDistance = 16;
|
||||
if (distanceSquared > particleDistance * particleDistance) return;
|
||||
//static Stopwatch sw;
|
||||
//sw.start();
|
||||
|
||||
//static Stopwatch sw;
|
||||
//sw.start();
|
||||
if (name == "bubble") mc->particleEngine->add(new BubbleParticle(level, x, y, z, xa, ya, za));
|
||||
else if (name == "crit") mc->particleEngine->add(new CritParticle2(level, x, y, z, xa, ya, za));
|
||||
else if (name == "smoke") mc->particleEngine->add(new SmokeParticle(level, x, y, z, xa, ya, za));
|
||||
//else if (name == "note") mc->particleEngine->add(new NoteParticle(level, x, y, z, xa, ya, za));
|
||||
else if (name == "explode") mc->particleEngine->add(new ExplodeParticle(level, x, y, z, xa, ya, za));
|
||||
else if (name == "flame") mc->particleEngine->add(new FlameParticle(level, x, y, z, xa, ya, za));
|
||||
else if (name == "lava") mc->particleEngine->add(new LavaParticle(level, x, y, z));
|
||||
//else if (name == "splash") mc->particleEngine->add(new SplashParticle(level, x, y, z, xa, ya, za));
|
||||
else if (name == "largesmoke") mc->particleEngine->add(new SmokeParticle(level, x, y, z, xa, ya, za, 2.5f));
|
||||
else if (name == "reddust") mc->particleEngine->add(new RedDustParticle(level, x, y, z, xa, ya, za));
|
||||
else if (name == "iconcrack") mc->particleEngine->add(new BreakingItemParticle(level, x, y, z, xa, ya, za, Item::items[data]));
|
||||
else if (name == "snowballpoof") mc->particleEngine->add(new BreakingItemParticle(level, x, y, z, Item::snowBall));
|
||||
//else if (name == "snowballpoof") mc->particleEngine->add(new BreakingItemParticle(level, x, y, z, Item::snowBall));
|
||||
//else if (name == "slime") mc->particleEngine->add(new BreakingItemParticle(level, x, y, z, Item::slimeBall));
|
||||
//else if (name == "heart") mc->particleEngine->add(new HeartParticle(level, x, y, z, xa, ya, za));
|
||||
|
||||
if (name == "bubble") mc->particleEngine->add(new BubbleParticle(level, x, y, z, xa, ya, za));
|
||||
else if (name == "crit") mc->particleEngine->add(new CritParticle2(level, x, y, z, xa, ya, za));
|
||||
else if (name == "smoke") mc->particleEngine->add(new SmokeParticle(level, x, y, z, xa, ya, za));
|
||||
//else if (name == "note") mc->particleEngine->add(new NoteParticle(level, x, y, z, xa, ya, za));
|
||||
else if (name == "explode") mc->particleEngine->add(new ExplodeParticle(level, x, y, z, xa, ya, za));
|
||||
else if (name == "flame") mc->particleEngine->add(new FlameParticle(level, x, y, z, xa, ya, za));
|
||||
else if (name == "lava") mc->particleEngine->add(new LavaParticle(level, x, y, z));
|
||||
//else if (name == "splash") mc->particleEngine->add(new SplashParticle(level, x, y, z, xa, ya, za));
|
||||
else if (name == "largesmoke") mc->particleEngine->add(new SmokeParticle(level, x, y, z, xa, ya, za, 2.5f));
|
||||
else if (name == "reddust") mc->particleEngine->add(new RedDustParticle(level, x, y, z, xa, ya, za));
|
||||
else if (name == "iconcrack") mc->particleEngine->add(new BreakingItemParticle(level, x, y, z, xa, ya, za, Item::items[data]));
|
||||
else if (name == "snowballpoof") mc->particleEngine->add(new BreakingItemParticle(level, x, y, z, Item::snowBall));
|
||||
//else if (name == "snowballpoof") mc->particleEngine->add(new BreakingItemParticle(level, x, y, z, Item::snowBall));
|
||||
//else if (name == "slime") mc->particleEngine->add(new BreakingItemParticle(level, x, y, z, Item::slimeBall));
|
||||
//else if (name == "heart") mc->particleEngine->add(new HeartParticle(level, x, y, z, xa, ya, za));
|
||||
|
||||
//sw.stop();
|
||||
//sw.printEvery(50, "add-particle-string");
|
||||
//sw.stop();
|
||||
//sw.printEvery(50, "add-particle-string");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -77,10 +77,10 @@ void PlayerRenderer::render(Entity* mob_, float x, float y, float z, float rot,
|
||||
model = desired;
|
||||
humanoidModel = desired;
|
||||
}
|
||||
// LOGI("[PlayerRenderer] %s: skin=%s, modelTex=%dx%d, desired=%s\n", // don't log it always, only for debug - shredder
|
||||
// ((Player*)mob)->name.c_str(), mob->getTexture().c_str(),
|
||||
// humanoidModel->texWidth, humanoidModel->texHeight,
|
||||
// (desired == playerModel64 ? "64" : "32"));
|
||||
/* LOGI("[PlayerRenderer] %s: skin=%s, modelTex=%dx%d, desired=%s\n",
|
||||
((Player*)mob)->name.c_str(), mob->getTexture().c_str(),
|
||||
humanoidModel->texWidth, humanoidModel->texHeight,
|
||||
(desired == playerModel64 ? "64" : "32")); */
|
||||
HumanoidMobRenderer::render(mob_, x, y, z, rot, a);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user