Merge branch 'main' into TU43

This commit is contained in:
Fireblade 2026-05-28 16:33:20 -04:00 committed by GitHub
commit 253460c5df
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 145 additions and 85 deletions

View file

@ -916,7 +916,7 @@ void IUIScene_CraftingMenu::UpdateHighlight()
// special case for the torch coal/charcoal
int id=pTempItemInstAdditional->getDescriptionId();
LPCWSTR itemstring;
wstring itemstring;
switch(id)
{
@ -945,11 +945,15 @@ void IUIScene_CraftingMenu::UpdateHighlight()
}
break;
default:
itemstring=app.GetString(id );
if (pTempItemInstAdditional->hasCustomHoverName()) {
itemstring = pTempItemInstAdditional->getHoverName();
} else {
itemstring = app.GetString(id);
}
break;
}
setItemText(itemstring);
setItemText(itemstring.c_str());
}
else
{

View file

@ -850,8 +850,10 @@ void ServerPlayer::die(DamageSource *source)
bool ServerPlayer::hurt(DamageSource *dmgSource, float dmg)
{
if (isInvulnerable()) return false;
if (gameMode == nullptr||gameMode->isCreative()) return false;
if (isInvulnerable() && dmgSource != DamageSource::outOfWorld) return false;
if (gameMode == nullptr || gameMode->isCreative()) {
if (dmgSource != DamageSource::outOfWorld) return false;
}
// 4J: Not relevant to console servers
// Allow falldamage on dedicated pvpservers -- so people cannot cheat their way out of 'fall traps'

View file

@ -290,24 +290,53 @@ void TrackedEntity::tick(EntityTracker *tracker, vector<shared_ptr<Player> > *pl
wasRiding = false;
}
else
{
bool rot = abs(yRotn - yRotp) >= TOLERANCE_LEVEL || abs(xRotn - xRotp) >= TOLERANCE_LEVEL;
if (rot)
{
// 4J: Changed this to use deltas
broadcast(std::make_shared<MoveEntityPacket::Rot>(e->entityId, static_cast<byte>(yRota), static_cast<byte>(xRota)));
yRotp = yRotn;
xRotp = xRotn;
}
{
// the entity have a rider, the code didnt send position updates,
// causing desync between client and server when boat was spritning.
xp = Mth::floor(e->x * 32.0);
yp = Mth::floor(e->y * 32.0);
zp = Mth::floor(e->z * 32.0);
bool rot = abs(yRotn - yRotp) >= TOLERANCE_LEVEL || abs(xRotn - xRotp) >= TOLERANCE_LEVEL;
if (rot)
{
broadcast(std::make_shared<MoveEntityPacket::Rot>(e->entityId, static_cast<byte>(yRota), static_cast<byte>(xRota)));
yRotp = yRotn;
xRotp = xRotn;
}
sendDirtyEntityData();
int xn = Mth::floor(e->x * 32.0);
int yn = Mth::floor(e->y * 32.0);
int zn = Mth::floor(e->z * 32.0);
int xa = xn - xp;
int ya = yn - yp;
int za = zn - zp;
wasRiding = true;
}
// send only if the boat moved enough
// or 3 seconds periodically
bool pos = abs(xa) >= TOLERANCE_LEVEL || abs(ya) >= TOLERANCE_LEVEL || abs(za) >= TOLERANCE_LEVEL
|| (tickCount % (SharedConstants::TICKS_PER_SECOND * 3) == 0);
if (pos)
{
// if deltapos is too much big use teleport.
if (xa < -128 || xa >= 128 || ya < -128 || ya >= 128 || za < -128 || za >= 128)
{
broadcast(std::make_shared<TeleportEntityPacket>(e->entityId, xn, yn, zn,
static_cast<byte>(yRotn), static_cast<byte>(xRotn)));
}
else
{
// small movement, delta
broadcast(std::make_shared<MoveEntityPacket::Pos>(e->entityId,
static_cast<char>(xa), static_cast<char>(ya), static_cast<char>(za)));
}
xp = xn;
yp = yn;
zp = zn;
}
sendDirtyEntityData();
wasRiding = true;
}
int yHeadRot = Mth::floor(e->getYHeadRot() * 256 / 360);
if (abs(yHeadRot - yHeadRotp) >= TOLERANCE_LEVEL)

View file

@ -149,47 +149,57 @@ static void CopyWideArgToAnsi(LPCWSTR source, char* dest, size_t destSize)
dest[destSize - 1] = 0;
}
// ---------- Persistent options (options.txt next to exe) ----------
static void GetOptionsFilePath(char *out, size_t outSize)
// ---------- Persistent options (options.dat next to exe) ----------
static void GetOptionsFilePath(char *out, DWORD outSize)
{
GetModuleFileNameA(nullptr, out, static_cast<DWORD>(outSize));
char *p = strrchr(out, '\\');
if (p) *(p + 1) = '\0';
strncat_s(out, outSize, "options.txt", _TRUNCATE);
GetModuleFileNameA(nullptr, out, outSize);
char *p = strrchr(out, '\\');
if (p) *(p + 1) = '\0';
strncat_s(out, outSize, "settings.dat", _TRUNCATE);
}
static void SaveFullscreenOption(bool fullscreen)
{
char path[MAX_PATH];
GetOptionsFilePath(path, sizeof(path));
FILE *f = nullptr;
if (fopen_s(&f, path, "w") == 0 && f)
{
fprintf(f, "fullscreen=%d\n", fullscreen ? 1 : 0);
fclose(f);
}
GAME_SETTINGS settings = {};
char path[MAX_PATH] = {};
GetOptionsFilePath(path, MAX_PATH);
FILE *f = nullptr;
if (fopen_s(&f, path, "rb") == 0 && f)
{
fread(&settings, sizeof(GAME_SETTINGS), 1, f);
fclose(f);
}
if (fullscreen)
settings.uiBitmaskValues |= (1UL << 25);
else
settings.uiBitmaskValues &= ~(1UL << 25);
if (fopen_s(&f, path, "wb") == 0 && f)
{
fwrite(&settings, sizeof(GAME_SETTINGS), 1, f);
fclose(f);
}
}
static bool LoadFullscreenOption()
{
char path[MAX_PATH];
char path[MAX_PATH] = {};
GetOptionsFilePath(path, sizeof(path));
FILE *f = nullptr;
if (fopen_s(&f, path, "r") == 0 && f)
{
char line[256];
while (fgets(line, sizeof(line), f))
{
int val = 0;
if (sscanf_s(line, "fullscreen=%d", &val) == 1)
{
fclose(f);
return val != 0;
}
}
fclose(f);
}
return false;
FILE *f = nullptr;
if (fopen_s(&f, path, "rb") != 0 || !f)
return false;
GAME_SETTINGS current = {};
bool ok = (fread(&current, sizeof(GAME_SETTINGS), 1, f) == 1);
fclose(f);
if (!ok)
return false;
return (current.uiBitmaskValues & (1UL << 25)) != 0;
}
// ------------------------------------------------------------------
@ -824,7 +834,7 @@ BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
return FALSE;
}
return TRUE;
}
@ -1696,11 +1706,12 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
CleanupDevice();
return 0;
}
// Restore fullscreen state from previous session. Route through the
// deferred exclusive fullscreen path so the main loop applies it on the
// first tick (safer than transitioning during init).
if ((LoadFullscreenOption() && !g_isFullscreen) || launchOptions.fullscreen)
bool FullScreenEnabled = LoadFullscreenOption();
if (FullScreenEnabled && !g_isFullscreen)
{
g_bPendingExclusiveFullscreen = true;
g_bPendingExclusiveFullscreenValue = true;
@ -1765,7 +1776,7 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
return 1;
}
g_bResizeReady = true;
//app.TemporaryCreateGameStart();
//Sleep(10000);

