Merge pull request 'Fix Whool and block variations n slabs n stuff' (#13) from EpikIzCool/minecraft-pe-0.6.1:main into main

Reviewed-on: #13
This commit was merged in pull request #13.
This commit is contained in:
2026-03-24 16:31:46 +02:00
6 changed files with 768 additions and 794 deletions

View File

@@ -1,69 +1,56 @@
#include "CreativeMode.h"
#include "../Minecraft.h"
#ifndef STANDALONE_SERVER
#include "../particle/ParticleEngine.h"
#endif
#include "../player/LocalPlayer.h"
#ifndef STANDALONE_SERVER
#include "../renderer/LevelRenderer.h"
#include "../sound/SoundEngine.h"
#endif
#include "../../world/level/Level.h"
//#include "../../network/Packet.h"
#include "../../network/packet/RemoveBlockPacket.h"
#include "../../world/entity/player/Abilities.h"
static const int DestructionTickDelay = 5;
CreativeMode::CreativeMode(Minecraft* minecraft)
: super(minecraft)
{
}
void CreativeMode::startDestroyBlock(int x, int y, int z, int face) {
if(minecraft->player->getCarriedItem() != NULL && minecraft->player->getCarriedItem()->id == Item::bow->id)
return;
creativeDestroyBlock(x, y, z, face);
destroyDelay = DestructionTickDelay;
}
void CreativeMode::creativeDestroyBlock(int x, int y, int z, int face) {
minecraft->level->extinguishFire(x, y, z, face);
destroyBlock(x, y, z, face);
}
void CreativeMode::continueDestroyBlock(int x, int y, int z, int face) {
destroyDelay--;
if (destroyDelay <= 0) {
destroyDelay = DestructionTickDelay;
creativeDestroyBlock(x, y, z, face);
}
}
void CreativeMode::stopDestroyBlock() {
destroyDelay = 0;
}
void CreativeMode::initAbilities( Abilities& abilities ) {
abilities.mayfly = true;
abilities.instabuild = true;
abilities.invulnerable = true;
}
bool CreativeMode::isCreativeType() {
return true;
}
void CreativeMode::releaseUsingItem( Player* player ) {
if(player->getCarriedItem() != NULL) {
int oldItemId = player->getCarriedItem()->id;
int oldAux = player->getAuxData();
super::releaseUsingItem(player);
if(player->getCarriedItem() != NULL && player->getCarriedItem()->id == oldItemId) {
player->getCarriedItem()->setAuxValue(oldAux);
}
} else {
super::releaseUsingItem(player);
}
}
#include "CreativeMode.h"
#include "../Minecraft.h"
#ifndef STANDALONE_SERVER
#include "../particle/ParticleEngine.h"
#endif
#include "../player/LocalPlayer.h"
#ifndef STANDALONE_SERVER
#include "../renderer/LevelRenderer.h"
#include "../sound/SoundEngine.h"
#endif
#include "../../world/level/Level.h"
//#include "../../network/Packet.h"
#include "../../network/packet/RemoveBlockPacket.h"
#include "../../world/entity/player/Abilities.h"
static const int DestructionTickDelay = 5;
CreativeMode::CreativeMode(Minecraft* minecraft)
: super(minecraft)
{
}
void CreativeMode::startDestroyBlock(int x, int y, int z, int face) {
if(minecraft->player->getCarriedItem() != NULL && minecraft->player->getCarriedItem()->id == Item::bow->id)
return;
creativeDestroyBlock(x, y, z, face);
destroyDelay = DestructionTickDelay;
}
void CreativeMode::creativeDestroyBlock(int x, int y, int z, int face) {
minecraft->level->extinguishFire(x, y, z, face);
destroyBlock(x, y, z, face);
}
void CreativeMode::continueDestroyBlock(int x, int y, int z, int face) {
destroyDelay--;
if (destroyDelay <= 0) {
destroyDelay = DestructionTickDelay;
creativeDestroyBlock(x, y, z, face);
}
}
void CreativeMode::stopDestroyBlock() {
destroyDelay = 0;
}
void CreativeMode::initAbilities( Abilities& abilities ) {
abilities.mayfly = true;
abilities.instabuild = true;
abilities.invulnerable = true;
}
bool CreativeMode::isCreativeType() {
return true;
}

View File

@@ -1,27 +1,26 @@
#ifndef NET_MINECRAFT_CLIENT_GAMEMODE__CreativeMode_H__
#define NET_MINECRAFT_CLIENT_GAMEMODE__CreativeMode_H__
//package net.minecraft.client.gamemode;
#include "GameMode.h"
class CreativeMode: public GameMode
{
typedef GameMode super;
public:
CreativeMode(Minecraft* minecraft);
void startDestroyBlock(int x, int y, int z, int face);
void continueDestroyBlock(int x, int y, int z, int face);
void stopDestroyBlock();
bool isCreativeType();
void initAbilities(Abilities& abilities);
void releaseUsingItem(Player* player);
private:
void creativeDestroyBlock(int x, int y, int z, int face);
};
#endif /*NET_MINECRAFT_CLIENT_GAMEMODE__CreativeMode_H__*/
#ifndef NET_MINECRAFT_CLIENT_GAMEMODE__CreativeMode_H__
#define NET_MINECRAFT_CLIENT_GAMEMODE__CreativeMode_H__
//package net.minecraft.client.gamemode;
#include "GameMode.h"
class CreativeMode: public GameMode
{
typedef GameMode super;
public:
CreativeMode(Minecraft* minecraft);
void startDestroyBlock(int x, int y, int z, int face);
void continueDestroyBlock(int x, int y, int z, int face);
void stopDestroyBlock();
bool isCreativeType();
void initAbilities(Abilities& abilities);
private:
void creativeDestroyBlock(int x, int y, int z, int face);
};
#endif /*NET_MINECRAFT_CLIENT_GAMEMODE__CreativeMode_H__*/

View File

@@ -1,115 +1,102 @@
#include "CreatorMode.h"
#include "../Minecraft.h"
#include "../particle/ParticleEngine.h"
#include "../player/LocalPlayer.h"
#include "../renderer/LevelRenderer.h"
#include "../sound/SoundEngine.h"
#include "../../world/level/Level.h"
//#include "../../network/Packet.h"
#include "../../network/packet/RemoveBlockPacket.h"
#include "../../world/entity/player/Abilities.h"
static const int DestructionTickDelay = 5;
class Creator: public ICreator {
//virtual void getEvents();
public:
Creator(/*int eventLifeTime*/)
: _tileEvents(32),
_tickId(0)
{
}
void setTick(int tick) {
_tickId = tick;
}
EventList<TileEvent>& getTileEvents() { return _tileEvents; }
void addevent_blockUse(int entityId, int x, int y, int z, int face) {
TileEvent t = {
entityId,
x,y,z,
face
};
_tileEvents.add(t, _tickId);
}
private:
EventList<TileEvent> _tileEvents;
int _tickId;
};
CreatorMode::CreatorMode(Minecraft* minecraft)
: super(minecraft)
{
_creator = new Creator();
}
CreatorMode::~CreatorMode() {
delete _creator;
}
void CreatorMode::startDestroyBlock(int x, int y, int z, int face) {
if(minecraft->player->getCarriedItem() != NULL && minecraft->player->getCarriedItem()->id == Item::bow->id)
return;
CreatorDestroyBlock(x, y, z, face);
destroyDelay = DestructionTickDelay;
}
void CreatorMode::CreatorDestroyBlock(int x, int y, int z, int face) {
minecraft->level->extinguishFire(x, y, z, face);
destroyBlock(x, y, z, face);
}
void CreatorMode::continueDestroyBlock(int x, int y, int z, int face) {
destroyDelay--;
if (destroyDelay <= 0) {
destroyDelay = DestructionTickDelay;
CreatorDestroyBlock(x, y, z, face);
}
}
bool CreatorMode::useItemOn( Player* player, Level* level, ItemInstance* item, int x, int y, int z, int face, const Vec3& hit ) {
if (item && item->id == ((Item*)Item::sword_iron)->id)
_creator->addevent_blockUse(player->entityId, x, y, z, face);
return super::useItemOn(player, level, item, x, y, z, face, hit);
}
void CreatorMode::stopDestroyBlock() {
destroyDelay = 0;
}
void CreatorMode::initAbilities( Abilities& abilities ) {
abilities.mayfly = true;
abilities.instabuild = true;
abilities.invulnerable = true;
}
bool CreatorMode::isCreativeType() {
return true;
}
void CreatorMode::releaseUsingItem( Player* player ) {
if(player->getCarriedItem() != NULL) {
int oldItemId = player->getCarriedItem()->id;
int oldAux = player->getAuxData();
super::releaseUsingItem(player);
if(player->getCarriedItem() != NULL && player->getCarriedItem()->id == oldItemId) {
player->getCarriedItem()->setAuxValue(oldAux);
}
} else {
super::releaseUsingItem(player);
}
}
ICreator* CreatorMode::getCreator() {
return _creator;
}
void CreatorMode::tick() {
_creator->setTick(minecraft->level->getTime());
super::tick();
}
#include "CreatorMode.h"
#include "../Minecraft.h"
#include "../particle/ParticleEngine.h"
#include "../player/LocalPlayer.h"
#include "../renderer/LevelRenderer.h"
#include "../sound/SoundEngine.h"
#include "../../world/level/Level.h"
//#include "../../network/Packet.h"
#include "../../network/packet/RemoveBlockPacket.h"
#include "../../world/entity/player/Abilities.h"
static const int DestructionTickDelay = 5;
class Creator: public ICreator {
//virtual void getEvents();
public:
Creator(/*int eventLifeTime*/)
: _tileEvents(32),
_tickId(0)
{
}
void setTick(int tick) {
_tickId = tick;
}
EventList<TileEvent>& getTileEvents() { return _tileEvents; }
void addevent_blockUse(int entityId, int x, int y, int z, int face) {
TileEvent t = {
entityId,
x,y,z,
face
};
_tileEvents.add(t, _tickId);
}
private:
EventList<TileEvent> _tileEvents;
int _tickId;
};
CreatorMode::CreatorMode(Minecraft* minecraft)
: super(minecraft)
{
_creator = new Creator();
}
CreatorMode::~CreatorMode() {
delete _creator;
}
void CreatorMode::startDestroyBlock(int x, int y, int z, int face) {
if(minecraft->player->getCarriedItem() != NULL && minecraft->player->getCarriedItem()->id == Item::bow->id)
return;
CreatorDestroyBlock(x, y, z, face);
destroyDelay = DestructionTickDelay;
}
void CreatorMode::CreatorDestroyBlock(int x, int y, int z, int face) {
minecraft->level->extinguishFire(x, y, z, face);
destroyBlock(x, y, z, face);
}
void CreatorMode::continueDestroyBlock(int x, int y, int z, int face) {
destroyDelay--;
if (destroyDelay <= 0) {
destroyDelay = DestructionTickDelay;
CreatorDestroyBlock(x, y, z, face);
}
}
bool CreatorMode::useItemOn( Player* player, Level* level, ItemInstance* item, int x, int y, int z, int face, const Vec3& hit ) {
if (item && item->id == ((Item*)Item::sword_iron)->id)
_creator->addevent_blockUse(player->entityId, x, y, z, face);
return super::useItemOn(player, level, item, x, y, z, face, hit);
}
void CreatorMode::stopDestroyBlock() {
destroyDelay = 0;
}
void CreatorMode::initAbilities( Abilities& abilities ) {
abilities.mayfly = true;
abilities.instabuild = true;
abilities.invulnerable = true;
}
bool CreatorMode::isCreativeType() {
return true;
}
ICreator* CreatorMode::getCreator() {
return _creator;
}
void CreatorMode::tick() {
_creator->setTick(minecraft->level->getTime());
super::tick();
}

View File

@@ -1,61 +1,61 @@
#ifndef NET_MINECRAFT_CLIENT_GAMEMODE__CreatorMode_H__
#define NET_MINECRAFT_CLIENT_GAMEMODE__CreatorMode_H__
//package net.minecraft.client.gamemode;
#include "GameMode.h"
#include "../../world/PosTranslator.h"
class ICreator {
public:
virtual ~ICreator() {}
struct TileEvent {
int entityId;
int x, y, z;
int face;
void write(std::stringstream& ss, IPosTranslator& t) const {
int xx = x, yy = y, zz = z;
t.to(xx, yy, zz);
ss << xx << "," << yy << "," << zz << "," << face << "," << entityId;
}
};
template <class T>
class EventList {
public:
EventList(int size) {
_events.reserve(size);
_maxSize = (int)size;
clear();
}
void clear() {
_index = -1;
_size = 0;
}
void add(const T& item, int tick) {
if (_size < _maxSize) {
_events.push_back(Item());
++_size;
}
Item& e = _events[_nextIndex()];
e.item = item;
e.timestamp = tick;
}
int size() const {
return _size;
}
const T& operator[](int i) const {
return _events[_getIndex(i)].item;
}
T& operator[](int i) {
return _events[_getIndex(i)].item;
}
void write(std::stringstream& ss, IPosTranslator& t, int minTimetamp) const {
#ifndef NET_MINECRAFT_CLIENT_GAMEMODE__CreatorMode_H__
#define NET_MINECRAFT_CLIENT_GAMEMODE__CreatorMode_H__
//package net.minecraft.client.gamemode;
#include "GameMode.h"
#include "../../world/PosTranslator.h"
class ICreator {
public:
virtual ~ICreator() {}
struct TileEvent {
int entityId;
int x, y, z;
int face;
void write(std::stringstream& ss, IPosTranslator& t) const {
int xx = x, yy = y, zz = z;
t.to(xx, yy, zz);
ss << xx << "," << yy << "," << zz << "," << face << "," << entityId;
}
};
template <class T>
class EventList {
public:
EventList(int size) {
_events.reserve(size);
_maxSize = (int)size;
clear();
}
void clear() {
_index = -1;
_size = 0;
}
void add(const T& item, int tick) {
if (_size < _maxSize) {
_events.push_back(Item());
++_size;
}
Item& e = _events[_nextIndex()];
e.item = item;
e.timestamp = tick;
}
int size() const {
return _size;
}
const T& operator[](int i) const {
return _events[_getIndex(i)].item;
}
T& operator[](int i) {
return _events[_getIndex(i)].item;
}
void write(std::stringstream& ss, IPosTranslator& t, int minTimetamp) const {
int i = _getFirstNewerIndex(minTimetamp);
if (i < 0)
return;
@@ -66,63 +66,62 @@ public:
ss << "|";
if (++i == _size) i = 0;
}
}
private:
int _getIndex(int i) const { return (1 + _index + i) % _size; }
int _nextIndex() {
if (++_index == _size) _index = 0;
return _index;
}
int _getFirstNewerIndex(int timestamp) const {
for (int i = _index + 1, j = 0; j < _size; ++i, ++j) {
if (i == _size) i = 0;
if (_events[i].timestamp >= timestamp) return i;
}
return -1;
}
struct Item {
int timestamp;
T item;
};
int _index;
int _size;
int _maxSize;
std::vector<Item> _events;
};
virtual EventList<TileEvent>& getTileEvents() = 0;
};
class Creator;
class CreatorMode: public GameMode
{
typedef GameMode super;
public:
CreatorMode(Minecraft* minecraft);
~CreatorMode();
void startDestroyBlock(int x, int y, int z, int face);
void continueDestroyBlock(int x, int y, int z, int face);
void stopDestroyBlock();
bool useItemOn(Player* player, Level* level, ItemInstance* item, int x, int y, int z, int face, const Vec3& hit);
void tick();
ICreator* getCreator();
bool isCreativeType();
void initAbilities(Abilities& abilities);
void releaseUsingItem(Player* player);
private:
void CreatorDestroyBlock(int x, int y, int z, int face);
Creator* _creator;
};
#endif /*NET_MINECRAFT_CLIENT_GAMEMODE__CreatorMode_H__*/
}
private:
int _getIndex(int i) const { return (1 + _index + i) % _size; }
int _nextIndex() {
if (++_index == _size) _index = 0;
return _index;
}
int _getFirstNewerIndex(int timestamp) const {
for (int i = _index + 1, j = 0; j < _size; ++i, ++j) {
if (i == _size) i = 0;
if (_events[i].timestamp >= timestamp) return i;
}
return -1;
}
struct Item {
int timestamp;
T item;
};
int _index;
int _size;
int _maxSize;
std::vector<Item> _events;
};
virtual EventList<TileEvent>& getTileEvents() = 0;
};
class Creator;
class CreatorMode: public GameMode
{
typedef GameMode super;
public:
CreatorMode(Minecraft* minecraft);
~CreatorMode();
void startDestroyBlock(int x, int y, int z, int face);
void continueDestroyBlock(int x, int y, int z, int face);
void stopDestroyBlock();
bool useItemOn(Player* player, Level* level, ItemInstance* item, int x, int y, int z, int face, const Vec3& hit);
void tick();
ICreator* getCreator();
bool isCreativeType();
void initAbilities(Abilities& abilities);
private:
void CreatorDestroyBlock(int x, int y, int z, int face);
Creator* _creator;
};
#endif /*NET_MINECRAFT_CLIENT_GAMEMODE__CreatorMode_H__*/

