aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.Client/MultiPlayerGameMode.cpp
diff options
context:
space:
mode:
authordaoge <3523206925@qq.com>2026-03-03 03:04:10 +0800
committerGitHub <noreply@github.com>2026-03-03 03:04:10 +0800
commitb3feddfef372618c8a9d7a0abcaf18cfad866c18 (patch)
tree267761c3bb39241ba5c347bfbe2254d06686e287 /Minecraft.Client/MultiPlayerGameMode.cpp
parent84c31a2331f7a0ec85b9d438992e244f60e5020f (diff)
feat: TU19 (Dec 2014) Features & Content (#155)
* try to resolve merge conflict * feat: TU19 (Dec 2014) Features & Content (#32) * December 2014 files * Working release build * Fix compilation issues * Add sound to Windows64Media * Add DLC content and force Tutorial DLC * Revert "Add DLC content and force Tutorial DLC" This reverts commit 97a43994725008e35fceb984d5549df9c8cea470. * Disable broken light packing * Disable breakpoint during DLC texture map load Allows DLC loading but the DLC textures are still broken * Fix post build not working * ... * fix vs2022 build * fix cmake build --------- Co-authored-by: Loki <lokirautio@gmail.com>
Diffstat (limited to 'Minecraft.Client/MultiPlayerGameMode.cpp')
-rw-r--r--Minecraft.Client/MultiPlayerGameMode.cpp121
1 files changed, 81 insertions, 40 deletions
diff --git a/Minecraft.Client/MultiPlayerGameMode.cpp b/Minecraft.Client/MultiPlayerGameMode.cpp
index 7de59803..cbf8a7ab 100644
--- a/Minecraft.Client/MultiPlayerGameMode.cpp
+++ b/Minecraft.Client/MultiPlayerGameMode.cpp
@@ -19,8 +19,8 @@ MultiPlayerGameMode::MultiPlayerGameMode(Minecraft *minecraft, ClientConnection
xDestroyBlock = -1;
yDestroyBlock = -1;
zDestroyBlock = -1;
+ destroyingItem = nullptr;
destroyProgress = 0;
- oDestroyProgress = 0;
destroyTicks = 0;
destroyDelay = 0;
isDestroying = false;
@@ -66,10 +66,19 @@ bool MultiPlayerGameMode::canHurtPlayer()
bool MultiPlayerGameMode::destroyBlock(int x, int y, int z, int face)
{
- if (localPlayerMode->isReadOnly())
+ if (localPlayerMode->isAdventureRestricted()) {
+ if (!minecraft->player->mayDestroyBlockAt(x, y, z)) {
+ return false;
+ }
+ }
+
+ if (localPlayerMode->isCreative())
{
- return false;
- }
+ if (minecraft->player->getCarriedItem() != NULL && dynamic_cast<WeaponItem *>(minecraft->player->getCarriedItem()->getItem()) != NULL)
+ {
+ return false;
+ }
+ }
Level *level = minecraft->level;
Tile *oldTile = Tile::tiles[level->getTile(x, y, z)];
@@ -79,11 +88,12 @@ bool MultiPlayerGameMode::destroyBlock(int x, int y, int z, int face)
level->levelEvent(LevelEvent::PARTICLES_DESTROY_BLOCK, x, y, z, oldTile->id + (level->getData(x, y, z) << Tile::TILE_NUM_SHIFT));
int data = level->getData(x, y, z);
- bool changed = level->setTile(x, y, z, 0);
+ bool changed = level->removeTile(x, y, z);
if (changed)
{
oldTile->destroy(level, x, y, z, data);
}
+ yDestroyBlock = -1;
if (!localPlayerMode->isCreative())
{
@@ -104,10 +114,14 @@ bool MultiPlayerGameMode::destroyBlock(int x, int y, int z, int face)
void MultiPlayerGameMode::startDestroyBlock(int x, int y, int z, int face)
{
if(!minecraft->player->isAllowedToMine()) return;
- if (localPlayerMode->isReadOnly())
+
+ if (localPlayerMode->isAdventureRestricted())
{
- return;
- }
+ if (!minecraft->player->mayDestroyBlockAt(x, y, z))
+ {
+ return;
+ }
+ }
if (localPlayerMode->isCreative())
{
@@ -115,14 +129,18 @@ void MultiPlayerGameMode::startDestroyBlock(int x, int y, int z, int face)
creativeDestroyBlock(minecraft, this, x, y, z, face);
destroyDelay = 5;
}
- else if (!isDestroying || x != xDestroyBlock || y != yDestroyBlock || z != zDestroyBlock)
+ else if (!isDestroying || !sameDestroyTarget(x, y, z))
{
+ if (isDestroying)
+ {
+ connection->send(shared_ptr<PlayerActionPacket>(new PlayerActionPacket(PlayerActionPacket::ABORT_DESTROY_BLOCK, xDestroyBlock, yDestroyBlock, zDestroyBlock, face)));
+ }
connection->send( shared_ptr<PlayerActionPacket>( new PlayerActionPacket(PlayerActionPacket::START_DESTROY_BLOCK, x, y, z, face) ) );
int t = minecraft->level->getTile(x, y, z);
if (t > 0 && destroyProgress == 0) Tile::tiles[t]->attack(minecraft->level, x, y, z, minecraft->player);
if (t > 0 &&
- (Tile::tiles[t]->getDestroyProgress(minecraft->player, minecraft->player->level, x, y, z) >= 1 ||
- (app.DebugSettingsOn() && app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad())&(1L<<eDebugSetting_InstantDestroy))
+ (Tile::tiles[t]->getDestroyProgress(minecraft->player, minecraft->player->level, x, y, z) >= 1
+ // ||(app.DebugSettingsOn() && app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad())&(1L<<eDebugSetting_InstantDestroy))
)
)
{
@@ -134,8 +152,8 @@ void MultiPlayerGameMode::startDestroyBlock(int x, int y, int z, int face)
xDestroyBlock = x;
yDestroyBlock = y;
zDestroyBlock = z;
- destroyProgress = 0;
- oDestroyProgress = 0;
+ destroyingItem = minecraft->player->getCarriedItem();
+ destroyProgress = 0;
destroyTicks = 0;
minecraft->level->destroyTileProgress(minecraft->player->entityId, xDestroyBlock, yDestroyBlock, zDestroyBlock, (int)(destroyProgress * 10) - 1);
}
@@ -175,7 +193,7 @@ void MultiPlayerGameMode::continueDestroyBlock(int x, int y, int z, int face)
return;
}
- if (x == xDestroyBlock && y == yDestroyBlock && z == zDestroyBlock)
+ if (sameDestroyTarget(x, y, z))
{
int t = minecraft->level->getTile(x, y, z);
if (t == 0)
@@ -205,7 +223,6 @@ void MultiPlayerGameMode::continueDestroyBlock(int x, int y, int z, int face)
connection->send( shared_ptr<PlayerActionPacket>( new PlayerActionPacket(PlayerActionPacket::STOP_DESTROY_BLOCK, x, y, z, face) ) );
destroyBlock(x, y, z, face);
destroyProgress = 0;
- oDestroyProgress = 0;
destroyTicks = 0;
destroyDelay = 5;
}
@@ -231,10 +248,23 @@ float MultiPlayerGameMode::getPickRange()
void MultiPlayerGameMode::tick()
{
ensureHasSentCarriedItem();
- oDestroyProgress = destroyProgress;
//minecraft->soundEngine->playMusicTick();
}
+bool MultiPlayerGameMode::sameDestroyTarget(int x, int y, int z)
+{
+ shared_ptr<ItemInstance> selected = minecraft->player->getCarriedItem();
+ bool sameItems = destroyingItem == NULL && selected == NULL;
+ if (destroyingItem != NULL && selected != NULL)
+ {
+ sameItems =
+ selected->id == destroyingItem->id &&
+ ItemInstance::tagMatches(selected, destroyingItem) &&
+ (selected->isDamageableItem() || selected->getAuxValue() == destroyingItem->getAuxValue());
+ }
+ return x == xDestroyBlock && y == yDestroyBlock && z == zDestroyBlock && sameItems;
+}
+
void MultiPlayerGameMode::ensureHasSentCarriedItem()
{
int newItem = minecraft->player->inventory->selected;
@@ -258,34 +288,37 @@ bool MultiPlayerGameMode::useItemOn(shared_ptr<Player> player, Level *level, sha
float clickY = (float) hit->y - y;
float clickZ = (float) hit->z - z;
bool didSomething = false;
- int t = level->getTile(x, y, z);
-
- if (t > 0 && player->isAllowedToUse(Tile::tiles[t]))
+
+ if (!player->isSneaking() || player->getCarriedItem() == NULL)
{
- if(bTestUseOnly)
+ int t = level->getTile(x, y, z);
+ if (t > 0 && player->isAllowedToUse(Tile::tiles[t]))
{
- switch(t)
+ if(bTestUseOnly)
{
- case Tile::recordPlayer_Id:
- case Tile::bed_Id: // special case for a bed
- if (Tile::tiles[t]->TestUse(level, x, y, z, player ))
- {
- return true;
- }
- else if (t==Tile::bed_Id) // 4J-JEV: You can still use items on record players (ie. set fire to them).
+ switch(t)
{
- // bed is too far away, or something
- return false;
- }
- break;
- default:
- if (Tile::tiles[t]->TestUse()) return true;
+ case Tile::jukebox_Id:
+ case Tile::bed_Id: // special case for a bed
+ if (Tile::tiles[t]->TestUse(level, x, y, z, player ))
+ {
+ return true;
+ }
+ else if (t==Tile::bed_Id) // 4J-JEV: You can still use items on record players (ie. set fire to them).
+ {
+ // bed is too far away, or something
+ return false;
+ }
break;
+ default:
+ if (Tile::tiles[t]->TestUse()) return true;
+ break;
+ }
+ }
+ else
+ {
+ if (Tile::tiles[t]->use(level, x, y, z, player, face, clickX, clickY, clickZ)) didSomething = true;
}
- }
- else
- {
- if (Tile::tiles[t]->use(level, x, y, z, player, face, clickX, clickY, clickZ)) didSomething = true;
}
}
@@ -321,6 +354,7 @@ bool MultiPlayerGameMode::useItemOn(shared_ptr<Player> player, Level *level, sha
}
else
{
+ int t = level->getTile(x, y, z);
// 4J - Bit of a hack, however seems preferable to any larger changes which would have more chance of causing unwanted side effects.
// If we aren't going to be actually performing the use method locally, then call this method with its "soundOnly" parameter set to true.
// This is an addition from the java version, and as its name suggests, doesn't actually perform the use locally but just makes any sounds that
@@ -361,7 +395,7 @@ bool MultiPlayerGameMode::useItem(shared_ptr<Player> player, Level *level, share
// 4J-PB added for tooltips to test use only
if(bTestUseOnly)
{
- result = item->TestUse(level, player);
+ result = item->TestUse(item, level, player);
}
else
{
@@ -444,7 +478,7 @@ void MultiPlayerGameMode::releaseUsingItem(shared_ptr<Player> player)
bool MultiPlayerGameMode::hasExperience()
{
- return true;
+ return localPlayerMode->isSurvival();
}
bool MultiPlayerGameMode::hasMissTime()
@@ -462,6 +496,13 @@ bool MultiPlayerGameMode::hasFarPickRange()
return localPlayerMode->isCreative();
}
+// Returns true when the inventory is opened from the server-side. Currently
+// only happens when the player is riding a horse.
+bool MultiPlayerGameMode::isServerControlledInventory()
+{
+ return minecraft->player->isRiding() && minecraft->player->riding->instanceof(eTYPE_HORSE);
+}
+
bool MultiPlayerGameMode::handleCraftItem(int recipe, shared_ptr<Player> player)
{
short changeUid = player->containerMenu->backup(player->inventory);