View file

@ -8,7 +8,7 @@
const BlockPos BlockPos::ZERO = BlockPos(0, 0, 0);
// Costruttori
BlockPos::BlockPos() : Vec3i(0, 0, 0) {}
BlockPos::BlockPos(int x, int y, int z) : Vec3i(x, y, z) {}
@ -49,7 +49,7 @@ BlockPos::BlockPos(int compressed) : Vec3i(0, 0, 0) {
BlockPos::BlockPos(BlockSource& source)
: Vec3i(source.getBlockX(), source.getBlockY(), source.getBlockZ()) {}
// Metodi di confronto
bool BlockPos::equals(const BlockPos& other) const {
return x == other.x && y == other.y && z == other.z;
}
@ -88,7 +88,7 @@ BlockPos BlockPos::relative(int direction, int distance) const {
return BlockPos(x + dx, y, z + dz);
}
// Metodi direzionali
// directional methods
BlockPos BlockPos::above(int distance) const {
return BlockPos(x, y + distance, z);
}
@ -119,7 +119,7 @@ BlockPos BlockPos::multiply(int factor) const {
return BlockPos(x * factor, y * factor, z * factor);
}
// Compressione
// compression
int BlockPos::compress() const {
static const int MASK_X = (1 << BITS_X) - 1;
static const int MASK_Y = (1 << BITS_Y) - 1;

View file

@ -148,7 +148,7 @@ void Boat::lerpTo(double x, double y, double z, float yRot, float xRot, int step
{
if (doLerp)
{
lSteps = steps + 5;
lSteps = steps +5;
}
else
{
@ -188,6 +188,10 @@ void Boat::lerpMotion(double xd, double yd, double zd)
void Boat::tick()
{
Entity::tick();
if (getHurtTime() > 0) setHurtTime(getHurtTime() - 1);
if (getDamage() > 0) setDamage(getDamage() - 1);
xo = x;
@ -199,8 +203,8 @@ void Boat::tick()
double waterPercentage = 0;
for (int i = 0; i < steps; i++)
{
double y0 = bb->y0 + (bb->y1 - bb->y0) * (i + 0) / steps - 2 / 16.0f;
double y1 = bb->y0 + (bb->y1 - bb->y0) * (i + 1) / steps - 2 / 16.0f;
double y0 = bb->y0 + (bb->y1 - bb->y0) * (i + 0) / steps + 1.5f / 16.0f;
double y1 = bb->y0 + (bb->y1 - bb->y0) * (i + 1) / steps + 1.5f / 16.0f;
AABB *bb2 = AABB::newTemp(bb->x0, y0, bb->z0, bb->x1, y1, bb->z1);
if (level->containsLiquid(bb2, Material::water))
{
@ -257,18 +261,19 @@ void Boat::tick()
return;
}
// Bob in water
if (waterPercentage > 0)
// Bob in water & gravity
if (waterPercentage < 1.0)
{
double bob = waterPercentage * 2 - 1;
double bob = waterPercentage * 2.0 - 1.0;
yd += 0.04f * bob;
}
// Reimplement gravity again (??)
int tileUnder = level->getTile(Mth::floor(x), Mth::floor(y-0.15), Mth::floor(z));
if (tileUnder == 0 && !onGround)
else
{
yd -= 0.04f;
if (yd < 0.0)
{
yd /= 2.0;
}
yd += 0.007f;
}
// Rider controls
@ -281,24 +286,16 @@ void Boat::tick()
{
double riderXd = -sin(livingRider->yRot * PI / 180);
double riderZd = cos(livingRider->yRot * PI / 180);
float mult = livingRider->isSprinting() ? 2.0f : 1.0f;
double currentSpeed = sqrt(xd * xd + zd * zd);
float moveFactor = (float)forward;
if (forward < 0) moveFactor *= 0.5f; // Move slower backwards
xd += riderXd * acceleration * 0.05f * mult * moveFactor;
zd += riderZd * acceleration * 0.05f * mult * moveFactor;
xd += riderXd * acceleration * 0.05f * moveFactor;
zd += riderZd * acceleration * 0.05f * moveFactor;
}
}
double curSpeed = sqrt(xd * xd + zd * zd);
double maxSpeed = MAX_SPEED;
if (rider.lock() != nullptr && rider.lock()->instanceof(eTYPE_LIVINGENTITY))
{
shared_ptr<LivingEntity> livingRider = dynamic_pointer_cast<LivingEntity>(rider.lock());
if (livingRider->isSprinting())
{
maxSpeed *= 1.5;
}
}
if (curSpeed > maxSpeed)
{
@ -330,10 +327,12 @@ void Boat::tick()
move(xd, yd, zd);
// Break boat on high speed collision
float breakThreshold = (rider.lock() != nullptr) ? 0.35f : 0.20f;
if ((horizontalCollision && lastSpeed > 0.20))
{
if (!level->isClientSide && !removed)
{
remove();
for (int i = 0; i < 3; i++)
{
@ -343,6 +342,9 @@ void Boat::tick()
{
spawnAtLocation(Item::stick->id, 1, 0);
}
}
}
else
@ -472,10 +474,19 @@ bool Boat::interact(shared_ptr<Player> player)
if ( (rider.lock() != nullptr) && rider.lock()->instanceof(eTYPE_PLAYER) && (rider.lock() != player) ) return true;
if (!level->isClientSide)
{
bool isRiding = (rider.lock() == player);
if (isRiding)
{
player->xd = 0;
player->yd = 0;
player->zd = 0;
}
// 4J HEG - Fixed issue with player not being able to dismount boat (issue #4446)
player->ride( rider.lock() == player ? nullptr : shared_from_this() );
}
return true;
player->ride(isRiding ? nullptr : shared_from_this());
}
return true;
}
void Boat::setDamage(float damage)

View file

@ -116,6 +116,9 @@ void ClothDyeRecipes::addRecipes(Recipes *r)
new ItemInstance(Item::dye, 1, DyePowderItem::RED),
new ItemInstance(Item::dye, 1, DyePowderItem::WHITE),L'D');
for (int i = 0; i < 16; i++)
{
r->addShapedRecipy(new ItemInstance(Tile::woolCarpet, 3, i),

View file

@ -199,7 +199,7 @@ bool Ocelot::mobInteract(shared_ptr<Player> player)
}
else
{
if (temptGoal->isRunning() && item != nullptr && item->id == Item::fish_Id && player->distanceToSqr(shared_from_this()) < 3 * 3)
if (/*temptGoal->isRunning() &&*/ item != nullptr && item->id == Item::fish_Id && player->distanceToSqr(shared_from_this()) < 3 * 3)
{
// 4J-PB - don't lose the fish in creative mode
if (!player->abilities.instabuild) item->count--;