View File

@@ -1,174 +1,174 @@
#include "GameMode.h"
#include "../Minecraft.h"
#include "../../network/packet/UseItemPacket.h"
#include "../../network/packet/PlayerActionPacket.h"
#include "../../world/level/Level.h"
#include "../../world/item/ItemInstance.h"
#include "../player/LocalPlayer.h"
#include "client/Options.h"
#ifndef STANDALONE_SERVER
#include "../sound/SoundEngine.h"
#include "../particle/ParticleEngine.h"
#endif
#include "../../network/RakNetInstance.h"
#include "../../network/packet/RemoveBlockPacket.h"
#ifndef STANDALONE_SERVER
#include "../renderer/LevelRenderer.h"
#endif
#include "../../world/level/material/Material.h"
GameMode::GameMode( Minecraft* minecraft)
: minecraft(minecraft),
destroyProgress(0),
oDestroyProgress(0),
destroyTicks(0),
destroyDelay(0)
{
}
/*virtual*/
Player* GameMode::createPlayer(Level* level) {
return new LocalPlayer(minecraft, level, minecraft->options.getStringValue(OPTIONS_USERNAME), level->dimension->id, isCreativeType());
}
/*virtual*/
void GameMode::interact(Player* player, Entity* entity) {
player->interact(entity);
}
/*virtual*/
void GameMode::attack(Player* player, Entity* entity) {
if (minecraft->level->adventureSettings.noPvP && entity->isPlayer())
return;
if (minecraft->level->adventureSettings.noPvM && entity->isMob())
return;
player->attack(entity);
}
/* virtual */
void GameMode::startDestroyBlock( int x, int y, int z, int face ) {
if(minecraft->player->getCarriedItem() != NULL && minecraft->player->getCarriedItem()->id == Item::bow->id)
return;
destroyBlock(x, y, z, face);
}
/*virtual*/
bool GameMode::destroyBlock(int x, int y, int z, int face) {
Level* level = minecraft->level;
Tile* oldTile = Tile::tiles[level->getTile(x, y, z)];
if (!oldTile)
return false;
if (level->adventureSettings.immutableWorld) {
if (oldTile != (Tile*)Tile::leaves
&& oldTile->material != Material::plant) {
return false;
}
}
#ifndef STANDALONE_SERVER
minecraft->particleEngine->destroy(x, y, z);
#endif
int data = level->getData(x, y, z);
bool changed = level->setTile(x, y, z, 0);
if (changed) {
#ifndef STANDALONE_SERVER
minecraft->soundEngine->play(oldTile->soundType->getBreakSound(), x + 0.5f, y + 0.5f, z + 0.5f, (oldTile->soundType->getVolume() + 1) / 2, oldTile->soundType->getPitch() * 0.8f);
#endif
oldTile->destroy(level, x, y, z, data);
if (minecraft->options.getBooleanValue(OPTIONS_DESTROY_VIBRATION)) minecraft->platform()->vibrate(24);
if (minecraft->isOnline()) {
RemoveBlockPacket packet(minecraft->player, x, y, z);
minecraft->raknetInstance->send(packet);
}
}
return changed;
}
/*virtual*/
bool GameMode::useItemOn(Player* player, Level* level, ItemInstance* item, int x, int y, int z, int face, const Vec3& hit) {
float clickX = hit.x - x;
float clickY = hit.y - y;
float clickZ = hit.z - z;
item = player->inventory->getSelected();
if(level->isClientSide) {
UseItemPacket packet(x, y, z, face, item, player->entityId, clickX, clickY, clickZ);
minecraft->raknetInstance->send(packet);
}
int t = level->getTile(x, y, z);
if (t == Tile::invisible_bedrock->id) return false;
if (t > 0 && Tile::tiles[t]->use(level, x, y, z, player))
return true;
if (item == NULL) return false;
if(isCreativeType()) {
int aux = item->getAuxValue();
int count = item->count;
bool success = item->useOn(player, level, x, y, z, face, clickX, clickY, clickZ);
item->setAuxValue(aux);
item->count = count;
return success;
} else {
return item->useOn(player, level, x, y, z, face, clickX, clickY, clickZ);
}
}
bool GameMode::useItem( Player* player, Level* level, ItemInstance* item ) {
int oldCount = item->count;
ItemInstance* itemInstance = item->use(level, player);
if(level->isClientSide) {
UseItemPacket packet(item, player->entityId, player->aimDirection);
minecraft->raknetInstance->send(packet);
}
if (itemInstance != item || (itemInstance != NULL && itemInstance->count != oldCount)) {
//player.inventory.items[player.inventory.selected] = itemInstance;
//if (itemInstance.count == 0) {
// player.inventory.items[player.inventory.selected] = NULL;
//}
return true;
}
return false;
}
ItemInstance* GameMode::handleInventoryMouseClick( int containerId, int slotNum, int buttonNum, Player* player ) {
//return player.containerMenu.clicked(slotNum, buttonNum, player);
return NULL;
}
void GameMode::handleCloseInventory( int containerId, Player* player ) {
//player.containerMenu.removed(player);
//player.containerMenu = player.inventoryMenu;
}
float GameMode::getPickRange() {
return 5.0f;
}
void GameMode::initPlayer( Player* player ) {
initAbilities(player->abilities);
}
void GameMode::releaseUsingItem(Player* player){
if(minecraft->level->isClientSide) {
PlayerActionPacket packet(PlayerActionPacket::RELEASE_USE_ITEM, 0, 0, 0, 0, player->entityId);
minecraft->raknetInstance->send(packet);
}
player->releaseUsingItem();
}
void GameMode::tick() {
oDestroyProgress = destroyProgress;
}
void GameMode::render( float a ) {
#ifndef STANDALONE_SERVER
if (destroyProgress <= 0) {
minecraft->gui.progress = 0;
minecraft->levelRenderer->destroyProgress = 0;
} else {
float dp = oDestroyProgress + (destroyProgress - oDestroyProgress) * a;
minecraft->gui.progress = dp;
minecraft->levelRenderer->destroyProgress = dp;
}
#endif
}
#include "GameMode.h"
#include "../Minecraft.h"
#include "../../network/packet/UseItemPacket.h"
#include "../../network/packet/PlayerActionPacket.h"
#include "../../world/level/Level.h"
#include "../../world/item/ItemInstance.h"
#include "../player/LocalPlayer.h"
#include "client/Options.h"
#ifndef STANDALONE_SERVER
#include "../sound/SoundEngine.h"
#include "../particle/ParticleEngine.h"
#endif
#include "../../network/RakNetInstance.h"
#include "../../network/packet/RemoveBlockPacket.h"
#ifndef STANDALONE_SERVER
#include "../renderer/LevelRenderer.h"
#endif
#include "../../world/level/material/Material.h"
GameMode::GameMode( Minecraft* minecraft)
: minecraft(minecraft),
destroyProgress(0),
oDestroyProgress(0),
destroyTicks(0),
destroyDelay(0)
{
}
/*virtual*/
Player* GameMode::createPlayer(Level* level) {
return new LocalPlayer(minecraft, level, minecraft->options.getStringValue(OPTIONS_USERNAME), level->dimension->id, isCreativeType());
}
/*virtual*/
void GameMode::interact(Player* player, Entity* entity) {
player->interact(entity);
}
/*virtual*/
void GameMode::attack(Player* player, Entity* entity) {
if (minecraft->level->adventureSettings.noPvP && entity->isPlayer())
return;
if (minecraft->level->adventureSettings.noPvM && entity->isMob())
return;
player->attack(entity);
}
/* virtual */
void GameMode::startDestroyBlock( int x, int y, int z, int face ) {
if(minecraft->player->getCarriedItem() != NULL && minecraft->player->getCarriedItem()->id == Item::bow->id)
return;
destroyBlock(x, y, z, face);
}
/*virtual*/
bool GameMode::destroyBlock(int x, int y, int z, int face) {
Level* level = minecraft->level;
Tile* oldTile = Tile::tiles[level->getTile(x, y, z)];
if (!oldTile)
return false;
if (level->adventureSettings.immutableWorld) {
if (oldTile != (Tile*)Tile::leaves
&& oldTile->material != Material::plant) {
return false;
}
}
#ifndef STANDALONE_SERVER
minecraft->particleEngine->destroy(x, y, z);
#endif
int data = level->getData(x, y, z);
bool changed = level->setTile(x, y, z, 0);
if (changed) {
#ifndef STANDALONE_SERVER
minecraft->soundEngine->play(oldTile->soundType->getBreakSound(), x + 0.5f, y + 0.5f, z + 0.5f, (oldTile->soundType->getVolume() + 1) / 2, oldTile->soundType->getPitch() * 0.8f);
#endif
oldTile->destroy(level, x, y, z, data);
if (minecraft->options.getBooleanValue(OPTIONS_DESTROY_VIBRATION)) minecraft->platform()->vibrate(24);
if (minecraft->isOnline()) {
RemoveBlockPacket packet(minecraft->player, x, y, z);
minecraft->raknetInstance->send(packet);
}
}
return changed;
}
/*virtual*/
bool GameMode::useItemOn(Player* player, Level* level, ItemInstance* item, int x, int y, int z, int face, const Vec3& hit) {
float clickX = hit.x - x;
float clickY = hit.y - y;
float clickZ = hit.z - z;
if (level->isClientSide) {
item = player->inventory->getSelected();
UseItemPacket packet(x, y, z, face, item, player->entityId, clickX, clickY, clickZ);
minecraft->raknetInstance->send(packet);
}
int t = level->getTile(x, y, z);
if (t == Tile::invisible_bedrock->id) return false;
if (t > 0 && Tile::tiles[t]->use(level, x, y, z, player))
return true;
if (item == NULL) return false;
if(isCreativeType()) {
int aux = item->getAuxValue();
int count = item->count;
bool success = item->useOn(player, level, x, y, z, face, clickX, clickY, clickZ);
item->setAuxValue(aux);
item->count = count;
return success;
} else {
return item->useOn(player, level, x, y, z, face, clickX, clickY, clickZ);
}
}
bool GameMode::useItem( Player* player, Level* level, ItemInstance* item ) {
int oldCount = item->count;
ItemInstance* itemInstance = item->use(level, player);
if(level->isClientSide) {
UseItemPacket packet(item, player->entityId, player->aimDirection);
minecraft->raknetInstance->send(packet);
}
if (itemInstance != item || (itemInstance != NULL && itemInstance->count != oldCount)) {
//player.inventory.items[player.inventory.selected] = itemInstance;
//if (itemInstance.count == 0) {
// player.inventory.items[player.inventory.selected] = NULL;
//}
return true;
}
return false;
}
ItemInstance* GameMode::handleInventoryMouseClick( int containerId, int slotNum, int buttonNum, Player* player ) {
//return player.containerMenu.clicked(slotNum, buttonNum, player);
return NULL;
}
void GameMode::handleCloseInventory( int containerId, Player* player ) {
//player.containerMenu.removed(player);
//player.containerMenu = player.inventoryMenu;
}
float GameMode::getPickRange() {
return 5.0f;
}
void GameMode::initPlayer( Player* player ) {
initAbilities(player->abilities);
}
void GameMode::releaseUsingItem(Player* player){
if (minecraft->level->isClientSide && player->isUsingItem()) {
PlayerActionPacket packet(PlayerActionPacket::RELEASE_USE_ITEM, 0, 0, 0, 0, player->entityId);
minecraft->raknetInstance->send(packet);
}
player->releaseUsingItem();
}
void GameMode::tick() {
oDestroyProgress = destroyProgress;
}
void GameMode::render( float a ) {
#ifndef STANDALONE_SERVER
if (destroyProgress <= 0) {
minecraft->gui.progress = 0;
minecraft->levelRenderer->destroyProgress = 0;
} else {
float dp = oDestroyProgress + (destroyProgress - oDestroyProgress) * a;
minecraft->gui.progress = dp;
minecraft->levelRenderer->destroyProgress = dp;
}
#endif
}

View File

@@ -1,291 +1,293 @@
#include "TouchIngameBlockSelectionScreen.h"
#include "../crafting/WorkbenchScreen.h"
#include "../../Screen.h"
#include "../../components/ImageButton.h"
#include "../../components/InventoryPane.h"
#include "../../../gamemode/GameMode.h"
#include "../../../renderer/TileRenderer.h"
#include "../../../player/LocalPlayer.h"
#include "../../../renderer/gles.h"
#include "../../../renderer/entity/ItemRenderer.h"
#include "../../../renderer/Tesselator.h"
#include "../../../renderer/Textures.h"
#include "../../../Minecraft.h"
#include "../../../sound/SoundEngine.h"
#include "../../../../world/entity/player/Inventory.h"
#include "../../../../platform/input/Mouse.h"
#include "../../../../util/Mth.h"
#include "../../../../world/item/ItemInstance.h"
#include "../../../../world/entity/player/Player.h"
#include "../../../../world/item/crafting/Recipe.h"
#include "../../../player/input/touchscreen/TouchAreaModel.h"
#include "../ArmorScreen.h"
namespace Touch {
#if defined(__APPLE__)
static const std::string demoVersionString("Not available in the Lite version");
#else
static const std::string demoVersionString("Not available in the demo version");
#endif
#ifdef __APPLE__
static const float BorderPixels = 4;
#ifdef DEMO_MODE
static const float BlockPixels = 22;
#else
static const float BlockPixels = 22;
#endif
#else
static const float BorderPixels = 4;
static const float BlockPixels = 24;
#endif
static const int ItemSize = (int)(BlockPixels + 2*BorderPixels);
static const int Bx = 10; // Border Frame width
static const int By = 6; // Border Frame height
//
// Block selection screen
//
IngameBlockSelectionScreen::IngameBlockSelectionScreen()
: selectedItem(0),
_blockList(NULL),
_pendingClose(false),
bArmor (4, "Armor"),
bDone (3, ""),
//bDone (3, "Done"),
bMenu (2, "Menu"),
bCraft (1, "Craft"),
bHeader (0, "Select blocks")
{
}
IngameBlockSelectionScreen::~IngameBlockSelectionScreen()
{
delete _blockList;
}
void IngameBlockSelectionScreen::init()
{
Inventory* inventory = minecraft->player->inventory;
//const int itemWidth = 2 * BorderPixels +
int maxWidth = width - Bx - Bx;
InventoryColumns = maxWidth / ItemSize;
const int realWidth = InventoryColumns * ItemSize;
const int realBx = (width - realWidth) / 2;
IntRectangle rect(realBx,
#ifdef __APPLE__
24 + By - ((width==240)?1:0), realWidth, ((width==240)?1:0) + height-By-By-20-24);
#else
24 + By, realWidth, height-By-By-20-24);
#endif
_blockList = new InventoryPane(this, minecraft, rect, width, BorderPixels, inventory->getContainerSize() - Inventory::MAX_SELECTION_SIZE, ItemSize, (int)BorderPixels);
_blockList->fillMarginX = realBx;
//for (int i = 0; i < inventory->getContainerSize(); ++i)
//LOGI("> %d - %s\n", i, inventory->getItem(i)? inventory->getItem(i)->getDescriptionId().c_str() : "<-->\n");
InventorySize = inventory->getContainerSize();
InventoryRows = 1 + (InventorySize-1) / InventoryColumns;
//
// Buttons
//
ImageDef def;
def.name = "gui/spritesheet.png";
def.x = 0;
def.y = 1;
def.width = def.height = 18;
def.setSrc(IntRectangle(60, 0, 18, 18));
bDone.setImageDef(def, true);
bDone.width = bDone.height = 19;
bDone.scaleWhenPressed = false;
buttons.push_back(&bHeader);
buttons.push_back(&bDone);
if (!minecraft->isCreativeMode()) {
buttons.push_back(&bCraft);
buttons.push_back(&bArmor);
}
}
void IngameBlockSelectionScreen::setupPositions() {
bHeader.y = bDone.y = bCraft.y = 0;
bDone.x = width - bDone.width;
bCraft.x = 0;//width - bDone.w - bCraft.w;
bCraft.width = bArmor.width = 48;
bArmor.x = bCraft.width;
if (minecraft->isCreativeMode()) {
bHeader.x = 0;
bHeader.width = width;// - bDone.w;
bHeader.xText = width/2; // Center of the screen
} else {
bHeader.x = bCraft.width + bArmor.width;
bHeader.width = width - bCraft.width - bArmor.width;// - bDone.w;
bHeader.xText = bHeader.x + (bHeader.width - bDone.width) /2;
}
clippingArea.x = 0;
clippingArea.w = minecraft->width;
clippingArea.y = 0;
clippingArea.h = (int)(Gui::GuiScale * 24);
}
void IngameBlockSelectionScreen::removed()
{
minecraft->gui.inventoryUpdated();
}
int IngameBlockSelectionScreen::getSlotPosX(int slotX) {
// @todo: Number of columns
return width / 2 - InventoryColumns * 10 + slotX * 20 + 2;
}
int IngameBlockSelectionScreen::getSlotPosY(int slotY) {
return height - 16 - 3 - 22 * 2 - 22 * slotY;
}
int IngameBlockSelectionScreen::getSlotHeight() {
// same as non-touch implementation
return 22;
}
void IngameBlockSelectionScreen::mouseClicked(int x, int y, int buttonNum) {
_pendingClose = _blockList->_clickArea->isInside((float)x, (float)y);
if (!_pendingClose)
super::mouseClicked(x, y, buttonNum);
}
void IngameBlockSelectionScreen::mouseReleased(int x, int y, int buttonNum) {
if (_pendingClose && _blockList->_clickArea->isInside((float)x, (float)y))
minecraft->setScreen(NULL);
else
super::mouseReleased(x, y, buttonNum);
}
void IngameBlockSelectionScreen::mouseWheel(int dx, int dy, int xm, int ym)
{
if (dy == 0) return;
if (_blockList) {
float amount = -dy * getSlotHeight();
_blockList->scrollBy(0, amount);
}
int cols = InventoryColumns;
int maxIndex = InventorySize - 1;
int idx = selectedItem;
if (dy > 0) {
if (idx >= cols) idx -= cols;
} else {
if (idx + cols <= maxIndex) idx += cols;
}
selectedItem = idx;
}
bool IngameBlockSelectionScreen::addItem(const InventoryPane* pane, int itemId)
{
Inventory* inventory = minecraft->player->inventory;
itemId += Inventory::MAX_SELECTION_SIZE;
if (!inventory->getItem(itemId))
return false;
inventory->moveToSelectionSlot(0, itemId, true);
inventory->selectSlot(0);
#ifdef __APPLE__
minecraft->soundEngine->playUI("random.pop", 0.3f, 0.3f);//1.0f + 0.2f*(Mth::random()-Mth::random()));
#else
minecraft->soundEngine->playUI("random.pop2", 1.0f, 0.3f);//1.0f + 0.2f*(Mth::random()-Mth::random()));
#endif
// Flash the selected gui item
minecraft->gui.flashSlot(inventory->selected);
return true;
}
void IngameBlockSelectionScreen::tick()
{
_blockList->tick();
super::tick();
}
void IngameBlockSelectionScreen::render( int xm, int ym, float a )
{
glDisable2(GL_DEPTH_TEST);
glEnable2(GL_BLEND);
Screen::render(xm, ym, a);
_blockList->render(xm, ym, a);
// render frame
IntRectangle& bbox = _blockList->rect;
Tesselator::instance.colorABGR(0xffffffff);
minecraft->textures->loadAndBindTexture("gui/itemframe.png");
glEnable2(GL_BLEND);
glColor4f2(1, 1, 1, 1);
glBlendFunc2(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
blit(0, bbox.y-By, 0, 0, width, bbox.h+By+By, 215, 256); // why bbox.h + 1*B?
glDisable2(GL_BLEND);
glEnable2(GL_DEPTH_TEST);
}
void IngameBlockSelectionScreen::renderDemoOverlay() {
#ifdef DEMO_MODE
fill( getSlotPosX(0) - 3, getSlotPosY(1) - 3,
getSlotPosX(9) - 3, getSlotPosY(-1) - 3, 0xa0 << 24);
const int centerX = (getSlotPosX(4) + getSlotPosX(5)) / 2;
const int centerY = (getSlotPosY(0) + getSlotPosY(1)) / 2 + 5;
drawCenteredString(minecraft->font, demoVersionString, centerX, centerY, 0xffffffff);
#endif /*DEMO_MODE*/
}
void IngameBlockSelectionScreen::buttonClicked(Button* button) {
if (button->id == bDone.id)
minecraft->setScreen(NULL);
if (button->id == bMenu.id)
minecraft->screenChooser.setScreen(SCREEN_PAUSE);
if (button->id == bCraft.id)
minecraft->setScreen(new WorkbenchScreen(Recipe::SIZE_2X2));
if (button == &bArmor)
minecraft->setScreen(new ArmorScreen());
}
bool IngameBlockSelectionScreen::isAllowed( int slot )
{
if (slot < 0 || slot >= minecraft->player->inventory->getContainerSize())
return false;
#ifdef DEMO_MODE
if (slot >= (minecraft->isCreativeMode()? 28 : 27)) return false;
#endif
return true;
}
bool IngameBlockSelectionScreen::hasClippingArea( IntRectangle& out )
{
out = clippingArea;
return true;
}
std::vector<const ItemInstance*> IngameBlockSelectionScreen::getItems( const InventoryPane* forPane )
{
std::vector<const ItemInstance*> out;
for (int i = Inventory::MAX_SELECTION_SIZE; i < minecraft->player->inventory->getContainerSize(); ++i)
out.push_back(minecraft->player->inventory->getItem(i));
return out;
}
}
#include "TouchIngameBlockSelectionScreen.h"
#include "../crafting/WorkbenchScreen.h"
#include "../../Screen.h"
#include "../../components/ImageButton.h"
#include "../../components/InventoryPane.h"
#include "../../../gamemode/GameMode.h"
#include "../../../renderer/TileRenderer.h"
#include "../../../player/LocalPlayer.h"
#include "../../../renderer/gles.h"
#include "../../../renderer/entity/ItemRenderer.h"
#include "../../../renderer/Tesselator.h"
#include "../../../renderer/Textures.h"
#include "../../../Minecraft.h"
#include "../../../sound/SoundEngine.h"
#include "../../../../world/entity/player/Inventory.h"
#include "../../../../platform/input/Mouse.h"
#include "../../../../util/Mth.h"
#include "../../../../world/item/ItemInstance.h"
#include "../../../../world/entity/player/Player.h"
#include "../../../../world/item/crafting/Recipe.h"
#include "../../../player/input/touchscreen/TouchAreaModel.h"
#include "../ArmorScreen.h"
namespace Touch {
#if defined(__APPLE__)
static const std::string demoVersionString("Not available in the Lite version");
#else
static const std::string demoVersionString("Not available in the demo version");
#endif
#ifdef __APPLE__
static const float BorderPixels = 4;
#ifdef DEMO_MODE
static const float BlockPixels = 22;
#else
static const float BlockPixels = 22;
#endif
#else
static const float BorderPixels = 4;
static const float BlockPixels = 24;
#endif
static const int ItemSize = (int)(BlockPixels + 2*BorderPixels);
static const int Bx = 10; // Border Frame width
static const int By = 6; // Border Frame height
//
// Block selection screen
//
IngameBlockSelectionScreen::IngameBlockSelectionScreen()
: selectedItem(0),
_blockList(NULL),
_pendingClose(false),
bArmor (4, "Armor"),
bDone (3, ""),
//bDone (3, "Done"),
bMenu (2, "Menu"),
bCraft (1, "Craft"),
bHeader (0, "Select blocks")
{
}
IngameBlockSelectionScreen::~IngameBlockSelectionScreen()
{
delete _blockList;
}
void IngameBlockSelectionScreen::init()
{
Inventory* inventory = minecraft->player->inventory;
//const int itemWidth = 2 * BorderPixels +
int maxWidth = width - Bx - Bx;
InventoryColumns = maxWidth / ItemSize;
const int realWidth = InventoryColumns * ItemSize;
const int realBx = (width - realWidth) / 2;
IntRectangle rect(realBx,
#ifdef __APPLE__
24 + By - ((width==240)?1:0), realWidth, ((width==240)?1:0) + height-By-By-20-24);
#else
24 + By, realWidth, height-By-By-20-24);
#endif
_blockList = new InventoryPane(this, minecraft, rect, width, BorderPixels, inventory->getContainerSize() - Inventory::MAX_SELECTION_SIZE, ItemSize, (int)BorderPixels);
_blockList->fillMarginX = realBx;
//for (int i = 0; i < inventory->getContainerSize(); ++i)
//LOGI("> %d - %s\n", i, inventory->getItem(i)? inventory->getItem(i)->getDescriptionId().c_str() : "<-->\n");
// Grid indices are 0..N-1 for main inventory only; slots 0..MAX_SELECTION_SIZE-1 are hotbar links.
InventorySize = inventory->getContainerSize() - Inventory::MAX_SELECTION_SIZE;
InventoryRows = 1 + (InventorySize-1) / InventoryColumns;
//
// Buttons
//
ImageDef def;
def.name = "gui/spritesheet.png";
def.x = 0;
def.y = 1;
def.width = def.height = 18;
def.setSrc(IntRectangle(60, 0, 18, 18));
bDone.setImageDef(def, true);
bDone.width = bDone.height = 19;
bDone.scaleWhenPressed = false;
buttons.push_back(&bHeader);
buttons.push_back(&bDone);
if (!minecraft->isCreativeMode()) {
buttons.push_back(&bCraft);
buttons.push_back(&bArmor);
}
}
void IngameBlockSelectionScreen::setupPositions() {
bHeader.y = bDone.y = bCraft.y = 0;
bDone.x = width - bDone.width;
bCraft.x = 0;//width - bDone.w - bCraft.w;
bCraft.width = bArmor.width = 48;
bArmor.x = bCraft.width;
if (minecraft->isCreativeMode()) {
bHeader.x = 0;
bHeader.width = width;// - bDone.w;
bHeader.xText = width/2; // Center of the screen
} else {
bHeader.x = bCraft.width + bArmor.width;
bHeader.width = width - bCraft.width - bArmor.width;// - bDone.w;
bHeader.xText = bHeader.x + (bHeader.width - bDone.width) /2;
}
clippingArea.x = 0;
clippingArea.w = minecraft->width;
clippingArea.y = 0;
clippingArea.h = (int)(Gui::GuiScale * 24);
}
void IngameBlockSelectionScreen::removed()
{
minecraft->gui.inventoryUpdated();
}
int IngameBlockSelectionScreen::getSlotPosX(int slotX) {
// @todo: Number of columns
return width / 2 - InventoryColumns * 10 + slotX * 20 + 2;
}
int IngameBlockSelectionScreen::getSlotPosY(int slotY) {
return height - 16 - 3 - 22 * 2 - 22 * slotY;
}
int IngameBlockSelectionScreen::getSlotHeight() {
// same as non-touch implementation
return 22;
}
void IngameBlockSelectionScreen::mouseClicked(int x, int y, int buttonNum) {
_pendingClose = _blockList->_clickArea->isInside((float)x, (float)y);
if (!_pendingClose)
super::mouseClicked(x, y, buttonNum);
}
void IngameBlockSelectionScreen::mouseReleased(int x, int y, int buttonNum) {
if (_pendingClose && _blockList->_clickArea->isInside((float)x, (float)y))
minecraft->setScreen(NULL);
else
super::mouseReleased(x, y, buttonNum);
}
void IngameBlockSelectionScreen::mouseWheel(int dx, int dy, int xm, int ym)
{
if (dy == 0) return;
if (_blockList) {
float amount = -dy * getSlotHeight();
_blockList->scrollBy(0, amount);
}
int cols = InventoryColumns;
int maxIndex = InventorySize - 1;
int idx = selectedItem;
if (dy > 0) {
if (idx >= cols) idx -= cols;
} else {
if (idx + cols <= maxIndex) idx += cols;
}
selectedItem = idx;
}
bool IngameBlockSelectionScreen::addItem(const InventoryPane* pane, int itemId)
{
Inventory* inventory = minecraft->player->inventory;
itemId += Inventory::MAX_SELECTION_SIZE;
if (!inventory->getItem(itemId))
return false;
inventory->moveToSelectionSlot(0, itemId, true);
inventory->selectSlot(0);
#ifdef __APPLE__
minecraft->soundEngine->playUI("random.pop", 0.3f, 0.3f);//1.0f + 0.2f*(Mth::random()-Mth::random()));
#else
minecraft->soundEngine->playUI("random.pop2", 1.0f, 0.3f);//1.0f + 0.2f*(Mth::random()-Mth::random()));
#endif
// Flash the selected gui item
minecraft->gui.flashSlot(inventory->selected);
return true;
}
void IngameBlockSelectionScreen::tick()
{
_blockList->tick();
super::tick();
}
void IngameBlockSelectionScreen::render( int xm, int ym, float a )
{
glDisable2(GL_DEPTH_TEST);
glEnable2(GL_BLEND);
Screen::render(xm, ym, a);
_blockList->render(xm, ym, a);
// render frame
IntRectangle& bbox = _blockList->rect;
Tesselator::instance.colorABGR(0xffffffff);
minecraft->textures->loadAndBindTexture("gui/itemframe.png");
glEnable2(GL_BLEND);
glColor4f2(1, 1, 1, 1);
glBlendFunc2(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
blit(0, bbox.y-By, 0, 0, width, bbox.h+By+By, 215, 256); // why bbox.h + 1*B?
glDisable2(GL_BLEND);
glEnable2(GL_DEPTH_TEST);
}
void IngameBlockSelectionScreen::renderDemoOverlay() {
#ifdef DEMO_MODE
fill( getSlotPosX(0) - 3, getSlotPosY(1) - 3,
getSlotPosX(9) - 3, getSlotPosY(-1) - 3, 0xa0 << 24);
const int centerX = (getSlotPosX(4) + getSlotPosX(5)) / 2;
const int centerY = (getSlotPosY(0) + getSlotPosY(1)) / 2 + 5;
drawCenteredString(minecraft->font, demoVersionString, centerX, centerY, 0xffffffff);
#endif /*DEMO_MODE*/
}
void IngameBlockSelectionScreen::buttonClicked(Button* button) {
if (button->id == bDone.id)
minecraft->setScreen(NULL);
if (button->id == bMenu.id)
minecraft->screenChooser.setScreen(SCREEN_PAUSE);
if (button->id == bCraft.id)
minecraft->setScreen(new WorkbenchScreen(Recipe::SIZE_2X2));
if (button == &bArmor)
minecraft->setScreen(new ArmorScreen());
}
bool IngameBlockSelectionScreen::isAllowed( int slot )
{
const int gridCount = minecraft->player->inventory->getContainerSize() - Inventory::MAX_SELECTION_SIZE;
if (slot < 0 || slot >= gridCount)
return false;
#ifdef DEMO_MODE
if (slot >= (minecraft->isCreativeMode()? 28 : 27)) return false;
#endif
return true;
}
bool IngameBlockSelectionScreen::hasClippingArea( IntRectangle& out )
{
out = clippingArea;
return true;
}
std::vector<const ItemInstance*> IngameBlockSelectionScreen::getItems( const InventoryPane* forPane )
{
std::vector<const ItemInstance*> out;
for (int i = Inventory::MAX_SELECTION_SIZE; i < minecraft->player->inventory->getContainerSize(); ++i)
out.push_back(minecraft->player->inventory->getItem(i));
return out;
}
}