diff -Nru minetest-5.2.0/build/android/app/build.gradle minetest-5.3.0/build/android/app/build.gradle
--- minetest-5.2.0/build/android/app/build.gradle 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/build/android/app/build.gradle 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,111 @@
+apply plugin: 'com.android.application'
+android {
+ compileSdkVersion 29
+ buildToolsVersion '29.0.3'
+ ndkVersion '21.1.6352462'
+ defaultConfig {
+ applicationId 'net.minetest.minetest'
+ minSdkVersion 16
+ targetSdkVersion 29
+ versionName "${versionMajor}.${versionMinor}.${versionPatch}"
+ versionCode project.versionCode
+ }
+
+ Properties props = new Properties()
+ props.load(new FileInputStream(file('../local.properties')))
+
+ if (props.getProperty('keystore') != null) {
+ signingConfigs {
+ release {
+ storeFile file(props['keystore'])
+ storePassword props['keystore.password']
+ keyAlias props['key']
+ keyPassword props['key.password']
+ }
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled true
+ signingConfig signingConfigs.release
+ }
+ }
+ }
+
+ // for multiple APKs
+ splits {
+ abi {
+ enable true
+ reset()
+ include 'armeabi-v7a', 'arm64-v8a'
+ }
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+}
+
+task prepareAssets() {
+ def assetsFolder = "build/assets"
+ def projRoot = "../../.."
+ def gameToCopy = "minetest_game"
+
+ copy {
+ from "${projRoot}/minetest.conf.example", "${projRoot}/README.md" into assetsFolder
+ }
+ copy {
+ from "${projRoot}/doc/lgpl-2.1.txt" into "${assetsFolder}"
+ }
+ copy {
+ from "${projRoot}/builtin" into "${assetsFolder}/builtin"
+ }
+ /*copy {
+ // ToDo: fix Minetest shaders that currently don't work with OpenGL ES
+ from "${projRoot}/client/shaders" into "${assetsFolder}/client/shaders"
+ }*/
+ copy {
+ from "../native/deps/Android/Irrlicht/shaders" into "${assetsFolder}/client/shaders/Irrlicht"
+ }
+ copy {
+ from "${projRoot}/fonts" include "*.ttf" into "${assetsFolder}/fonts"
+ }
+ copy {
+ from "${projRoot}/games/${gameToCopy}" into "${assetsFolder}/games/${gameToCopy}"
+ }
+ /*copy {
+ // ToDo: fix broken locales
+ from "${projRoot}/po" into "${assetsFolder}/po"
+ }*/
+ copy {
+ from "${projRoot}/textures" into "${assetsFolder}/textures"
+ }
+
+ file("${assetsFolder}/.nomedia").text = "";
+
+ task zipAssets(type: Zip) {
+ archiveName "Minetest.zip"
+ from "${assetsFolder}"
+ destinationDir file("src/main/assets")
+ }
+}
+
+preBuild.dependsOn zipAssets
+
+// Map for the version code that gives each ABI a value.
+import com.android.build.OutputFile
+
+def abiCodes = ['armeabi-v7a': 0, 'arm64-v8a': 1]
+android.applicationVariants.all { variant ->
+ variant.outputs.each {
+ output ->
+ def abiName = output.getFilter(OutputFile.ABI)
+ output.versionCodeOverride = abiCodes.get(abiName, 0) + variant.versionCode
+ }
+}
+
+dependencies {
+ implementation project(':native')
+ implementation 'androidx.appcompat:appcompat:1.1.0'
+}
diff -Nru minetest-5.2.0/build/android/app/src/main/AndroidManifest.xml minetest-5.3.0/build/android/app/src/main/AndroidManifest.xml
--- minetest-5.2.0/build/android/app/src/main/AndroidManifest.xml 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/build/android/app/src/main/AndroidManifest.xml 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -Nru minetest-5.2.0/build/android/app/src/main/java/net/minetest/minetest/CopyZipTask.java minetest-5.3.0/build/android/app/src/main/java/net/minetest/minetest/CopyZipTask.java
--- minetest-5.2.0/build/android/app/src/main/java/net/minetest/minetest/CopyZipTask.java 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/build/android/app/src/main/java/net/minetest/minetest/CopyZipTask.java 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,82 @@
+/*
+Minetest
+Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik
+Copyright (C) 2014-2020 ubulem, Bektur Mambetov
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+package net.minetest.minetest;
+
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.widget.Toast;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.ref.WeakReference;
+
+public class CopyZipTask extends AsyncTask {
+
+ private final WeakReference activityRef;
+
+ CopyZipTask(AppCompatActivity activity) {
+ activityRef = new WeakReference<>(activity);
+ }
+
+ protected String doInBackground(String... params) {
+ copyAsset(params[0]);
+ return params[0];
+ }
+
+ @Override
+ protected void onPostExecute(String result) {
+ startUnzipService(result);
+ }
+
+ private void copyAsset(String zipName) {
+ String filename = zipName.substring(zipName.lastIndexOf("/") + 1);
+ try (InputStream in = activityRef.get().getAssets().open(filename);
+ OutputStream out = new FileOutputStream(zipName)) {
+ copyFile(in, out);
+ } catch (IOException e) {
+ AppCompatActivity activity = activityRef.get();
+ if (activity != null) {
+ activity.runOnUiThread(() -> Toast.makeText(activityRef.get(), e.getLocalizedMessage(), Toast.LENGTH_LONG).show());
+ }
+ cancel(true);
+ }
+ }
+
+ private void copyFile(InputStream in, OutputStream out) throws IOException {
+ byte[] buffer = new byte[1024];
+ int read;
+ while ((read = in.read(buffer)) != -1)
+ out.write(buffer, 0, read);
+ }
+
+ private void startUnzipService(String file) {
+ Intent intent = new Intent(activityRef.get(), UnzipService.class);
+ intent.putExtra(UnzipService.EXTRA_KEY_IN_FILE, file);
+ AppCompatActivity activity = activityRef.get();
+ if (activity != null) {
+ activity.startService(intent);
+ }
+ }
+}
diff -Nru minetest-5.2.0/build/android/app/src/main/java/net/minetest/minetest/GameActivity.java minetest-5.3.0/build/android/app/src/main/java/net/minetest/minetest/GameActivity.java
--- minetest-5.2.0/build/android/app/src/main/java/net/minetest/minetest/GameActivity.java 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/build/android/app/src/main/java/net/minetest/minetest/GameActivity.java 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,126 @@
+/*
+Minetest
+Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik
+Copyright (C) 2014-2020 ubulem, Bektur Mambetov
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+package net.minetest.minetest;
+
+import android.app.NativeActivity;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.view.View;
+import android.view.WindowManager;
+
+public class GameActivity extends NativeActivity {
+ static {
+ System.loadLibrary("c++_shared");
+ System.loadLibrary("Minetest");
+ }
+
+ private int messageReturnCode;
+ private String messageReturnValue;
+
+ public static native void putMessageBoxResult(String text);
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ messageReturnCode = -1;
+ messageReturnValue = "";
+ }
+
+ private void makeFullScreen() {
+ if (Build.VERSION.SDK_INT >= 19)
+ this.getWindow().getDecorView().setSystemUiVisibility(
+ View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
+ View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
+ View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
+ }
+
+ @Override
+ public void onWindowFocusChanged(boolean hasFocus) {
+ super.onWindowFocusChanged(hasFocus);
+ if (hasFocus)
+ makeFullScreen();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ makeFullScreen();
+ }
+
+ @Override
+ public void onBackPressed() {
+ // Ignore the back press so Minetest can handle it
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == 101) {
+ if (resultCode == RESULT_OK) {
+ String text = data.getStringExtra("text");
+ messageReturnCode = 0;
+ messageReturnValue = text;
+ } else
+ messageReturnCode = 1;
+ }
+ }
+
+ public void showDialog(String acceptButton, String hint, String current, int editType) {
+ Intent intent = new Intent(this, InputDialogActivity.class);
+ Bundle params = new Bundle();
+ params.putString("acceptButton", acceptButton);
+ params.putString("hint", hint);
+ params.putString("current", current);
+ params.putInt("editType", editType);
+ intent.putExtras(params);
+ startActivityForResult(intent, 101);
+ messageReturnValue = "";
+ messageReturnCode = -1;
+ }
+
+ public int getDialogState() {
+ return messageReturnCode;
+ }
+
+ public String getDialogValue() {
+ messageReturnCode = -1;
+ return messageReturnValue;
+ }
+
+ public float getDensity() {
+ return getResources().getDisplayMetrics().density;
+ }
+
+ public int getDisplayHeight() {
+ return getResources().getDisplayMetrics().heightPixels;
+ }
+
+ public int getDisplayWidth() {
+ return getResources().getDisplayMetrics().widthPixels;
+ }
+
+ public void openURL(String url) {
+ Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
+ startActivity(browserIntent);
+ }
+}
diff -Nru minetest-5.2.0/build/android/app/src/main/java/net/minetest/minetest/InputDialogActivity.java minetest-5.3.0/build/android/app/src/main/java/net/minetest/minetest/InputDialogActivity.java
--- minetest-5.2.0/build/android/app/src/main/java/net/minetest/minetest/InputDialogActivity.java 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/build/android/app/src/main/java/net/minetest/minetest/InputDialogActivity.java 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,98 @@
+/*
+Minetest
+Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik
+Copyright (C) 2014-2020 ubulem, Bektur Mambetov
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+package net.minetest.minetest;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.text.InputType;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.EditText;
+
+import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.app.AppCompatActivity;
+
+import java.util.Objects;
+
+public class InputDialogActivity extends AppCompatActivity {
+ private AlertDialog alertDialog;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Bundle b = getIntent().getExtras();
+ int editType = Objects.requireNonNull(b).getInt("editType");
+ String hint = b.getString("hint");
+ String current = b.getString("current");
+ final AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ EditText editText = new EditText(this);
+ builder.setView(editText);
+ editText.requestFocus();
+ editText.setHint(hint);
+ editText.setText(current);
+ final InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
+ Objects.requireNonNull(imm).toggleSoftInput(InputMethodManager.SHOW_FORCED,
+ InputMethodManager.HIDE_IMPLICIT_ONLY);
+ if (editType == 3)
+ editText.setInputType(InputType.TYPE_CLASS_TEXT |
+ InputType.TYPE_TEXT_VARIATION_PASSWORD);
+ else
+ editText.setInputType(InputType.TYPE_CLASS_TEXT);
+ editText.setOnKeyListener((view, KeyCode, event) -> {
+ if (KeyCode == KeyEvent.KEYCODE_ENTER) {
+ imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
+ pushResult(editText.getText().toString());
+ return true;
+ }
+ return false;
+ });
+ alertDialog = builder.create();
+ if (!this.isFinishing())
+ alertDialog.show();
+ alertDialog.setOnCancelListener(dialog -> {
+ pushResult(editText.getText().toString());
+ setResult(Activity.RESULT_CANCELED);
+ alertDialog.dismiss();
+ makeFullScreen();
+ finish();
+ });
+ }
+
+ private void pushResult(String text) {
+ Intent resultData = new Intent();
+ resultData.putExtra("text", text);
+ setResult(AppCompatActivity.RESULT_OK, resultData);
+ alertDialog.dismiss();
+ makeFullScreen();
+ finish();
+ }
+
+ private void makeFullScreen() {
+ if (Build.VERSION.SDK_INT >= 19)
+ this.getWindow().getDecorView().setSystemUiVisibility(
+ View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
+ View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
+ View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
+ }
+}
diff -Nru minetest-5.2.0/build/android/app/src/main/java/net/minetest/minetest/MainActivity.java minetest-5.3.0/build/android/app/src/main/java/net/minetest/minetest/MainActivity.java
--- minetest-5.2.0/build/android/app/src/main/java/net/minetest/minetest/MainActivity.java 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/build/android/app/src/main/java/net/minetest/minetest/MainActivity.java 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,153 @@
+/*
+Minetest
+Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik
+Copyright (C) 2014-2020 ubulem, Bektur Mambetov
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+package net.minetest.minetest;
+
+import android.Manifest;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static net.minetest.minetest.UnzipService.ACTION_FAILURE;
+import static net.minetest.minetest.UnzipService.ACTION_PROGRESS;
+import static net.minetest.minetest.UnzipService.ACTION_UPDATE;
+import static net.minetest.minetest.UnzipService.FAILURE;
+import static net.minetest.minetest.UnzipService.SUCCESS;
+
+public class MainActivity extends AppCompatActivity {
+ private final static int versionCode = BuildConfig.VERSION_CODE;
+ private final static int PERMISSIONS = 1;
+ private static final String[] REQUIRED_SDK_PERMISSIONS =
+ new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE};
+ private static final String SETTINGS = "MinetestSettings";
+ private static final String TAG_VERSION_CODE = "versionCode";
+ private ProgressBar mProgressBar;
+ private TextView mTextView;
+ private SharedPreferences sharedPreferences;
+ private final BroadcastReceiver myReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ int progress = 0;
+ if (intent != null)
+ progress = intent.getIntExtra(ACTION_PROGRESS, 0);
+ if (progress >= 0) {
+ if (mProgressBar != null) {
+ mProgressBar.setVisibility(View.VISIBLE);
+ mProgressBar.setProgress(progress);
+ }
+ mTextView.setVisibility(View.VISIBLE);
+ } else if (progress == FAILURE) {
+ Toast.makeText(MainActivity.this, intent.getStringExtra(ACTION_FAILURE), Toast.LENGTH_LONG).show();
+ finish();
+ } else if (progress == SUCCESS)
+ startNative();
+ }
+ };
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ IntentFilter filter = new IntentFilter(ACTION_UPDATE);
+ registerReceiver(myReceiver, filter);
+ mProgressBar = findViewById(R.id.progressBar);
+ mTextView = findViewById(R.id.textView);
+ sharedPreferences = getSharedPreferences(SETTINGS, Context.MODE_PRIVATE);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
+ checkPermission();
+ else
+ checkAppVersion();
+ }
+
+ private void checkPermission() {
+ final List missingPermissions = new ArrayList<>();
+ for (final String permission : REQUIRED_SDK_PERMISSIONS) {
+ final int result = ContextCompat.checkSelfPermission(this, permission);
+ if (result != PackageManager.PERMISSION_GRANTED)
+ missingPermissions.add(permission);
+ }
+ if (!missingPermissions.isEmpty()) {
+ final String[] permissions = missingPermissions
+ .toArray(new String[0]);
+ ActivityCompat.requestPermissions(this, permissions, PERMISSIONS);
+ } else {
+ final int[] grantResults = new int[REQUIRED_SDK_PERMISSIONS.length];
+ Arrays.fill(grantResults, PackageManager.PERMISSION_GRANTED);
+ onRequestPermissionsResult(PERMISSIONS, REQUIRED_SDK_PERMISSIONS, grantResults);
+ }
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode,
+ @NonNull String[] permissions, @NonNull int[] grantResults) {
+ if (requestCode == PERMISSIONS) {
+ for (int grantResult : grantResults) {
+ if (grantResult != PackageManager.PERMISSION_GRANTED) {
+ Toast.makeText(this, R.string.not_granted, Toast.LENGTH_LONG).show();
+ finish();
+ }
+ }
+ checkAppVersion();
+ }
+ }
+
+ private void checkAppVersion() {
+ if (sharedPreferences.getInt(TAG_VERSION_CODE, 0) == versionCode)
+ startNative();
+ else
+ new CopyZipTask(this).execute(getCacheDir() + "/Minetest.zip");
+ }
+
+ private void startNative() {
+ sharedPreferences.edit().putInt(TAG_VERSION_CODE, versionCode).apply();
+ Intent intent = new Intent(this, GameActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ startActivity(intent);
+ }
+
+ @Override
+ public void onBackPressed() {
+ // Prevent abrupt interruption when copy game files from assets
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ unregisterReceiver(myReceiver);
+ }
+}
diff -Nru minetest-5.2.0/build/android/app/src/main/java/net/minetest/minetest/UnzipService.java minetest-5.3.0/build/android/app/src/main/java/net/minetest/minetest/UnzipService.java
--- minetest-5.2.0/build/android/app/src/main/java/net/minetest/minetest/UnzipService.java 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/build/android/app/src/main/java/net/minetest/minetest/UnzipService.java 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,157 @@
+/*
+Minetest
+Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik
+Copyright (C) 2014-2020 ubulem, Bektur Mambetov
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+package net.minetest.minetest;
+
+import android.app.IntentService;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Environment;
+import android.widget.Toast;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipInputStream;
+
+public class UnzipService extends IntentService {
+ public static final String ACTION_UPDATE = "net.minetest.minetest.UPDATE";
+ public static final String ACTION_PROGRESS = "net.minetest.minetest.PROGRESS";
+ public static final String ACTION_FAILURE = "net.minetest.minetest.FAILURE";
+ public static final String EXTRA_KEY_IN_FILE = "file";
+ public static final int SUCCESS = -1;
+ public static final int FAILURE = -2;
+ private final int id = 1;
+ private NotificationManager mNotifyManager;
+ private boolean isSuccess = true;
+ private String failureMessage;
+
+ public UnzipService() {
+ super("net.minetest.minetest.UnzipService");
+ }
+
+ private void isDir(String dir, String location) {
+ File f = new File(location, dir);
+ if (!f.isDirectory())
+ f.mkdirs();
+ }
+
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ createNotification();
+ unzip(intent);
+ }
+
+ private void createNotification() {
+ String name = "net.minetest.minetest";
+ String channelId = "Minetest channel";
+ String description = "notifications from Minetest";
+ Notification.Builder builder;
+ if (mNotifyManager == null)
+ mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ int importance = NotificationManager.IMPORTANCE_LOW;
+ NotificationChannel mChannel = null;
+ if (mNotifyManager != null)
+ mChannel = mNotifyManager.getNotificationChannel(channelId);
+ if (mChannel == null) {
+ mChannel = new NotificationChannel(channelId, name, importance);
+ mChannel.setDescription(description);
+ // Configure the notification channel, NO SOUND
+ mChannel.setSound(null, null);
+ mChannel.enableLights(false);
+ mChannel.enableVibration(false);
+ mNotifyManager.createNotificationChannel(mChannel);
+ }
+ builder = new Notification.Builder(this, channelId);
+ } else {
+ builder = new Notification.Builder(this);
+ }
+ builder.setContentTitle(getString(R.string.notification_title))
+ .setSmallIcon(R.mipmap.ic_launcher)
+ .setContentText(getString(R.string.notification_description));
+ mNotifyManager.notify(id, builder.build());
+ }
+
+ private void unzip(Intent intent) {
+ String zip = intent.getStringExtra(EXTRA_KEY_IN_FILE);
+ isDir("Minetest", Environment.getExternalStorageDirectory().toString());
+ String location = Environment.getExternalStorageDirectory() + File.separator + "Minetest" + File.separator;
+ int per = 0;
+ int size = getSummarySize(zip);
+ File zipFile = new File(zip);
+ int readLen;
+ byte[] readBuffer = new byte[8192];
+ try (FileInputStream fileInputStream = new FileInputStream(zipFile);
+ ZipInputStream zipInputStream = new ZipInputStream(fileInputStream)) {
+ ZipEntry ze;
+ while ((ze = zipInputStream.getNextEntry()) != null) {
+ if (ze.isDirectory()) {
+ ++per;
+ isDir(ze.getName(), location);
+ } else {
+ publishProgress(100 * ++per / size);
+ try (OutputStream outputStream = new FileOutputStream(location + ze.getName())) {
+ while ((readLen = zipInputStream.read(readBuffer)) != -1) {
+ outputStream.write(readBuffer, 0, readLen);
+ }
+ }
+ }
+ zipFile.delete();
+ }
+ } catch (IOException e) {
+ isSuccess = false;
+ failureMessage = e.getLocalizedMessage();
+ }
+ }
+
+ private void publishProgress(int progress) {
+ Intent intentUpdate = new Intent(ACTION_UPDATE);
+ intentUpdate.putExtra(ACTION_PROGRESS, progress);
+ if (!isSuccess) intentUpdate.putExtra(ACTION_FAILURE, failureMessage);
+ sendBroadcast(intentUpdate);
+ }
+
+ private int getSummarySize(String zip) {
+ int size = 0;
+ try {
+ ZipFile zipSize = new ZipFile(zip);
+ size += zipSize.size();
+ } catch (IOException e) {
+ Toast.makeText(this, e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
+ }
+ return size;
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ mNotifyManager.cancel(id);
+ publishProgress(isSuccess ? SUCCESS : FAILURE);
+ }
+}
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/build/android/app/src/main/res/drawable/background.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/build/android/app/src/main/res/drawable/background.png differ
diff -Nru minetest-5.2.0/build/android/app/src/main/res/drawable/bg.xml minetest-5.3.0/build/android/app/src/main/res/drawable/bg.xml
--- minetest-5.2.0/build/android/app/src/main/res/drawable/bg.xml 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/build/android/app/src/main/res/drawable/bg.xml 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,4 @@
+
+
diff -Nru minetest-5.2.0/build/android/app/src/main/res/layout/activity_main.xml minetest-5.3.0/build/android/app/src/main/res/layout/activity_main.xml
--- minetest-5.2.0/build/android/app/src/main/res/layout/activity_main.xml 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/build/android/app/src/main/res/layout/activity_main.xml 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/build/android/app/src/main/res/mipmap/ic_launcher.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/build/android/app/src/main/res/mipmap/ic_launcher.png differ
diff -Nru minetest-5.2.0/build/android/app/src/main/res/values/strings.xml minetest-5.3.0/build/android/app/src/main/res/values/strings.xml
--- minetest-5.2.0/build/android/app/src/main/res/values/strings.xml 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/build/android/app/src/main/res/values/strings.xml 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,10 @@
+
+
+
+ Minetest
+ Loading…
+ Required permission wasn\'t granted, Minetest can\'t run without it
+ Loading Minetest
+ Less than 1 minute…
+
+
diff -Nru minetest-5.2.0/build/android/app/src/main/res/values/styles.xml minetest-5.3.0/build/android/app/src/main/res/values/styles.xml
--- minetest-5.2.0/build/android/app/src/main/res/values/styles.xml 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/build/android/app/src/main/res/values/styles.xml 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
diff -Nru minetest-5.2.0/build/android/build.gradle minetest-5.3.0/build/android/build.gradle
--- minetest-5.2.0/build/android/build.gradle 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/build/android/build.gradle 2020-07-09 21:13:20.000000000 +0000
@@ -1,10 +1,24 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+project.ext.set("versionMajor", 5) // Version Major
+project.ext.set("versionMinor", 3) // Version Minor
+project.ext.set("versionPatch", 0) // Version Patch
+project.ext.set("versionExtra", "-dev") // Version Extra
+project.ext.set("versionCode", 30) // Android Version Code
+// NOTE: +2 after each release!
+// +1 for ARM and +1 for ARM64 APK's, because
+// each APK must have a larger `versionCode` than the previous
+
buildscript {
repositories {
google()
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.5.1'
+ classpath 'com.android.tools.build:gradle:3.6.3'
+ classpath 'org.ajoberstar.grgit:grgit-gradle:4.0.2'
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
}
}
@@ -15,161 +29,6 @@
}
}
-def curl_version = "7.60.0"
-def irrlicht_revision = "5150"
-def openal_version = "1.18.2"
-def openssl_version = "1.0.2n"
-def sqlite3_version = "3240000"
-
-apply plugin: "com.android.application"
-
-android {
- compileSdkVersion 29
- buildToolsVersion '29.0.2'
-
- defaultConfig {
- versionCode 26
- versionName "${System.env.VERSION_STR}.${versionCode}"
- minSdkVersion 14
- targetSdkVersion 29
- applicationId "net.minetest.minetest"
- manifestPlaceholders = [package: "net.minetest.minetest", project: project.name]
- ndk {
- // Specifies the ABI configurations of your native
- // libraries Gradle should build and package with your APK.
- // abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
- abiFilters 'armeabi-v7a', 'x86', 'arm64-v8a'
- }
- }
-
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
- }
-
- lintOptions {
- disable "OldTargetApi", "GoogleAppIndexingWarning"
- }
-
- Properties props = new Properties()
- props.load(new FileInputStream(file("local.properties")))
-
- if (props.getProperty("keystore") != null) {
- signingConfigs {
- release {
- storeFile file(props["keystore"])
- storePassword props["keystore.password"]
- keyAlias props["key"]
- keyPassword props["key.password"]
- }
- }
-
- buildTypes {
- release {
- signingConfig signingConfigs.release
- }
- }
- }
-}
-
-task cleanAssets(type: Delete) {
- delete 'src/main/assets'
-}
-
-task copyAssets {
- dependsOn 'cleanAssets'
- mkdir "src/main/assets"
-
- def mtAssetsFolder = "src/main/assets/Minetest"
- def projRoot = "../.."
- def gameToCopy = "minetest_game"
-
- doLast {
- mkdir "${mtAssetsFolder}"
- mkdir "${mtAssetsFolder}/client"
- mkdir "${mtAssetsFolder}/fonts"
- mkdir "${mtAssetsFolder}/games"
- mkdir "${mtAssetsFolder}/media"
-
- copy {
- from "${projRoot}/minetest.conf.example", "${projRoot}/README.md" into mtAssetsFolder
- }
- copy {
- from "${projRoot}/doc/lgpl-2.1.txt" into "${mtAssetsFolder}/LICENSE.txt"
- }
- copy {
- from "${projRoot}/builtin" into "${mtAssetsFolder}/builtin"
- }
- copy {
- from "${projRoot}/client/shaders" into "${mtAssetsFolder}/client/shaders"
- }
- copy {
- from "${projRoot}/fonts" include "*.ttf" into "${mtAssetsFolder}/fonts"
- }
- copy {
- from "${projRoot}/games/${gameToCopy}" into "${mtAssetsFolder}/games/${gameToCopy}"
- }
- copy {
- from "${projRoot}/po" into "${mtAssetsFolder}/po"
- }
- copy {
- from "${projRoot}/textures" into "${mtAssetsFolder}/textures"
- }
- }
-}
-
-task cleanIconv(type: Delete) {
- delete 'deps/libiconv'
-}
-
-task cleanIrrlicht(type: Delete) {
- delete 'deps/irrlicht'
-}
-
-task cleanLevelDB(type: Delete) {
- delete 'deps/leveldb'
-}
-
-task cleanCURL(type: Delete) {
- delete 'deps/curl'
- delete 'deps/curl-' + curl_version
-}
-
-task cleanOpenSSL(type: Delete) {
- delete 'deps/openssl'
- delete 'deps/openssl-' + openssl_version
- delete 'deps/openssl-' + openssl_version + '.tar.gz'
-}
-
-task cleanOpenAL(type: Delete) {
- delete 'deps/openal-soft'
-}
-
-task cleanFreetype(type: Delete) {
- delete 'deps/freetype2-android'
-}
-
-task cleanOgg(type: Delete) {
- delete 'deps/libvorbis-libogg-android'
-}
-
-task cleanSQLite3(type: Delete) {
- delete 'deps/sqlite-amalgamation-' + sqlite3_version
- delete 'deps/sqlite-amalgamation-' + sqlite3_version + '.zip'
-}
-
-task cleanAll(type: Delete, dependsOn: [clean, cleanAssets, cleanIconv,
- cleanFreetype, cleanIrrlicht, cleanLevelDB, cleanSQLite3, cleanCURL,
- cleanOpenSSL, cleanOpenAL, cleanOgg]) {
- delete 'deps'
- delete 'gen'
- delete 'libs'
- delete 'obj'
- delete 'bin'
- delete 'Debug'
- delete 'and_env'
-}
-
-dependencies {
- implementation 'androidx.core:core:1.1.0'
+task clean(type: Delete) {
+ delete rootProject.buildDir
}
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/build/android/gradle/wrapper/gradle-wrapper.jar and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/build/android/gradle/wrapper/gradle-wrapper.jar differ
diff -Nru minetest-5.2.0/build/android/gradle/wrapper/gradle-wrapper.properties minetest-5.3.0/build/android/gradle/wrapper/gradle-wrapper.properties
--- minetest-5.2.0/build/android/gradle/wrapper/gradle-wrapper.properties 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/build/android/gradle/wrapper/gradle-wrapper.properties 2020-07-09 21:13:20.000000000 +0000
@@ -1 +1,2 @@
-distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
+#Mon Apr 06 00:06:16 CEST 2020
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
diff -Nru minetest-5.2.0/build/android/gradle.properties minetest-5.3.0/build/android/gradle.properties
--- minetest-5.2.0/build/android/gradle.properties 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/build/android/gradle.properties 2020-07-09 21:13:20.000000000 +0000
@@ -1,2 +1,11 @@
+<#if isLowMemory>
+org.gradle.jvmargs=-Xmx4G -XX:MaxPermSize=2G -XX:+HeapDumpOnOutOfMemoryError
+<#else>
+org.gradle.jvmargs=-Xmx16G -XX:MaxPermSize=8G -XX:+HeapDumpOnOutOfMemoryError
+#if>
+org.gradle.daemon=true
+org.gradle.parallel=true
+org.gradle.parallel.threads=8
+org.gradle.configureondemand=true
android.enableJetifier=true
-android.useAndroidX=true
\ No newline at end of file
+android.useAndroidX=true
diff -Nru minetest-5.2.0/build/android/gradlew minetest-5.3.0/build/android/gradlew
--- minetest-5.2.0/build/android/gradlew 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/build/android/gradlew 2020-07-09 21:13:20.000000000 +0000
@@ -1,5 +1,21 @@
#!/usr/bin/env sh
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
##############################################################################
##
## Gradle start up script for UN*X
@@ -28,7 +44,7 @@
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
@@ -109,8 +125,8 @@
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin ; then
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
diff -Nru minetest-5.2.0/build/android/gradlew.bat minetest-5.3.0/build/android/gradlew.bat
--- minetest-5.2.0/build/android/gradlew.bat 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/build/android/gradlew.bat 2020-07-09 21:13:20.000000000 +0000
@@ -1,3 +1,19 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@@ -14,7 +30,7 @@
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
diff -Nru minetest-5.2.0/build/android/jni/Android.mk minetest-5.3.0/build/android/jni/Android.mk
--- minetest-5.2.0/build/android/jni/Android.mk 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/build/android/jni/Android.mk 1970-01-01 00:00:00.000000000 +0000
@@ -1,446 +0,0 @@
-LOCAL_PATH := $(call my-dir)/..
-
-#LOCAL_ADDRESS_SANITIZER:=true
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := Irrlicht
-LOCAL_SRC_FILES := deps/irrlicht/lib/Android/libIrrlicht.a
-include $(PREBUILT_STATIC_LIBRARY)
-
-ifeq ($(HAVE_LEVELDB), 1)
- include $(CLEAR_VARS)
- LOCAL_MODULE := LevelDB
- LOCAL_SRC_FILES := deps/leveldb/libleveldb.a
- include $(PREBUILT_STATIC_LIBRARY)
-endif
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := curl
-LOCAL_SRC_FILES := deps/curl/lib/.libs/libcurl.a
-include $(PREBUILT_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := freetype
-LOCAL_SRC_FILES := deps/freetype2-android/Android/obj/local/$(TARGET_ARCH_ABI)/libfreetype2-static.a
-include $(PREBUILT_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := iconv
-LOCAL_SRC_FILES := deps/libiconv/lib/.libs/libiconv.so
-include $(PREBUILT_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := openal
-LOCAL_SRC_FILES := deps/openal-soft/libs/$(TARGET_LIBDIR)/libopenal.so
-include $(PREBUILT_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := ogg
-LOCAL_SRC_FILES := deps/libvorbis-libogg-android/libs/$(TARGET_LIBDIR)/libogg.so
-include $(PREBUILT_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := vorbis
-LOCAL_SRC_FILES := deps/libvorbis-libogg-android/libs/$(TARGET_LIBDIR)/libvorbis.so
-include $(PREBUILT_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := ssl
-LOCAL_SRC_FILES := deps/openssl/libssl.a
-include $(PREBUILT_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := crypto
-LOCAL_SRC_FILES := deps/openssl/libcrypto.a
-include $(PREBUILT_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := minetest
-
-LOCAL_CPP_FEATURES += exceptions
-
-ifdef GPROF
-GPROF_DEF=-DGPROF
-endif
-
-LOCAL_CFLAGS := -D_IRR_ANDROID_PLATFORM_ \
- -DHAVE_TOUCHSCREENGUI \
- -DENABLE_GLES=1 \
- -DUSE_CURL=1 \
- -DUSE_SOUND=1 \
- -DUSE_FREETYPE=1 \
- -DUSE_LEVELDB=$(HAVE_LEVELDB) \
- $(GPROF_DEF) \
- -pipe -fstrict-aliasing
-
-ifndef NDEBUG
-LOCAL_CFLAGS += -g -D_DEBUG -O0 -fno-omit-frame-pointer
-else
-LOCAL_CFLAGS += $(TARGET_CFLAGS_ADDON)
-endif
-
-ifdef GPROF
-PROFILER_LIBS := android-ndk-profiler
-LOCAL_CFLAGS += -pg
-endif
-
-# LOCAL_CFLAGS += -fsanitize=address
-# LOCAL_LDFLAGS += -fsanitize=address
-
-ifeq ($(TARGET_ABI),x86)
-LOCAL_CFLAGS += -fno-stack-protector
-endif
-
-LOCAL_C_INCLUDES := \
- jni/src \
- jni/src/script \
- jni/lib/gmp \
- jni/lib/lua/src \
- jni/lib/jsoncpp \
- jni/src/cguittfont \
- deps/irrlicht/include \
- deps/libiconv/include \
- deps/freetype2-android/include \
- deps/curl/include \
- deps/openal-soft/jni/OpenAL/include \
- deps/libvorbis-libogg-android/jni/include \
- deps/leveldb/include \
- deps/sqlite/
-
-LOCAL_SRC_FILES := \
- jni/src/ban.cpp \
- jni/src/chat.cpp \
- jni/src/client/activeobjectmgr.cpp \
- jni/src/client/camera.cpp \
- jni/src/client/client.cpp \
- jni/src/client/clientenvironment.cpp \
- jni/src/client/clientlauncher.cpp \
- jni/src/client/clientmap.cpp \
- jni/src/client/clientmedia.cpp \
- jni/src/client/clientobject.cpp \
- jni/src/client/clouds.cpp \
- jni/src/client/content_cao.cpp \
- jni/src/client/content_cso.cpp \
- jni/src/client/content_mapblock.cpp \
- jni/src/client/filecache.cpp \
- jni/src/client/fontengine.cpp \
- jni/src/client/game.cpp \
- jni/src/client/gameui.cpp \
- jni/src/client/guiscalingfilter.cpp \
- jni/src/client/hud.cpp \
- jni/src/clientiface.cpp \
- jni/src/client/imagefilters.cpp \
- jni/src/client/inputhandler.cpp \
- jni/src/client/joystick_controller.cpp \
- jni/src/client/keycode.cpp \
- jni/src/client/localplayer.cpp \
- jni/src/client/mapblock_mesh.cpp \
- jni/src/client/mesh.cpp \
- jni/src/client/meshgen/collector.cpp \
- jni/src/client/mesh_generator_thread.cpp \
- jni/src/client/minimap.cpp \
- jni/src/client/particles.cpp \
- jni/src/client/render/anaglyph.cpp \
- jni/src/client/render/core.cpp \
- jni/src/client/render/factory.cpp \
- jni/src/client/renderingengine.cpp \
- jni/src/client/render/interlaced.cpp \
- jni/src/client/render/pageflip.cpp \
- jni/src/client/render/plain.cpp \
- jni/src/client/render/sidebyside.cpp \
- jni/src/client/render/stereo.cpp \
- jni/src/client/shader.cpp \
- jni/src/client/sky.cpp \
- jni/src/client/sound.cpp \
- jni/src/client/sound_openal.cpp \
- jni/src/client/tile.cpp \
- jni/src/client/wieldmesh.cpp \
- jni/src/collision.cpp \
- jni/src/content/content.cpp \
- jni/src/content_mapnode.cpp \
- jni/src/content/mods.cpp \
- jni/src/content_nodemeta.cpp \
- jni/src/content/packages.cpp \
- jni/src/content_sao.cpp \
- jni/src/content/subgames.cpp \
- jni/src/convert_json.cpp \
- jni/src/craftdef.cpp \
- jni/src/database/database.cpp \
- jni/src/database/database-dummy.cpp \
- jni/src/database/database-files.cpp \
- jni/src/database/database-leveldb.cpp \
- jni/src/database/database-sqlite3.cpp \
- jni/src/debug.cpp \
- jni/src/defaultsettings.cpp \
- jni/src/emerge.cpp \
- jni/src/environment.cpp \
- jni/src/face_position_cache.cpp \
- jni/src/filesys.cpp \
- jni/src/genericobject.cpp \
- jni/src/gettext.cpp \
- jni/src/gui/guiAnimatedImage.cpp \
- jni/src/gui/guiBackgroundImage.cpp \
- jni/src/gui/guiBox.cpp \
- jni/src/gui/guiButton.cpp \
- jni/src/gui/guiButtonImage.cpp \
- jni/src/gui/guiButtonItemImage.cpp \
- jni/src/gui/guiChatConsole.cpp \
- jni/src/gui/guiConfirmRegistration.cpp \
- jni/src/gui/guiEditBoxWithScrollbar.cpp \
- jni/src/gui/guiEngine.cpp \
- jni/src/gui/guiFormSpecMenu.cpp \
- jni/src/gui/guiHyperText.cpp \
- jni/src/gui/guiInventoryList.cpp \
- jni/src/gui/guiItemImage.cpp \
- jni/src/gui/guiKeyChangeMenu.cpp \
- jni/src/gui/guiPasswordChange.cpp \
- jni/src/gui/guiPathSelectMenu.cpp \
- jni/src/gui/guiScrollBar.cpp \
- jni/src/gui/guiSkin.cpp \
- jni/src/gui/guiTable.cpp \
- jni/src/gui/guiVolumeChange.cpp \
- jni/src/gui/intlGUIEditBox.cpp \
- jni/src/gui/modalMenu.cpp \
- jni/src/gui/profilergraph.cpp \
- jni/src/gui/touchscreengui.cpp \
- jni/src/httpfetch.cpp \
- jni/src/hud.cpp \
- jni/src/inventory.cpp \
- jni/src/inventorymanager.cpp \
- jni/src/irrlicht_changes/CGUITTFont.cpp \
- jni/src/irrlicht_changes/static_text.cpp \
- jni/src/itemdef.cpp \
- jni/src/itemstackmetadata.cpp \
- jni/src/light.cpp \
- jni/src/log.cpp \
- jni/src/main.cpp \
- jni/src/mapblock.cpp \
- jni/src/map.cpp \
- jni/src/mapgen/cavegen.cpp \
- jni/src/mapgen/dungeongen.cpp \
- jni/src/mapgen/mapgen_carpathian.cpp \
- jni/src/mapgen/mapgen.cpp \
- jni/src/mapgen/mapgen_flat.cpp \
- jni/src/mapgen/mapgen_fractal.cpp \
- jni/src/mapgen/mapgen_singlenode.cpp \
- jni/src/mapgen/mapgen_v5.cpp \
- jni/src/mapgen/mapgen_v6.cpp \
- jni/src/mapgen/mapgen_v7.cpp \
- jni/src/mapgen/mapgen_valleys.cpp \
- jni/src/mapgen/mg_biome.cpp \
- jni/src/mapgen/mg_decoration.cpp \
- jni/src/mapgen/mg_ore.cpp \
- jni/src/mapgen/mg_schematic.cpp \
- jni/src/mapgen/treegen.cpp \
- jni/src/mapnode.cpp \
- jni/src/mapsector.cpp \
- jni/src/map_settings_manager.cpp \
- jni/src/metadata.cpp \
- jni/src/modchannels.cpp \
- jni/src/nameidmapping.cpp \
- jni/src/nodedef.cpp \
- jni/src/nodemetadata.cpp \
- jni/src/nodetimer.cpp \
- jni/src/noise.cpp \
- jni/src/objdef.cpp \
- jni/src/object_properties.cpp \
- jni/src/pathfinder.cpp \
- jni/src/player.cpp \
- jni/src/porting_android.cpp \
- jni/src/porting.cpp \
- jni/src/profiler.cpp \
- jni/src/raycast.cpp \
- jni/src/reflowscan.cpp \
- jni/src/remoteplayer.cpp \
- jni/src/rollback.cpp \
- jni/src/rollback_interface.cpp \
- jni/src/serialization.cpp \
- jni/src/server/activeobjectmgr.cpp \
- jni/src/server.cpp \
- jni/src/serverenvironment.cpp \
- jni/src/serverlist.cpp \
- jni/src/server/mods.cpp \
- jni/src/serverobject.cpp \
- jni/src/settings.cpp \
- jni/src/staticobject.cpp \
- jni/src/tileanimation.cpp \
- jni/src/tool.cpp \
- jni/src/translation.cpp \
- jni/src/unittest/test_authdatabase.cpp \
- jni/src/unittest/test_collision.cpp \
- jni/src/unittest/test_compression.cpp \
- jni/src/unittest/test_connection.cpp \
- jni/src/unittest/test.cpp \
- jni/src/unittest/test_filepath.cpp \
- jni/src/unittest/test_gameui.cpp \
- jni/src/unittest/test_inventory.cpp \
- jni/src/unittest/test_mapnode.cpp \
- jni/src/unittest/test_map_settings_manager.cpp \
- jni/src/unittest/test_nodedef.cpp \
- jni/src/unittest/test_noderesolver.cpp \
- jni/src/unittest/test_noise.cpp \
- jni/src/unittest/test_objdef.cpp \
- jni/src/unittest/test_profiler.cpp \
- jni/src/unittest/test_random.cpp \
- jni/src/unittest/test_schematic.cpp \
- jni/src/unittest/test_serialization.cpp \
- jni/src/unittest/test_settings.cpp \
- jni/src/unittest/test_socket.cpp \
- jni/src/unittest/test_utilities.cpp \
- jni/src/unittest/test_voxelalgorithms.cpp \
- jni/src/unittest/test_voxelmanipulator.cpp \
- jni/src/util/areastore.cpp \
- jni/src/util/auth.cpp \
- jni/src/util/base64.cpp \
- jni/src/util/directiontables.cpp \
- jni/src/util/enriched_string.cpp \
- jni/src/util/ieee_float.cpp \
- jni/src/util/numeric.cpp \
- jni/src/util/pointedthing.cpp \
- jni/src/util/quicktune.cpp \
- jni/src/util/serialize.cpp \
- jni/src/util/sha1.cpp \
- jni/src/util/srp.cpp \
- jni/src/util/string.cpp \
- jni/src/util/timetaker.cpp \
- jni/src/version.cpp \
- jni/src/voxelalgorithms.cpp \
- jni/src/voxel.cpp
-
-
-# intentionally kept out (we already build openssl itself): jni/src/util/sha256.c
-
-# Network
-LOCAL_SRC_FILES += \
- jni/src/network/address.cpp \
- jni/src/network/connection.cpp \
- jni/src/network/networkpacket.cpp \
- jni/src/network/clientopcodes.cpp \
- jni/src/network/clientpackethandler.cpp \
- jni/src/network/connectionthreads.cpp \
- jni/src/network/serveropcodes.cpp \
- jni/src/network/serverpackethandler.cpp \
- jni/src/network/socket.cpp \
-
-# lua api
-LOCAL_SRC_FILES += \
- jni/src/script/common/c_content.cpp \
- jni/src/script/common/c_converter.cpp \
- jni/src/script/common/c_internal.cpp \
- jni/src/script/common/c_types.cpp \
- jni/src/script/common/helper.cpp \
- jni/src/script/cpp_api/s_async.cpp \
- jni/src/script/cpp_api/s_base.cpp \
- jni/src/script/cpp_api/s_client.cpp \
- jni/src/script/cpp_api/s_entity.cpp \
- jni/src/script/cpp_api/s_env.cpp \
- jni/src/script/cpp_api/s_inventory.cpp \
- jni/src/script/cpp_api/s_item.cpp \
- jni/src/script/cpp_api/s_mainmenu.cpp \
- jni/src/script/cpp_api/s_modchannels.cpp \
- jni/src/script/cpp_api/s_node.cpp \
- jni/src/script/cpp_api/s_nodemeta.cpp \
- jni/src/script/cpp_api/s_player.cpp \
- jni/src/script/cpp_api/s_security.cpp \
- jni/src/script/cpp_api/s_server.cpp \
- jni/src/script/lua_api/l_areastore.cpp \
- jni/src/script/lua_api/l_auth.cpp \
- jni/src/script/lua_api/l_base.cpp \
- jni/src/script/lua_api/l_camera.cpp \
- jni/src/script/lua_api/l_client.cpp \
- jni/src/script/lua_api/l_craft.cpp \
- jni/src/script/lua_api/l_env.cpp \
- jni/src/script/lua_api/l_inventory.cpp \
- jni/src/script/lua_api/l_item.cpp \
- jni/src/script/lua_api/l_itemstackmeta.cpp\
- jni/src/script/lua_api/l_localplayer.cpp \
- jni/src/script/lua_api/l_mainmenu.cpp \
- jni/src/script/lua_api/l_mapgen.cpp \
- jni/src/script/lua_api/l_metadata.cpp \
- jni/src/script/lua_api/l_minimap.cpp \
- jni/src/script/lua_api/l_modchannels.cpp \
- jni/src/script/lua_api/l_nodemeta.cpp \
- jni/src/script/lua_api/l_nodetimer.cpp \
- jni/src/script/lua_api/l_noise.cpp \
- jni/src/script/lua_api/l_object.cpp \
- jni/src/script/lua_api/l_playermeta.cpp \
- jni/src/script/lua_api/l_particles.cpp \
- jni/src/script/lua_api/l_particles_local.cpp\
- jni/src/script/lua_api/l_rollback.cpp \
- jni/src/script/lua_api/l_server.cpp \
- jni/src/script/lua_api/l_settings.cpp \
- jni/src/script/lua_api/l_sound.cpp \
- jni/src/script/lua_api/l_http.cpp \
- jni/src/script/lua_api/l_storage.cpp \
- jni/src/script/lua_api/l_util.cpp \
- jni/src/script/lua_api/l_vmanip.cpp \
- jni/src/script/scripting_client.cpp \
- jni/src/script/scripting_server.cpp \
- jni/src/script/scripting_mainmenu.cpp
-
-#freetype2 support
-#LOCAL_SRC_FILES += jni/src/cguittfont/xCGUITTFont.cpp
-
-# GMP
-LOCAL_SRC_FILES += jni/lib/gmp/mini-gmp.c
-
-# Lua
-LOCAL_SRC_FILES += \
- jni/lib/lua/src/lapi.c \
- jni/lib/lua/src/lauxlib.c \
- jni/lib/lua/src/lbaselib.c \
- jni/lib/lua/src/lcode.c \
- jni/lib/lua/src/ldblib.c \
- jni/lib/lua/src/ldebug.c \
- jni/lib/lua/src/ldo.c \
- jni/lib/lua/src/ldump.c \
- jni/lib/lua/src/lfunc.c \
- jni/lib/lua/src/lgc.c \
- jni/lib/lua/src/linit.c \
- jni/lib/lua/src/liolib.c \
- jni/lib/lua/src/llex.c \
- jni/lib/lua/src/lmathlib.c \
- jni/lib/lua/src/lmem.c \
- jni/lib/lua/src/loadlib.c \
- jni/lib/lua/src/lobject.c \
- jni/lib/lua/src/lopcodes.c \
- jni/lib/lua/src/loslib.c \
- jni/lib/lua/src/lparser.c \
- jni/lib/lua/src/lstate.c \
- jni/lib/lua/src/lstring.c \
- jni/lib/lua/src/lstrlib.c \
- jni/lib/lua/src/ltable.c \
- jni/lib/lua/src/ltablib.c \
- jni/lib/lua/src/ltm.c \
- jni/lib/lua/src/lundump.c \
- jni/lib/lua/src/lvm.c \
- jni/lib/lua/src/lzio.c \
- jni/lib/lua/src/print.c
-
-# SQLite3
-LOCAL_SRC_FILES += deps/sqlite/sqlite3.c
-
-# Threading
-LOCAL_SRC_FILES += \
- jni/src/threading/event.cpp \
- jni/src/threading/semaphore.cpp \
- jni/src/threading/thread.cpp
-
-# JSONCPP
-LOCAL_SRC_FILES += jni/lib/jsoncpp/jsoncpp.cpp
-
-LOCAL_SHARED_LIBRARIES := iconv openal ogg vorbis
-LOCAL_STATIC_LIBRARIES := Irrlicht freetype curl ssl crypto android_native_app_glue $(PROFILER_LIBS)
-
-ifeq ($(HAVE_LEVELDB), 1)
- LOCAL_STATIC_LIBRARIES += LevelDB
-endif
-LOCAL_LDLIBS := -lEGL -llog -lGLESv1_CM -lGLESv2 -lz -landroid
-
-include $(BUILD_SHARED_LIBRARY)
-
-# at the end of Android.mk
-ifdef GPROF
-$(call import-module,android-ndk-profiler)
-endif
-$(call import-module,android/native_app_glue)
diff -Nru minetest-5.2.0/build/android/jni/Application.mk minetest-5.3.0/build/android/jni/Application.mk
--- minetest-5.2.0/build/android/jni/Application.mk 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/build/android/jni/Application.mk 1970-01-01 00:00:00.000000000 +0000
@@ -1,9 +0,0 @@
-APP_PLATFORM := ${APP_PLATFORM}
-APP_ABI := ${TARGET_ABI}
-APP_STL := c++_shared
-APP_MODULES := minetest
-ifndef NDEBUG
-APP_OPTIM := debug
-endif
-
-APP_CPPFLAGS += -fexceptions -std=c++11 -frtti
diff -Nru minetest-5.2.0/build/android/jni/Deps.mk minetest-5.3.0/build/android/jni/Deps.mk
--- minetest-5.2.0/build/android/jni/Deps.mk 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/build/android/jni/Deps.mk 1970-01-01 00:00:00.000000000 +0000
@@ -1,7 +0,0 @@
-APP_PLATFORM := ${APP_PLATFORM}
-APP_ABI := ${TARGET_ABI}
-APP_STL := c++_shared
-APP_DEPRECATED_HEADERS := true
-
-APP_CFLAGS += ${TARGET_CFLAGS_ADDON}
-APP_CPPFLAGS += ${TARGET_CXXFLAGS_ADDON} -fexceptions -std=c++11
diff -Nru minetest-5.2.0/build/android/jni/Irrlicht.mk minetest-5.3.0/build/android/jni/Irrlicht.mk
--- minetest-5.2.0/build/android/jni/Irrlicht.mk 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/build/android/jni/Irrlicht.mk 1970-01-01 00:00:00.000000000 +0000
@@ -1,8 +0,0 @@
-APP_PLATFORM := ${APP_PLATFORM}
-APP_ABI := ${TARGET_ABI}
-APP_STL := c++_shared
-APP_DEPRECATED_HEADERS := true
-APP_MODULES := Irrlicht
-
-APP_CLAFGS += ${TARGET_CFLAGS_ADDON}
-APP_CPPFLAGS += ${TARGET_CXXFLAGS_ADDON} -fexceptions
diff -Nru minetest-5.2.0/build/android/Makefile minetest-5.3.0/build/android/Makefile
--- minetest-5.2.0/build/android/Makefile 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/build/android/Makefile 1970-01-01 00:00:00.000000000 +0000
@@ -1,763 +0,0 @@
-# build options
-
-OS := $(shell uname)
-
-# compile with GPROF
-# GPROF = 1
-
-# build for build platform
-API = 14
-APP_PLATFORM = android-$(API)
-
-ANDR_ROOT = $(shell pwd)
-PROJ_ROOT = $(shell realpath $(ANDR_ROOT)/../..)
-APP_ROOT = $(ANDR_ROOT)/src/main
-
-VERSION_MAJOR := $(shell cat $(PROJ_ROOT)/CMakeLists.txt | \
- grep ^set\(VERSION_MAJOR\ | sed 's/)/ /' | cut -f2 -d' ')
-VERSION_MINOR := $(shell cat $(PROJ_ROOT)/CMakeLists.txt | \
- grep ^set\(VERSION_MINOR\ | sed 's/)/ /' | cut -f2 -d' ')
-VERSION_PATCH := $(shell cat $(PROJ_ROOT)/CMakeLists.txt | \
- grep ^set\(VERSION_PATCH\ | sed 's/)/ /' | cut -f2 -d' ')
-
-################################################################################
-# toolchain config for arm new processors
-################################################################################
-TARGET_HOST = arm-linux
-TARGET_ABI = armeabi-v7a
-TARGET_LIBDIR = armeabi-v7a
-TARGET_TOOLCHAIN = arm-linux-androideabi-
-TARGET_CFLAGS_ADDON = -mfloat-abi=softfp -mfpu=vfpv3 -O3
-TARGET_CXXFLAGS_ADDON = $(TARGET_CFLAGS_ADDON)
-TARGET_ARCH = armv7
-CROSS_CC = clang
-CROSS_CXX = clang++
-COMPILER_VERSION = clang
-HAVE_LEVELDB = 0
-
-################################################################################
-# toolchain config for little endian mips
-################################################################################
-#TARGET_HOST = mipsel-linux
-#TARGET_ABI = mips
-#TARGET_LIBDIR = mips
-#TARGET_TOOLCHAIN = mipsel-linux-android-
-#TARGET_ARCH = mips32
-#CROSS_CC = mipsel-linux-android-gcc
-#CROSS_CXX = mipsel-linux-android-g++
-#COMPILER_VERSION = 4.9
-#HAVE_LEVELDB = 0
-
-################################################################################
-# toolchain config for x86
-################################################################################
-#TARGET_HOST = x86-linux
-#TARGET_ABI = x86
-#TARGET_LIBDIR = x86
-#TARGET_TOOLCHAIN = x86-
-#TARGET_ARCH = x86
-#CROSS_CC = clang
-#CROSS_CXX = clang++
-#COMPILER_VERSION = clang
-#HAVE_LEVELDB = 0
-
-################################################################################
-ASSETS_TIMESTAMP = deps/assets_timestamp
-
-LEVELDB_DIR = $(ANDR_ROOT)/deps/leveldb/
-LEVELDB_LIB = $(LEVELDB_DIR)libleveldb.a
-LEVELDB_TIMESTAMP = $(LEVELDB_DIR)/timestamp
-LEVELDB_TIMESTAMP_INT = $(ANDR_ROOT)/deps/leveldb_timestamp
-LEVELDB_URL_GIT = https://github.com/google/leveldb
-LEVELDB_COMMIT = 2d0320a458d0e6a20fff46d5f80b18bfdcce7018
-
-OPENAL_DIR = $(ANDR_ROOT)/deps/openal-soft/
-OPENAL_LIB = $(OPENAL_DIR)libs/$(TARGET_ABI)/libopenal.so
-OPENAL_TIMESTAMP = $(OPENAL_DIR)/timestamp
-OPENAL_TIMESTAMP_INT = $(ANDR_ROOT)/deps/openal_timestamp
-OPENAL_URL_GIT = https://github.com/apportable/openal-soft
-
-OGG_DIR = $(ANDR_ROOT)/deps/libvorbis-libogg-android/
-OGG_LIB = $(OGG_DIR)libs/$(TARGET_ABI)/libogg.so
-VORBIS_LIB = $(OGG_DIR)libs/$(TARGET_ABI)/libogg.so
-OGG_TIMESTAMP = $(OGG_DIR)timestamp
-OGG_TIMESTAMP_INT = $(ANDR_ROOT)/deps/ogg_timestamp
-OGG_URL_GIT = https://gitlab.com/minetest/libvorbis-libogg-android
-
-IRRLICHT_REVISION = 5150
-IRRLICHT_DIR = $(ANDR_ROOT)/deps/irrlicht/
-IRRLICHT_LIB = $(IRRLICHT_DIR)lib/Android/libIrrlicht.a
-IRRLICHT_TIMESTAMP = $(IRRLICHT_DIR)timestamp
-IRRLICHT_TIMESTAMP_INT = $(ANDR_ROOT)/deps/irrlicht_timestamp
-IRRLICHT_URL_SVN = https://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@$(IRRLICHT_REVISION)
-
-OPENSSL_VERSION = 1.0.2n
-OPENSSL_BASEDIR = openssl-$(OPENSSL_VERSION)
-OPENSSL_DIR = $(ANDR_ROOT)/deps/$(OPENSSL_BASEDIR)/
-OPENSSL_LIB = $(OPENSSL_DIR)/libssl.a
-OPENSSL_TIMESTAMP = $(OPENSSL_DIR)timestamp
-OPENSSL_TIMESTAMP_INT = $(ANDR_ROOT)/deps/openssl_timestamp
-OPENSSL_URL = https://www.openssl.org/source/openssl-$(OPENSSL_VERSION).tar.gz
-
-CURL_VERSION = 7.60.0
-CURL_DIR = $(ANDR_ROOT)/deps/curl-$(CURL_VERSION)
-CURL_LIB = $(CURL_DIR)/lib/.libs/libcurl.a
-CURL_TIMESTAMP = $(CURL_DIR)/timestamp
-CURL_TIMESTAMP_INT = $(ANDR_ROOT)/deps/curl_timestamp
-CURL_URL_HTTP = https://curl.haxx.se/download/curl-${CURL_VERSION}.tar.bz2
-
-FREETYPE_DIR = $(ANDR_ROOT)/deps/freetype2-android/
-FREETYPE_LIB = $(FREETYPE_DIR)/Android/obj/local/$(TARGET_ABI)/libfreetype2-static.a
-FREETYPE_TIMESTAMP = $(FREETYPE_DIR)timestamp
-FREETYPE_TIMESTAMP_INT = $(ANDR_ROOT)/deps/freetype_timestamp
-FREETYPE_URL_GIT = https://github.com/cdave1/freetype2-android
-
-ICONV_VERSION = 1.16
-ICONV_DIR = $(ANDR_ROOT)/deps/libiconv/
-ICONV_LIB = $(ICONV_DIR)/lib/.libs/libiconv.so
-ICONV_TIMESTAMP = $(ICONV_DIR)timestamp
-ICONV_TIMESTAMP_INT = $(ANDR_ROOT)/deps/iconv_timestamp
-ICONV_URL_HTTP = https://ftp.gnu.org/pub/gnu/libiconv/libiconv-$(ICONV_VERSION).tar.gz
-
-SQLITE3_FOLDER = sqlite-amalgamation-3240000
-SQLITE3_URL = https://www.sqlite.org/2018/$(SQLITE3_FOLDER).zip
-
-ANDROID_SDK = $(shell grep '^sdk\.dir' local.properties | sed 's/^.*=[[:space:]]*//')
-ANDROID_NDK = $(shell grep '^ndk\.dir' local.properties | sed 's/^.*=[[:space:]]*//')
-
-#use interim target variable to switch leveldb on or off
-ifeq ($(HAVE_LEVELDB),1)
- LEVELDB_TARGET = $(LEVELDB_LIB)
-endif
-
-.PHONY : debug release reconfig delconfig \
- leveldb_download clean_leveldb leveldb\
- irrlicht_download clean_irrlicht irrlicht \
- clean_assets assets sqlite3_download \
- freetype_download clean_freetype freetype \
- apk clean_apk \
- clean_all clean prep_srcdir \
- install_debug install_release envpaths all \
- $(ASSETS_TIMESTAMP) $(LEVELDB_TIMESTAMP) \
- $(OPENAL_TIMESTAMP) $(OGG_TIMESTAMP) \
- $(IRRLICHT_TIMESTAMP) $(CURL_TIMESTAMP) \
- $(OPENSSL_TIMESTAMP) \
- $(ANDR_ROOT)/jni/src/android_version.h \
- $(ANDR_ROOT)/jni/src/android_version_githash.h
-
-debug : local.properties
- export NDEBUG=; \
- export BUILD_TYPE=debug; \
- $(MAKE) apk
-
-all : debug release
-
-release : local.properties
- @export NDEBUG=1; \
- export BUILD_TYPE=release; \
- $(MAKE) apk
-
-reconfig: delconfig
- @$(MAKE) local.properties
-
-delconfig:
- $(RM) local.properties
-
-local.properties:
- @echo "Please specify path of ANDROID NDK"; \
- echo "e.g. $$HOME/Android/Sdk/ndk-bundle/"; \
- read ANDROID_NDK ; \
- if [ ! -d $$ANDROID_NDK ] ; then \
- echo "$$ANDROID_NDK is not a valid folder"; \
- exit 1; \
- fi; \
- echo "ndk.dir = $$ANDROID_NDK" > local.properties; \
- echo "Please specify path of ANDROID SDK"; \
- echo "e.g. $$HOME/Android/Sdk/"; \
- read SDKFLDR ; \
- if [ ! -d $$SDKFLDR ] ; then \
- echo "$$SDKFLDR is not a valid folder"; \
- exit 1; \
- fi; \
- echo "sdk.dir = $$SDKFLDR" >> local.properties;
-
-
-$(OPENAL_TIMESTAMP) : openal_download
- @LAST_MODIF=$$(find ${OPENAL_DIR} -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "); \
- if [ $$(basename $$LAST_MODIF) != "timestamp" ] ; then \
- touch ${OPENAL_TIMESTAMP}; \
- fi
-
-openal_download :
- @if [ ! -d ${OPENAL_DIR} ] ; then \
- echo "openal sources missing, downloading..."; \
- mkdir -p ${ANDR_ROOT}/deps; \
- cd ${ANDR_ROOT}/deps ; \
- git clone ${OPENAL_URL_GIT} || exit 1; \
- fi
-
-openal : $(OPENAL_LIB)
-
-$(OPENAL_LIB): $(OPENAL_TIMESTAMP)
- + @REFRESH=0; \
- if [ ! -e ${OPENAL_TIMESTAMP_INT} ] ; then \
- REFRESH=1; \
- fi; \
- if [ ${OPENAL_TIMESTAMP} -nt ${OPENAL_TIMESTAMP_INT} ] ; then \
- REFRESH=1; \
- fi; \
- if [ $$REFRESH -ne 0 ] ; then \
- echo "changed timestamp for openal detected building..."; \
- cd ${OPENAL_DIR}; \
- export APP_PLATFORM=${APP_PLATFORM}; \
- export TARGET_ABI=${TARGET_ABI}; \
- export TARGET_CFLAGS_ADDON="${TARGET_CFLAGS_ADDON}"; \
- export TARGET_CXXFLAGS_ADDON="${TARGET_CXXFLAGS_ADDON}"; \
- export COMPILER_VERSION=${COMPILER_VERSION}; \
- ${ANDROID_NDK}/ndk-build \
- NDK_APPLICATION_MK=${ANDR_ROOT}/jni/Deps.mk || exit 1; \
- touch ${OPENAL_TIMESTAMP}; \
- touch ${OPENAL_TIMESTAMP_INT}; \
- else \
- echo "nothing to be done for openal"; \
- fi
-
-clean_openal :
- $(RM) -rf ${OPENAL_DIR}
-
-$(OGG_TIMESTAMP) : ogg_download
- @LAST_MODIF=$$(find ${OGG_DIR} -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "); \
- if [ $$(basename $$LAST_MODIF) != "timestamp" ] ; then \
- touch ${OGG_TIMESTAMP}; \
- fi
-
-ogg_download :
- @if [ ! -d ${OGG_DIR} ] ; then \
- echo "ogg sources missing, downloading..."; \
- mkdir -p ${ANDR_ROOT}/deps; \
- cd ${ANDR_ROOT}/deps ; \
- git clone ${OGG_URL_GIT}|| exit 1; \
- cd libvorbis-libogg-android ; \
- patch -p1 < ${ANDR_ROOT}/patches/libvorbis-libogg-fpu.patch || exit 1; \
- fi
-
-ogg : $(OGG_LIB)
-
-$(OGG_LIB): $(OGG_TIMESTAMP)
- + @REFRESH=0; \
- if [ ! -e ${OGG_TIMESTAMP_INT} ] ; then \
- echo "${OGG_TIMESTAMP_INT} doesn't exist"; \
- REFRESH=1; \
- fi; \
- if [ ${OGG_TIMESTAMP} -nt ${OGG_TIMESTAMP_INT} ] ; then \
- REFRESH=1; \
- fi; \
- if [ $$REFRESH -ne 0 ] ; then \
- echo "changed timestamp for ogg detected building..."; \
- cd ${OGG_DIR}; \
- export APP_PLATFORM=${APP_PLATFORM}; \
- export TARGET_ABI=${TARGET_ABI}; \
- ${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \
- --toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
- --platform=${APP_PLATFORM} \
- --install-dir=$${TOOLCHAIN}; \
- touch ${OGG_TIMESTAMP}; \
- touch ${OGG_TIMESTAMP_INT}; \
- else \
- echo "nothing to be done for libogg/libvorbis"; \
- fi
-
-clean_ogg :
- $(RM) -rf ${OGG_DIR}
-
-$(OPENSSL_TIMESTAMP) : openssl_download
- @LAST_MODIF=$$(find ${OPENSSL_DIR} -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "); \
- if [ $$(basename $$LAST_MODIF) != "timestamp" ] ; then \
- touch ${OPENSSL_TIMESTAMP}; \
- fi
-
-openssl_download :
- @if [ ! -d ${OPENSSL_DIR} ] ; then \
- echo "openssl sources missing, downloading..."; \
- mkdir -p ${ANDR_ROOT}/deps; \
- cd ${ANDR_ROOT}/deps ; \
- wget ${OPENSSL_URL} || exit 1; \
- tar -xzf ${OPENSSL_BASEDIR}.tar.gz; \
- cd ${OPENSSL_BASEDIR}; \
- patch -p1 < ${ANDR_ROOT}/patches/openssl_arch.patch; \
- sed -i 's/-mandroid //g' Configure; \
- fi
-
-openssl : $(OPENSSL_LIB)
-
-$(OPENSSL_LIB): $(OPENSSL_TIMESTAMP)
- @REFRESH=0; \
- if [ ! -e ${OPENSSL_TIMESTAMP_INT} ] ; then \
- echo "${OPENSSL_TIMESTAMP_INT} doesn't exist"; \
- REFRESH=1; \
- fi; \
- if [ ${OPENSSL_TIMESTAMP} -nt ${OPENSSL_TIMESTAMP_INT} ] ; then \
- REFRESH=1; \
- fi; \
- if [ $$REFRESH -ne 0 ] ; then \
- echo "changed timestamp for openssl detected building..."; \
- cd ${OPENSSL_DIR}; \
- ln -s ${OPENSSL_DIR} ../openssl; \
- export TOOLCHAIN=/tmp/ndk-${TARGET_HOST}-openssl; \
- ${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \
- --toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
- --platform=${APP_PLATFORM} \
- --stl=libc++ \
- --install-dir=$${TOOLCHAIN}; \
- export PATH="$${TOOLCHAIN}/bin:$${PATH}"; \
- export CFLAGS="$${CFLAGS} ${TARGET_CFLAGS_ADDON}"; \
- export LDFLAGS="$${LDFLAGS} ${TARGET_LDFLAGS_ADDON}"; \
- CC=${CROSS_CC} ./Configure -DL_ENDIAN no-asm android-${TARGET_ARCH} \
- -D__ANDROID_API__=$(API); \
- CC=${CROSS_CC} ANDROID_DEV=/tmp/ndk-${TARGET_HOST} make depend; \
- CC=${CROSS_CC} ANDROID_DEV=/tmp/ndk-${TARGET_HOST} make build_libs; \
- touch ${OPENSSL_TIMESTAMP}; \
- touch ${OPENSSL_TIMESTAMP_INT}; \
- $(RM) -rf $${TOOLCHAIN}; \
- else \
- echo "nothing to be done for openssl"; \
- fi
-
-clean_openssl :
- $(RM) -rf ${OPENSSL_DIR}; \
- $(RM) -rf $(ANDR_ROOT)/deps/${OPENSSL_BASEDIR}.tar.gz; \
- $(RM) -rf $(ANDR_ROOT)/deps/openssl
-
-$(LEVELDB_TIMESTAMP) : leveldb_download
- @LAST_MODIF=$$(find ${LEVELDB_DIR} -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "); \
- if [ $$(basename $$LAST_MODIF) != "timestamp" ] ; then \
- touch ${LEVELDB_TIMESTAMP}; \
- fi
-
-leveldb_download :
- @if [ ! -d ${LEVELDB_DIR} ] ; then \
- echo "leveldb sources missing, downloading..."; \
- mkdir -p ${ANDR_ROOT}/deps; \
- cd ${ANDR_ROOT}/deps ; \
- git clone ${LEVELDB_URL_GIT} || exit 1; \
- cd ${LEVELDB_DIR} || exit 1; \
- git checkout ${LEVELDB_COMMIT} || exit 1; \
- fi
-
-leveldb : $(LEVELDB_LIB)
-ifeq ($(HAVE_LEVELDB),1)
-$(LEVELDB_LIB): $(LEVELDB_TIMESTAMP)
- @REFRESH=0; \
- if [ ! -e ${LEVELDB_TIMESTAMP_INT} ] ; then \
- REFRESH=1; \
- fi; \
- if [ ${LEVELDB_TIMESTAMP} -nt ${LEVELDB_TIMESTAMP_INT} ] ; then \
- REFRESH=1; \
- fi; \
- if [ $$REFRESH -ne 0 ] ; then \
- echo "changed timestamp for leveldb detected building..."; \
- cd deps/leveldb; \
- export CROSS_PREFIX=${TARGET_TOOLCHAIN}; \
- export TOOLCHAIN=/tmp/ndk-${TARGET_HOST}-leveldb; \
- ${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \
- --toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
- --platform=${APP_PLATFORM} \
- --stl=libc++ \
- --install-dir=$${TOOLCHAIN}; \
- export PATH="$${TOOLCHAIN}/bin:$${PATH}"; \
- export CC=${CROSS_CC}; \
- export CXX=${CROSS_CXX}; \
- export CFLAGS="$${CFLAGS} ${TARGET_CFLAGS_ADDON}"; \
- export CPPFLAGS="$${CPPFLAGS} ${TARGET_CXXFLAGS_ADDON}"; \
- export LDFLAGS="$${LDFLAGS} ${TARGET_LDFLAGS_ADDON}"; \
- export TARGET_OS=OS_ANDROID_CROSSCOMPILE; \
- $(MAKE) || exit 1; \
- touch ${LEVELDB_TIMESTAMP}; \
- touch ${LEVELDB_TIMESTAMP_INT}; \
- $(RM) -rf $${TOOLCHAIN}; \
- else \
- echo "nothing to be done for leveldb"; \
- fi
-endif
-
-clean_leveldb :
- ./gradlew cleanLevelDB
-
-$(FREETYPE_TIMESTAMP) : freetype_download
- @LAST_MODIF=$$(find ${FREETYPE_DIR} -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "); \
- if [ $$(basename $$LAST_MODIF) != "timestamp" ] ; then \
- touch ${FREETYPE_TIMESTAMP}; \
- fi
-
-freetype_download :
- @if [ ! -d ${FREETYPE_DIR} ] ; then \
- echo "freetype sources missing, downloading..."; \
- mkdir -p ${ANDR_ROOT}/deps; \
- cd deps; \
- git clone ${FREETYPE_URL_GIT} || exit 1; \
- fi
-
-freetype : $(FREETYPE_LIB)
-
-$(FREETYPE_LIB) : $(FREETYPE_TIMESTAMP)
- + @REFRESH=0; \
- if [ ! -e ${FREETYPE_TIMESTAMP_INT} ] ; then \
- REFRESH=1; \
- fi; \
- if [ ! -e ${FREETYPE_LIB} ] ; then \
- REFRESH=1; \
- fi; \
- if [ ${FREETYPE_TIMESTAMP} -nt ${FREETYPE_TIMESTAMP_INT} ] ; then \
- REFRESH=1; \
- fi; \
- if [ $$REFRESH -ne 0 ] ; then \
- mkdir -p ${FREETYPE_DIR}; \
- echo "changed timestamp for freetype detected building..."; \
- cd ${FREETYPE_DIR}/Android/jni; \
- export APP_PLATFORM=${APP_PLATFORM}; \
- export TARGET_ABI=${TARGET_ABI}; \
- export TARGET_CFLAGS_ADDON="${TARGET_CFLAGS_ADDON}"; \
- export TARGET_CXXFLAGS_ADDON="${TARGET_CXXFLAGS_ADDON}"; \
- export COMPILER_VERSION=${COMPILER_VERSION}; \
- ${ANDROID_NDK}/ndk-build \
- NDK_APPLICATION_MK=${ANDR_ROOT}/jni/Deps.mk || exit 1; \
- touch ${FREETYPE_TIMESTAMP}; \
- touch ${FREETYPE_TIMESTAMP_INT}; \
- else \
- echo "nothing to be done for freetype"; \
- fi
-
-clean_freetype :
- ./gradlew cleanFreetype
-
-$(ICONV_TIMESTAMP) : iconv_download
- @LAST_MODIF=$$(find ${ICONV_DIR} -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "); \
- if [ $$(basename $$LAST_MODIF) != "timestamp" ] ; then \
- touch ${ICONV_TIMESTAMP}; \
- fi
-
-iconv_download :
- @if [ ! -d ${ICONV_DIR} ] ; then \
- echo "iconv sources missing, downloading..."; \
- mkdir -p ${ANDR_ROOT}/deps; \
- cd ${ANDR_ROOT}/deps; \
- wget ${ICONV_URL_HTTP} || exit 1; \
- tar -xzf libiconv-${ICONV_VERSION}.tar.gz || exit 1; \
- rm libiconv-${ICONV_VERSION}.tar.gz; \
- ln -s libiconv-${ICONV_VERSION} libiconv; \
- fi
-
-iconv : $(ICONV_LIB)
-
-$(ICONV_LIB) : $(ICONV_TIMESTAMP)
- @REFRESH=0; \
- if [ ! -e ${ICONV_TIMESTAMP_INT} ] ; then \
- REFRESH=1; \
- fi; \
- if [ ! -e ${ICONV_LIB} ] ; then \
- REFRESH=1; \
- fi; \
- if [ ${ICONV_TIMESTAMP} -nt ${ICONV_TIMESTAMP_INT} ] ; then \
- REFRESH=1; \
- fi; \
- if [ $$REFRESH -ne 0 ] ; then \
- mkdir -p ${ICONV_DIR}; \
- echo "changed timestamp for iconv detected building..."; \
- cd ${ICONV_DIR}; \
- export TOOLCHAIN=/tmp/ndk-${TARGET_HOST}-iconv; \
- ${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \
- --toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
- --platform=${APP_PLATFORM} \
- --stl=libc++ \
- --install-dir=$${TOOLCHAIN}; \
- export PATH="$${TOOLCHAIN}/bin:$${PATH}"; \
- export CFLAGS="$${CFLAGS} ${TARGET_CFLAGS_ADDON}"; \
- export LDFLAGS="$${LDFLAGS} ${TARGET_LDFLAGS_ADDON} -lstdc++"; \
- export CC=${CROSS_CC}; \
- export CXX=${CROSS_CXX}; \
- export TARGET_OS=OS_ANDROID_CROSSCOMPILE; \
- ./configure --host=${TARGET_HOST} || exit 1; \
- sed -i 's/LIBICONV_VERSION_INFO) /LIBICONV_VERSION_INFO) -avoid-version /g' lib/Makefile; \
- grep "iconv_LDFLAGS" src/Makefile; \
- $(MAKE) -s || exit 1; \
- touch ${ICONV_TIMESTAMP}; \
- touch ${ICONV_TIMESTAMP_INT}; \
- rm -rf ${TOOLCHAIN}; \
- else \
- echo "nothing to be done for iconv"; \
- fi
-
-clean_iconv :
- ./gradlew cleanIconv
-
-#Note: Texturehack patch is required for gpu's not supporting color format
-# correctly. Known bad GPU:
-# -geforce on emulator
-# -Vivante Corporation GC1000 core (e.g. Galaxy Tab 3)
-
-irrlicht_download :
- @if [ ! -d "deps/irrlicht" ] ; then \
- echo "irrlicht sources missing, downloading..."; \
- mkdir -p ${ANDR_ROOT}/deps; \
- cd deps; \
- svn co ${IRRLICHT_URL_SVN} irrlicht || exit 1; \
- cd irrlicht; \
- patch -p1 < ${ANDR_ROOT}/patches/irrlicht-touchcount.patch || exit 1; \
- patch -p1 < ${ANDR_ROOT}/patches/irrlicht-back_button.patch || exit 1; \
- patch -p1 < ${ANDR_ROOT}/patches/irrlicht-texturehack.patch || exit 1; \
- patch -p1 < ${ANDR_ROOT}/patches/irrlicht-native_activity.patch || exit 1; \
- fi
-
-$(IRRLICHT_TIMESTAMP) : irrlicht_download
- @LAST_MODIF=$$(find ${IRRLICHT_DIR} -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "); \
- if [ $$(basename $$LAST_MODIF) != "timestamp" ] ; then \
- touch ${IRRLICHT_TIMESTAMP}; \
- fi
-
-irrlicht : $(IRRLICHT_LIB)
-
-$(IRRLICHT_LIB): $(IRRLICHT_TIMESTAMP) $(FREETYPE_LIB)
- + @REFRESH=0; \
- if [ ! -e ${IRRLICHT_TIMESTAMP_INT} ] ; then \
- REFRESH=1; \
- fi; \
- if [ ! -e ${IRRLICHT_LIB} ] ; then \
- REFRESH=1; \
- fi; \
- if [ ${IRRLICHT_TIMESTAMP} -nt ${IRRLICHT_TIMESTAMP_INT} ] ; then \
- REFRESH=1; \
- fi; \
- if [ $$REFRESH -ne 0 ] ; then \
- mkdir -p ${IRRLICHT_DIR}; \
- echo "changed timestamp for irrlicht detected building..."; \
- cd deps/irrlicht/source/Irrlicht/Android; \
- export APP_PLATFORM=${APP_PLATFORM}; \
- export TARGET_ABI=${TARGET_ABI}; \
- export TARGET_CFLAGS_ADDON="${TARGET_CFLAGS_ADDON}"; \
- export TARGET_CXXFLAGS_ADDON="${TARGET_CXXFLAGS_ADDON}"; \
- export COMPILER_VERSION=${COMPILER_VERSION}; \
- ${ANDROID_NDK}/ndk-build \
- NDK_APPLICATION_MK=${ANDR_ROOT}/jni/Deps.mk || exit 1; \
- touch ${IRRLICHT_TIMESTAMP}; \
- touch ${IRRLICHT_TIMESTAMP_INT}; \
- else \
- echo "nothing to be done for irrlicht"; \
- fi
-
-clean_irrlicht :
- ./gradlew cleanIrrlicht
-
-$(CURL_TIMESTAMP) : curl_download
- @LAST_MODIF=$$(find ${CURL_DIR} -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "); \
- if [ $$(basename $$LAST_MODIF) != "timestamp" ] ; then \
- touch ${CURL_TIMESTAMP}; \
- fi
-
-curl_download :
- @if [ ! -d "deps/curl-${CURL_VERSION}" ] ; then \
- echo "curl sources missing, downloading..."; \
- mkdir -p ${ANDR_ROOT}/deps; \
- cd deps; \
- wget ${CURL_URL_HTTP} || exit 1; \
- tar -xjf curl-${CURL_VERSION}.tar.bz2 || exit 1; \
- rm curl-${CURL_VERSION}.tar.bz2; \
- ln -s curl-${CURL_VERSION} curl; \
- fi
-
-curl : $(CURL_LIB)
-
-$(CURL_LIB): $(CURL_TIMESTAMP) $(OPENSSL_LIB)
- @REFRESH=0; \
- if [ ! -e ${CURL_TIMESTAMP_INT} ] ; then \
- REFRESH=1; \
- fi; \
- if [ ! -e ${CURL_LIB} ] ; then \
- REFRESH=1; \
- fi; \
- if [ ${CURL_TIMESTAMP} -nt ${CURL_TIMESTAMP_INT} ] ; then \
- REFRESH=1; \
- fi; \
- if [ $$REFRESH -ne 0 ] ; then \
- mkdir -p ${CURL_DIR}; \
- echo "changed timestamp for curl detected building..."; \
- cd deps/curl-${CURL_VERSION}; \
- export CROSS_PREFIX=${TARGET_TOOLCHAIN}; \
- export TOOLCHAIN=/tmp/ndk-${TARGET_HOST}-curl; \
- ${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \
- --toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
- --platform=${APP_PLATFORM} \
- --stl=libc++ \
- --install-dir=$${TOOLCHAIN}; \
- export PATH="$${TOOLCHAIN}/bin:$${PATH}"; \
- export CC=${CROSS_CC}; \
- export CXX=${CROSS_CXX}; \
- export TARGET_OS=OS_ANDROID_CROSSCOMPILE; \
- export CPPFLAGS="$${CPPFLAGS} -I${OPENSSL_DIR}/include ${TARGET_CFLAGS_ADDON}"; \
- export CFLAGS="$${CFLAGS} ${TARGET_CFLAGS_ADDON}"; \
- export LDFLAGS="$${LDFLAGS} -L${OPENSSL_DIR} ${TARGET_LDFLAGS_ADDON}"; \
- ./configure --host=${TARGET_HOST} --disable-shared --enable-static --with-ssl; \
- $(MAKE) -s || exit 1; \
- touch ${CURL_TIMESTAMP}; \
- touch ${CURL_TIMESTAMP_INT}; \
- $(RM) -rf $${TOOLCHAIN}; \
- else \
- echo "nothing to be done for curl"; \
- fi
-
-clean_curl :
- ./gradlew cleanCURL
-
-sqlite3_download: deps/${SQLITE3_FOLDER}/sqlite3.c
-
-deps/${SQLITE3_FOLDER}/sqlite3.c :
- cd deps; \
- wget ${SQLITE3_URL}; \
- unzip ${SQLITE3_FOLDER}.zip; \
- ln -s ${SQLITE3_FOLDER} sqlite; \
- cd ${SQLITE3_FOLDER};
-
-clean_sqlite3:
- ./gradlew cleanSQLite3
-
-$(ASSETS_TIMESTAMP) : $(IRRLICHT_LIB)
- @mkdir -p ${ANDR_ROOT}/deps; \
- for DIRNAME in {builtin,client,doc,fonts,games,mods,po,textures}; do \
- LAST_MODIF=$$(find ${PROJ_ROOT}/${DIRNAME} -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "); \
- if [ $$(basename $$LAST_MODIF) != "timestamp" ]; then \
- touch ${PROJ_ROOT}/${DIRNAME}/timestamp; \
- touch ${ASSETS_TIMESTAMP}; \
- echo ${DIRNAME} changed $$LAST_MODIF; \
- fi; \
- done; \
- LAST_MODIF=$$(find ${IRRLICHT_DIR}/media -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "); \
- if [ $$(basename $$LAST_MODIF) != "timestamp" ] ; then \
- touch ${IRRLICHT_DIR}/media/timestamp; \
- touch ${ASSETS_TIMESTAMP}; \
- fi; \
- if [ ${PROJ_ROOT}/minetest.conf.example -nt ${ASSETS_TIMESTAMP} ] ; then \
- echo "conf changed"; \
- touch ${ASSETS_TIMESTAMP}; \
- fi; \
- if [ ${PROJ_ROOT}/README.txt -nt ${ASSETS_TIMESTAMP} ] ; then \
- touch ${ASSETS_TIMESTAMP}; \
- fi; \
- if [ ! -e $(ASSETS_TIMESTAMP) ] ; then \
- touch $(ASSETS_TIMESTAMP); \
- fi
-
-assets : $(ASSETS_TIMESTAMP)
- @REFRESH=0; \
- if [ ! -e ${ASSETS_TIMESTAMP}.old ] ; then \
- REFRESH=1; \
- fi; \
- if [ ${ASSETS_TIMESTAMP} -nt ${ASSETS_TIMESTAMP}.old ] ; then \
- REFRESH=1; \
- fi; \
- if [ ! -d ${APP_ROOT}/assets ] ; then \
- REFRESH=1; \
- fi; \
- if [ $$REFRESH -ne 0 ] ; then \
- echo "assets changed, refreshing..."; \
- $(MAKE) clean_assets; \
- ./gradlew copyAssets; \
- cp -r ${IRRLICHT_DIR}/media/Shaders ${APP_ROOT}/assets/Minetest/media; \
- cd ${APP_ROOT}/assets || exit 1; \
- find . -name "timestamp" -exec rm {} \; ; \
- find . -name "*.blend" -exec rm {} \; ; \
- find . -name "*~" -exec rm {} \; ; \
- find . -type d -path "*.git" -exec rm -rf {} \; ; \
- find . -type d -path "*.svn" -exec rm -rf {} \; ; \
- find . -type f -path "*.gitignore" -exec rm -rf {} \; ; \
- ls -R | grep ":$$" | sed -e 's/:$$//' -e 's/\.//' -e 's/^\///' > "index.txt"; \
- find -L Minetest > filelist.txt; \
- cp ${ANDR_ROOT}/${ASSETS_TIMESTAMP} ${ANDR_ROOT}/${ASSETS_TIMESTAMP}.old; \
- else \
- echo "nothing to be done for assets"; \
- fi
-
-clean_assets :
- ./gradlew cleanAssets
-
-apk: local.properties assets $(ICONV_LIB) $(IRRLICHT_LIB) $(CURL_LIB) $(LEVELDB_TARGET) \
- $(OPENAL_LIB) $(OGG_LIB) prep_srcdir $(ANDR_ROOT)/jni/src/android_version.h \
- $(ANDR_ROOT)/jni/src/android_version_githash.h sqlite3_download
- + @export TARGET_LIBDIR=${TARGET_LIBDIR}; \
- export HAVE_LEVELDB=${HAVE_LEVELDB}; \
- export APP_PLATFORM=${APP_PLATFORM}; \
- export TARGET_ABI=${TARGET_ABI}; \
- export TARGET_CFLAGS_ADDON="${TARGET_CFLAGS_ADDON}"; \
- export TARGET_CXXFLAGS_ADDON="${TARGET_CXXFLAGS_ADDON}"; \
- export COMPILER_VERSION=${COMPILER_VERSION}; \
- export GPROF=${GPROF}; \
- ${ANDROID_NDK}/ndk-build || exit 1; \
- if [ ! -e ${APP_ROOT}/jniLibs ]; then \
- ln -s ${ANDR_ROOT}/libs ${APP_ROOT}/jniLibs || exit 1; \
- fi; \
- export VERSION_STR="${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}" && \
- export BUILD_TYPE_C=$$(echo "$${BUILD_TYPE}" | sed 's/./\U&/') && \
- ./gradlew assemble$$BUILD_TYPE_C && \
- echo "APK stored at: build/outputs/apk/$$BUILD_TYPE/Minetest-$$BUILD_TYPE.apk" && \
- echo "You can install it with \`make install_$$BUILD_TYPE\`"
-
-# These Intentionally doesn't depend on their respective build steps,
-# because it takes a while to verify that everything's up-to-date.
-install_debug:
- ${ANDROID_SDK}/platform-tools/adb install -r build/outputs/apk/debug/Minetest-debug.apk
-
-install_release:
- ${ANDROID_SDK}/platform-tools/adb install -r build/outputs/apk/release/Minetest-release.apk
-
-prep_srcdir :
- @if [ ! -e ${ANDR_ROOT}/jni/src ]; then \
- ln -s ${PROJ_ROOT}/src ${ANDR_ROOT}/jni/src; \
- fi; \
- if [ ! -e ${ANDR_ROOT}/jni/lib ]; then \
- ln -s ${PROJ_ROOT}/lib ${ANDR_ROOT}/jni/lib; \
- fi
-
-clean_apk :
- ./gradlew clean
-
-clean_all :
- ./gradlew cleanAll
-
-$(ANDR_ROOT)/jni/src/android_version_githash.h : prep_srcdir
- @export VERSION_FILE=${ANDR_ROOT}/jni/src/android_version_githash.h; \
- export VERSION_FILE_NEW=$${VERSION_FILE}.new; \
- { \
- echo "#ifndef ANDROID_MT_VERSION_GITHASH_H"; \
- echo "#define ANDROID_MT_VERSION_GITHASH_H"; \
- export GITHASH=$$(git rev-parse --short=8 HEAD); \
- export VERSION_STR="${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}"; \
- echo "#define VERSION_GITHASH \"$$VERSION_STR-$$GITHASH-Android\""; \
- echo "#endif"; \
- } > "$${VERSION_FILE_NEW}"; \
- if ! cmp -s $${VERSION_FILE} $${VERSION_FILE_NEW}; then \
- echo "android_version_githash.h changed, updating..."; \
- mv "$${VERSION_FILE_NEW}" "$${VERSION_FILE}"; \
- else \
- rm "$${VERSION_FILE_NEW}"; \
- fi
-
-
-$(ANDR_ROOT)/jni/src/android_version.h : prep_srcdir
- @export VERSION_FILE=${ANDR_ROOT}/jni/src/android_version.h; \
- export VERSION_FILE_NEW=$${VERSION_FILE}.new; \
- { \
- echo "#ifndef ANDROID_MT_VERSION_H"; \
- echo "#define ANDROID_MT_VERSION_H"; \
- echo "#define VERSION_MAJOR ${VERSION_MAJOR}"; \
- echo "#define VERSION_MINOR ${VERSION_MINOR}"; \
- echo "#define VERSION_PATCH ${VERSION_PATCH}"; \
- echo "#define VERSION_STRING STR(VERSION_MAJOR) \".\" STR(VERSION_MINOR) \
- \".\" STR(VERSION_PATCH)"; \
- echo "#endif"; \
- } > $${VERSION_FILE_NEW}; \
- if ! cmp -s $${VERSION_FILE} $${VERSION_FILE_NEW}; then \
- echo "android_version.h changed, updating..."; \
- mv "$${VERSION_FILE_NEW}" "$${VERSION_FILE}"; \
- else \
- rm "$${VERSION_FILE_NEW}"; \
- fi
-
-clean : clean_apk clean_assets
diff -Nru minetest-5.2.0/build/android/native/build.gradle minetest-5.3.0/build/android/native/build.gradle
--- minetest-5.2.0/build/android/native/build.gradle 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/build/android/native/build.gradle 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,59 @@
+apply plugin: 'com.android.library'
+import org.ajoberstar.grgit.Grgit
+
+android {
+ compileSdkVersion 29
+ buildToolsVersion '29.0.3'
+ ndkVersion '21.1.6352462'
+ defaultConfig {
+ minSdkVersion 16
+ targetSdkVersion 29
+ externalNativeBuild {
+ ndkBuild {
+ arguments '-j8',
+ "versionMajor=${versionMajor}",
+ "versionMinor=${versionMinor}",
+ "versionPatch=${versionPatch}",
+ "versionExtra=${versionExtra}"
+ }
+ }
+ }
+
+ externalNativeBuild {
+ ndkBuild {
+ path file('jni/Android.mk')
+ }
+ }
+
+ // supported architectures
+ splits {
+ abi {
+ enable true
+ reset()
+ include 'armeabi-v7a', 'arm64-v8a'//, 'x86'
+ }
+ }
+
+ buildTypes {
+ release {
+ externalNativeBuild {
+ ndkBuild {
+ arguments 'NDEBUG=1'
+ }
+ }
+ }
+ }
+}
+
+task cloneGitRepo() {
+ def destination = file('deps')
+ if(!destination.exists()) {
+ def grgit = Grgit.clone(
+ dir: destination,
+ uri: 'https://github.com/minetest/minetest_android_deps_binaries'
+ )
+ grgit.close()
+ }
+}
+
+preBuild.dependsOn cloneGitRepo
diff -Nru minetest-5.2.0/build/android/native/jni/Android.mk minetest-5.3.0/build/android/native/jni/Android.mk
--- minetest-5.2.0/build/android/native/jni/Android.mk 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/build/android/native/jni/Android.mk 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,219 @@
+LOCAL_PATH := $(call my-dir)/..
+
+#LOCAL_ADDRESS_SANITIZER:=true
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := Curl
+LOCAL_SRC_FILES := deps/Android/Curl/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libcurl.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := Freetype
+LOCAL_SRC_FILES := deps/Android/Freetype/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libfreetype.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := Irrlicht
+LOCAL_SRC_FILES := deps/Android/Irrlicht/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libIrrlicht.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+#include $(CLEAR_VARS)
+#LOCAL_MODULE := LevelDB
+#LOCAL_SRC_FILES := deps/Android/LevelDB/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libleveldb.a
+#include $(PREBUILT_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := LuaJIT
+LOCAL_SRC_FILES := deps/Android/LuaJIT/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libluajit.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := mbedTLS
+LOCAL_SRC_FILES := deps/Android/mbedTLS/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libmbedtls.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := mbedx509
+LOCAL_SRC_FILES := deps/Android/mbedTLS/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libmbedx509.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := mbedcrypto
+LOCAL_SRC_FILES := deps/Android/mbedTLS/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libmbedcrypto.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := OpenAL
+LOCAL_SRC_FILES := deps/Android/OpenAL-Soft/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libopenal.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+# You can use `OpenSSL and Crypto` instead `mbedTLS mbedx509 mbedcrypto`,
+#but it increase APK size on ~0.7MB
+#include $(CLEAR_VARS)
+#LOCAL_MODULE := OpenSSL
+#LOCAL_SRC_FILES := deps/Android/OpenSSL/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libssl.a
+#include $(PREBUILT_STATIC_LIBRARY)
+
+#include $(CLEAR_VARS)
+#LOCAL_MODULE := Crypto
+#LOCAL_SRC_FILES := deps/Android/OpenSSL/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libcrypto.a
+#include $(PREBUILT_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := Vorbis
+LOCAL_SRC_FILES := deps/Android/Vorbis/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libvorbis.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := Minetest
+
+LOCAL_CFLAGS += \
+ -DJSONCPP_NO_LOCALE_SUPPORT \
+ -DHAVE_TOUCHSCREENGUI \
+ -DENABLE_GLES=1 \
+ -DUSE_CURL=1 \
+ -DUSE_SOUND=1 \
+ -DUSE_FREETYPE=1 \
+ -DUSE_LEVELDB=0 \
+ -DUSE_LUAJIT=1 \
+ -DVERSION_MAJOR=${versionMajor} \
+ -DVERSION_MINOR=${versionMinor} \
+ -DVERSION_PATCH=${versionPatch} \
+ -DVERSION_EXTRA=${versionExtra} \
+ $(GPROF_DEF)
+
+ifdef NDEBUG
+ LOCAL_CFLAGS += -DNDEBUG=1
+endif
+
+ifdef GPROF
+ GPROF_DEF := -DGPROF
+ PROFILER_LIBS := android-ndk-profiler
+ LOCAL_CFLAGS += -pg
+endif
+
+LOCAL_C_INCLUDES := \
+ ../../../src \
+ ../../../src/script \
+ ../../../lib/gmp \
+ ../../../lib/jsoncpp \
+ deps/Android/Curl/include \
+ deps/Android/Freetype/include \
+ deps/Android/Irrlicht/include \
+ deps/Android/LevelDB/include \
+ deps/Android/libiconv/include \
+ deps/Android/libiconv/libcharset/include \
+ deps/Android/LuaJIT/src \
+ deps/Android/OpenAL-Soft/include \
+ deps/Android/sqlite \
+ deps/Android/Vorbis/include
+
+LOCAL_SRC_FILES := \
+ $(wildcard ../../../src/client/*.cpp) \
+ $(wildcard ../../../src/client/*/*.cpp) \
+ $(wildcard ../../../src/content/*.cpp) \
+ ../../../src/database/database.cpp \
+ ../../../src/database/database-dummy.cpp \
+ ../../../src/database/database-files.cpp \
+ ../../../src/database/database-sqlite3.cpp \
+ $(wildcard ../../../src/gui/*.cpp) \
+ $(wildcard ../../../src/irrlicht_changes/*.cpp) \
+ $(wildcard ../../../src/mapgen/*.cpp) \
+ $(wildcard ../../../src/network/*.cpp) \
+ $(wildcard ../../../src/script/*.cpp) \
+ $(wildcard ../../../src/script/*/*.cpp) \
+ $(wildcard ../../../src/server/*.cpp) \
+ $(wildcard ../../../src/threading/*.cpp) \
+ $(wildcard ../../../src/util/*.c) \
+ $(wildcard ../../../src/util/*.cpp) \
+ ../../../src/ban.cpp \
+ ../../../src/chat.cpp \
+ ../../../src/clientiface.cpp \
+ ../../../src/collision.cpp \
+ ../../../src/content_mapnode.cpp \
+ ../../../src/content_nodemeta.cpp \
+ ../../../src/convert_json.cpp \
+ ../../../src/craftdef.cpp \
+ ../../../src/debug.cpp \
+ ../../../src/defaultsettings.cpp \
+ ../../../src/emerge.cpp \
+ ../../../src/environment.cpp \
+ ../../../src/face_position_cache.cpp \
+ ../../../src/filesys.cpp \
+ ../../../src/gettext.cpp \
+ ../../../src/httpfetch.cpp \
+ ../../../src/hud.cpp \
+ ../../../src/inventory.cpp \
+ ../../../src/inventorymanager.cpp \
+ ../../../src/itemdef.cpp \
+ ../../../src/itemstackmetadata.cpp \
+ ../../../src/light.cpp \
+ ../../../src/log.cpp \
+ ../../../src/main.cpp \
+ ../../../src/map.cpp \
+ ../../../src/map_settings_manager.cpp \
+ ../../../src/mapblock.cpp \
+ ../../../src/mapnode.cpp \
+ ../../../src/mapsector.cpp \
+ ../../../src/metadata.cpp \
+ ../../../src/modchannels.cpp \
+ ../../../src/nameidmapping.cpp \
+ ../../../src/nodedef.cpp \
+ ../../../src/nodemetadata.cpp \
+ ../../../src/nodetimer.cpp \
+ ../../../src/noise.cpp \
+ ../../../src/objdef.cpp \
+ ../../../src/object_properties.cpp \
+ ../../../src/particles.cpp \
+ ../../../src/pathfinder.cpp \
+ ../../../src/player.cpp \
+ ../../../src/porting.cpp \
+ ../../../src/porting_android.cpp \
+ ../../../src/profiler.cpp \
+ ../../../src/raycast.cpp \
+ ../../../src/reflowscan.cpp \
+ ../../../src/remoteplayer.cpp \
+ ../../../src/rollback.cpp \
+ ../../../src/rollback_interface.cpp \
+ ../../../src/serialization.cpp \
+ ../../../src/server.cpp \
+ ../../../src/serverenvironment.cpp \
+ ../../../src/serverlist.cpp \
+ ../../../src/settings.cpp \
+ ../../../src/staticobject.cpp \
+ ../../../src/texture_override.cpp \
+ ../../../src/tileanimation.cpp \
+ ../../../src/tool.cpp \
+ ../../../src/translation.cpp \
+ ../../../src/version.cpp \
+ ../../../src/voxel.cpp \
+ ../../../src/voxelalgorithms.cpp
+
+# LevelDB backend is disabled
+# ../../../src/database/database-leveldb.cpp
+
+# GMP
+LOCAL_SRC_FILES += ../../../lib/gmp/mini-gmp.c
+
+# JSONCPP
+LOCAL_SRC_FILES += ../../../lib/jsoncpp/jsoncpp.cpp
+
+# iconv
+LOCAL_SRC_FILES += \
+ deps/Android/libiconv/lib/iconv.c \
+ deps/Android/libiconv/libcharset/lib/localcharset.c
+
+# SQLite3
+LOCAL_SRC_FILES += deps/Android/sqlite/sqlite3.c
+
+LOCAL_STATIC_LIBRARIES += Curl Freetype Irrlicht OpenAL mbedTLS mbedx509 mbedcrypto Vorbis LuaJIT android_native_app_glue $(PROFILER_LIBS) #LevelDB
+#OpenSSL Crypto
+
+LOCAL_LDLIBS := -lEGL -lGLESv1_CM -lGLESv2 -landroid -lOpenSLES
+
+include $(BUILD_SHARED_LIBRARY)
+
+ifdef GPROF
+$(call import-module,android-ndk-profiler)
+endif
+$(call import-module,android/native_app_glue)
diff -Nru minetest-5.2.0/build/android/native/jni/Application.mk minetest-5.3.0/build/android/native/jni/Application.mk
--- minetest-5.2.0/build/android/native/jni/Application.mk 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/build/android/native/jni/Application.mk 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,32 @@
+APP_PLATFORM := ${APP_PLATFORM}
+APP_ABI := ${TARGET_ABI}
+APP_STL := c++_shared
+NDK_TOOLCHAIN_VERSION := clang
+APP_SHORT_COMMANDS := true
+APP_MODULES := Minetest
+
+APP_CPPFLAGS := -Ofast -fvisibility=hidden -fexceptions -Wno-deprecated-declarations -Wno-extra-tokens
+
+ifeq ($(APP_ABI),armeabi-v7a)
+APP_CPPFLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -mthumb
+endif
+
+#ifeq ($(APP_ABI),x86)
+#APP_CPPFLAGS += -march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32 -funroll-loops
+#endif
+
+ifndef NDEBUG
+APP_CPPFLAGS := -g -D_DEBUG -O0 -fno-omit-frame-pointer -fexceptions
+endif
+
+APP_CFLAGS := $(APP_CPPFLAGS) -Wno-parentheses-equality #-Werror=shorten-64-to-32
+APP_CXXFLAGS := $(APP_CPPFLAGS) -frtti -std=gnu++17
+APP_LDFLAGS := -Wl,--no-warn-mismatch,--gc-sections,--icf=safe
+
+ifeq ($(APP_ABI),arm64-v8a)
+APP_LDFLAGS := -Wl,--no-warn-mismatch,--gc-sections
+endif
+
+ifndef NDEBUG
+APP_LDFLAGS :=
+endif
diff -Nru minetest-5.2.0/build/android/native/src/main/AndroidManifest.xml minetest-5.3.0/build/android/native/src/main/AndroidManifest.xml
--- minetest-5.2.0/build/android/native/src/main/AndroidManifest.xml 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/build/android/native/src/main/AndroidManifest.xml 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1 @@
+
diff -Nru minetest-5.2.0/build/android/patches/irrlicht-back_button.patch minetest-5.3.0/build/android/patches/irrlicht-back_button.patch
--- minetest-5.2.0/build/android/patches/irrlicht-back_button.patch 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/build/android/patches/irrlicht-back_button.patch 1970-01-01 00:00:00.000000000 +0000
@@ -1,20 +0,0 @@
---- irrlicht/source/Irrlicht/Android/CIrrDeviceAndroid.cpp.orig 2015-08-29 15:43:09.000000000 +0300
-+++ irrlicht/source/Irrlicht/Android/CIrrDeviceAndroid.cpp 2016-05-13 21:36:22.880388505 +0300
-@@ -486,7 +486,7 @@
- event.KeyInput.Char = 0;
- }
-
-- device->postEventFromUser(event);
-+ status = device->postEventFromUser(event);
- }
- break;
- default:
-@@ -543,7 +543,7 @@
- KeyMap[1] = KEY_LBUTTON; // AKEYCODE_SOFT_LEFT
- KeyMap[2] = KEY_RBUTTON; // AKEYCODE_SOFT_RIGHT
- KeyMap[3] = KEY_HOME; // AKEYCODE_HOME
-- KeyMap[4] = KEY_BACK; // AKEYCODE_BACK
-+ KeyMap[4] = KEY_CANCEL; // AKEYCODE_BACK
- KeyMap[5] = KEY_UNKNOWN; // AKEYCODE_CALL
- KeyMap[6] = KEY_UNKNOWN; // AKEYCODE_ENDCALL
- KeyMap[7] = KEY_KEY_0; // AKEYCODE_0
diff -Nru minetest-5.2.0/build/android/patches/irrlicht-native_activity.patch minetest-5.3.0/build/android/patches/irrlicht-native_activity.patch
--- minetest-5.2.0/build/android/patches/irrlicht-native_activity.patch 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/build/android/patches/irrlicht-native_activity.patch 1970-01-01 00:00:00.000000000 +0000
@@ -1,13 +0,0 @@
---- irrlicht/source/Irrlicht/CEGLManager.cpp.orig 2018-09-11 18:19:51.453403631 +0300
-+++ irrlicht/source/Irrlicht/CEGLManager.cpp 2018-09-11 18:36:24.603471869 +0300
-@@ -9,6 +9,10 @@
- #include "irrString.h"
- #include "os.h"
-
-+#if defined(_IRR_COMPILE_WITH_ANDROID_DEVICE_)
-+#include
-+#endif
-+
- namespace irr
- {
- namespace video
diff -Nru minetest-5.2.0/build/android/patches/irrlicht-texturehack.patch minetest-5.3.0/build/android/patches/irrlicht-texturehack.patch
--- minetest-5.2.0/build/android/patches/irrlicht-texturehack.patch 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/build/android/patches/irrlicht-texturehack.patch 1970-01-01 00:00:00.000000000 +0000
@@ -1,240 +0,0 @@
---- irrlicht/source/Irrlicht/COGLESTexture.cpp.orig 2014-06-22 17:01:13.266568869 +0200
-+++ irrlicht/source/Irrlicht/COGLESTexture.cpp 2014-06-22 17:03:59.298572810 +0200
-@@ -366,112 +366,140 @@
- void(*convert)(const void*, s32, void*) = 0;
- getFormatParameters(ColorFormat, InternalFormat, filtering, PixelFormat, PixelType, convert);
-
-- // make sure we don't change the internal format of existing images
-- if (!newTexture)
-- InternalFormat = oldInternalFormat;
--
-- Driver->setActiveTexture(0, this);
--
-- if (Driver->testGLError())
-- os::Printer::log("Could not bind Texture", ELL_ERROR);
--
-- // mipmap handling for main texture
-- if (!level && newTexture)
-- {
-- // auto generate if possible and no mipmap data is given
-- if (!IsCompressed && HasMipMaps && !mipmapData && Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE))
-- {
-- if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED))
-- glHint(GL_GENERATE_MIPMAP_HINT, GL_FASTEST);
-- else if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_QUALITY))
-- glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
-- else
-- glHint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE);
-+ bool retry = false;
-+
-+ do {
-+ if (retry) {
-+ InternalFormat = GL_RGBA;
-+ PixelFormat = GL_RGBA;
-+ convert = CColorConverter::convert_A8R8G8B8toA8B8G8R8;
-+ }
-+ // make sure we don't change the internal format of existing images
-+ if (!newTexture)
-+ InternalFormat = oldInternalFormat;
-
-- glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
-- AutomaticMipmapUpdate=true;
-- }
-+ Driver->setActiveTexture(0, this);
-
-- // enable bilinear filter without mipmaps
-- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
-- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
-- }
-+ if (Driver->testGLError())
-+ os::Printer::log("Could not bind Texture", ELL_ERROR);
-
-- // now get image data and upload to GPU
-+ // mipmap handling for main texture
-+ if (!level && newTexture)
-+ {
-+ // auto generate if possible and no mipmap data is given
-+ if (!IsCompressed && HasMipMaps && !mipmapData && Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE))
-+ {
-+ if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED))
-+ glHint(GL_GENERATE_MIPMAP_HINT, GL_FASTEST);
-+ else if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_QUALITY))
-+ glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
-+ else
-+ glHint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE);
-+
-+ glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
-+ AutomaticMipmapUpdate=true;
-+ }
-+
-+ // enable bilinear filter without mipmaps
-+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
-+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
-+ }
-
-- u32 compressedImageSize = IImage::getCompressedImageSize(ColorFormat, image->getDimension().Width, image->getDimension().Height);
-+ // now get image data and upload to GPU
-
-- void* source = image->lock();
-+ u32 compressedImageSize = IImage::getCompressedImageSize(ColorFormat, image->getDimension().Width, image->getDimension().Height);
-
-- IImage* tmpImage = 0;
-+ void* source = image->lock();
-
-- if (convert)
-- {
-- tmpImage = new CImage(image->getColorFormat(), image->getDimension());
-- void* dest = tmpImage->lock();
-- convert(source, image->getDimension().getArea(), dest);
-- image->unlock();
-- source = dest;
-- }
-+ IImage* tmpImage = 0;
-
-- if (newTexture)
-- {
-- if (IsCompressed)
-+ if (convert)
- {
-- glCompressedTexImage2D(GL_TEXTURE_2D, 0, InternalFormat, image->getDimension().Width,
-- image->getDimension().Height, 0, compressedImageSize, source);
-+ tmpImage = new CImage(image->getColorFormat(), image->getDimension());
-+ void* dest = tmpImage->lock();
-+ convert(source, image->getDimension().getArea(), dest);
-+ image->unlock();
-+ source = dest;
- }
-- else
-- glTexImage2D(GL_TEXTURE_2D, level, InternalFormat, image->getDimension().Width,
-- image->getDimension().Height, 0, PixelFormat, PixelType, source);
-- }
-- else
-- {
-- if (IsCompressed)
-+
-+ if (newTexture)
- {
-- glCompressedTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->getDimension().Width,
-- image->getDimension().Height, PixelFormat, compressedImageSize, source);
-+ if (IsCompressed)
-+ {
-+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, InternalFormat, image->getDimension().Width,
-+ image->getDimension().Height, 0, compressedImageSize, source);
-+ }
-+ else
-+ glTexImage2D(GL_TEXTURE_2D, level, InternalFormat, image->getDimension().Width,
-+ image->getDimension().Height, 0, PixelFormat, PixelType, source);
- }
- else
-- glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->getDimension().Width,
-- image->getDimension().Height, PixelFormat, PixelType, source);
-- }
--
-- if (convert)
-- {
-- tmpImage->unlock();
-- tmpImage->drop();
-- }
-- else
-- image->unlock();
--
-- if (!level && newTexture)
-- {
-- if (IsCompressed && !mipmapData)
- {
-- if (image->hasMipMaps())
-- mipmapData = static_cast(image->lock())+compressedImageSize;
-+ if (IsCompressed)
-+ {
-+ glCompressedTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->getDimension().Width,
-+ image->getDimension().Height, PixelFormat, compressedImageSize, source);
-+ }
- else
-- HasMipMaps = false;
-+ glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->getDimension().Width,
-+ image->getDimension().Height, PixelFormat, PixelType, source);
- }
-
-- regenerateMipMapLevels(mipmapData);
--
-- if (HasMipMaps) // might have changed in regenerateMipMapLevels
-+ if (convert)
- {
-- // enable bilinear mipmap filter
-- GLint filteringMipMaps = GL_LINEAR_MIPMAP_NEAREST;
--
-- if (filtering != GL_LINEAR)
-- filteringMipMaps = GL_NEAREST_MIPMAP_NEAREST;
-+ tmpImage->unlock();
-+ tmpImage->drop();
-+ }
-+ else
-+ image->unlock();
-+
-+ if (glGetError() != GL_NO_ERROR) {
-+ static bool warned = false;
-+ if ((!retry) && (ColorFormat == ECF_A8R8G8B8)) {
-+
-+ if (!warned) {
-+ os::Printer::log("Your driver claims to support GL_BGRA but fails on trying to upload a texture, converting to GL_RGBA and trying again", ELL_ERROR);
-+ warned = true;
-+ }
-+ }
-+ else if (retry) {
-+ os::Printer::log("Neither uploading texture as GL_BGRA nor, converted one using GL_RGBA succeeded", ELL_ERROR);
-+ }
-+ retry = !retry;
-+ continue;
-+ } else {
-+ retry = false;
-+ }
-
-- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filteringMipMaps);
-- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
-+ if (!level && newTexture)
-+ {
-+ if (IsCompressed && !mipmapData)
-+ {
-+ if (image->hasMipMaps())
-+ mipmapData = static_cast(image->lock())+compressedImageSize;
-+ else
-+ HasMipMaps = false;
-+ }
-+
-+ regenerateMipMapLevels(mipmapData);
-+
-+ if (HasMipMaps) // might have changed in regenerateMipMapLevels
-+ {
-+ // enable bilinear mipmap filter
-+ GLint filteringMipMaps = GL_LINEAR_MIPMAP_NEAREST;
-+
-+ if (filtering != GL_LINEAR)
-+ filteringMipMaps = GL_NEAREST_MIPMAP_NEAREST;
-+
-+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filteringMipMaps);
-+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
-+ }
- }
-- }
-
-- if (Driver->testGLError())
-- os::Printer::log("Could not glTexImage2D", ELL_ERROR);
-+ if (Driver->testGLError())
-+ os::Printer::log("Could not glTexImage2D", ELL_ERROR);
-+ }
-+ while(retry);
- }
-
-
---- irrlicht/source/Irrlicht/COGLESTexture.cpp.orig 2014-06-25 00:28:50.820501856 +0200
-+++ irrlicht/source/Irrlicht/COGLESTexture.cpp 2014-06-25 00:08:37.712544692 +0200
-@@ -422,6 +422,9 @@
- source = dest;
- }
-
-+ //clear old error
-+ glGetError();
-+
- if (newTexture)
- {
- if (IsCompressed)
diff -Nru minetest-5.2.0/build/android/patches/irrlicht-touchcount.patch minetest-5.3.0/build/android/patches/irrlicht-touchcount.patch
--- minetest-5.2.0/build/android/patches/irrlicht-touchcount.patch 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/build/android/patches/irrlicht-touchcount.patch 1970-01-01 00:00:00.000000000 +0000
@@ -1,30 +0,0 @@
---- irrlicht.orig/include/IEventReceiver.h 2014-06-03 19:43:50.433713133 +0200
-+++ irrlicht/include/IEventReceiver.h 2014-06-03 19:44:36.993711489 +0200
-@@ -375,6 +375,9 @@
- // Y position of simple touch.
- s32 Y;
-
-+ // number of current touches
-+ s32 touchedCount;
-+
- //! Type of touch event.
- ETOUCH_INPUT_EVENT Event;
- };
---- irrlicht.orig/source/Irrlicht/Android/CIrrDeviceAndroid.cpp 2014-06-03 19:43:50.505713130 +0200
-+++ irrlicht/source/Irrlicht/Android/CIrrDeviceAndroid.cpp 2014-06-03 19:45:37.265709359 +0200
-@@ -315,6 +315,7 @@
- event.TouchInput.ID = AMotionEvent_getPointerId(androidEvent, i);
- event.TouchInput.X = AMotionEvent_getX(androidEvent, i);
- event.TouchInput.Y = AMotionEvent_getY(androidEvent, i);
-+ event.TouchInput.touchedCount = AMotionEvent_getPointerCount(androidEvent);
-
- device->postEventFromUser(event);
- }
-@@ -326,6 +327,7 @@
- event.TouchInput.ID = AMotionEvent_getPointerId(androidEvent, pointerIndex);
- event.TouchInput.X = AMotionEvent_getX(androidEvent, pointerIndex);
- event.TouchInput.Y = AMotionEvent_getY(androidEvent, pointerIndex);
-+ event.TouchInput.touchedCount = AMotionEvent_getPointerCount(androidEvent);
-
- device->postEventFromUser(event);
- }
diff -Nru minetest-5.2.0/build/android/patches/libvorbis-libogg-fpu.patch minetest-5.3.0/build/android/patches/libvorbis-libogg-fpu.patch
--- minetest-5.2.0/build/android/patches/libvorbis-libogg-fpu.patch 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/build/android/patches/libvorbis-libogg-fpu.patch 1970-01-01 00:00:00.000000000 +0000
@@ -1,37 +0,0 @@
---- libvorbis-libogg-android/jni/libvorbis-jni/Android.mk.orig 2014-06-17 19:22:50.621559073 +0200
-+++ libvorbis-libogg-android/jni/libvorbis-jni/Android.mk 2014-06-17 19:38:20.641581140 +0200
-@@ -4,9 +4,6 @@
-
- LOCAL_MODULE := vorbis-jni
- LOCAL_CFLAGS += -I$(LOCAL_PATH)/../include -fsigned-char
--ifeq ($(TARGET_ARCH),arm)
-- LOCAL_CFLAGS += -march=armv6 -marm -mfloat-abi=softfp -mfpu=vfp
--endif
-
- LOCAL_SHARED_LIBRARIES := libogg libvorbis
-
---- libvorbis-libogg-android/jni/libvorbis/Android.mk.orig 2014-06-17 19:22:39.077558797 +0200
-+++ libvorbis-libogg-android/jni/libvorbis/Android.mk 2014-06-17 19:38:52.121581887 +0200
-@@ -4,9 +4,6 @@
-
- LOCAL_MODULE := libvorbis
- LOCAL_CFLAGS += -I$(LOCAL_PATH)/../include -ffast-math -fsigned-char
--ifeq ($(TARGET_ARCH),arm)
-- LOCAL_CFLAGS += -march=armv6 -marm -mfloat-abi=softfp -mfpu=vfp
--endif
- LOCAL_SHARED_LIBRARIES := libogg
-
- LOCAL_SRC_FILES := \
---- libvorbis-libogg-android/jni/libogg/Android.mk.orig 2014-06-17 19:22:33.965558675 +0200
-+++ libvorbis-libogg-android/jni/libogg/Android.mk 2014-06-17 19:38:25.337581252 +0200
-@@ -4,10 +4,6 @@
-
- LOCAL_MODULE := libogg
- LOCAL_CFLAGS += -I$(LOCAL_PATH)/../include -ffast-math -fsigned-char
--ifeq ($(TARGET_ARCH),arm)
-- LOCAL_CFLAGS += -march=armv6 -marm -mfloat-abi=softfp -mfpu=vfp
--endif
--
-
- LOCAL_SRC_FILES := \
- bitwise.c \
diff -Nru minetest-5.2.0/build/android/patches/openssl_arch.patch minetest-5.3.0/build/android/patches/openssl_arch.patch
--- minetest-5.2.0/build/android/patches/openssl_arch.patch 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/build/android/patches/openssl_arch.patch 1970-01-01 00:00:00.000000000 +0000
@@ -1,13 +0,0 @@
---- openssl-1.0.2e.orig/Configure 2015-12-03 15:04:23.000000000 +0100
-+++ openssl-1.0.2e/Configure 2015-12-14 21:01:40.351265968 +0100
-@@ -464,8 +464,10 @@
- # Android: linux-* but without pointers to headers and libs.
- "android","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
- "android-x86","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:".eval{my $asm=${x86_elf_asm};$asm=~s/:elf/:android/;$asm}.":dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-+"android-arm","gcc:-march=armv4 -mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${armv4_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
- "android-armv7","gcc:-march=armv7-a -mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${armv4_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
- "android-mips","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${mips32_asm}:o32:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-+"android-mips32","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${mips32_asm}:o32:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-
- #### *BSD [do see comment about ${BSDthreads} above!]
- "BSD-generic32","gcc:-O3 -fomit-frame-pointer -Wall::${BSDthreads}:::BN_LLONG RC2_CHAR RC4_INDEX DES_INT DES_UNROLL:${no_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
diff -Nru minetest-5.2.0/build/android/settings.gradle minetest-5.3.0/build/android/settings.gradle
--- minetest-5.2.0/build/android/settings.gradle 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/build/android/settings.gradle 2020-07-09 21:13:20.000000000 +0000
@@ -1 +1,2 @@
rootProject.name = "Minetest"
+include ':app', ':native'
diff -Nru minetest-5.2.0/build/android/src/main/AndroidManifest.xml minetest-5.3.0/build/android/src/main/AndroidManifest.xml
--- minetest-5.2.0/build/android/src/main/AndroidManifest.xml 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/build/android/src/main/AndroidManifest.xml 1970-01-01 00:00:00.000000000 +0000
@@ -1,60 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff -Nru minetest-5.2.0/build/android/src/main/java/net.minetest.minetest/MainActivity.java minetest-5.3.0/build/android/src/main/java/net.minetest.minetest/MainActivity.java
--- minetest-5.2.0/build/android/src/main/java/net.minetest.minetest/MainActivity.java 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/build/android/src/main/java/net.minetest.minetest/MainActivity.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,77 +0,0 @@
-package net.minetest.minetest;
-
-import android.Manifest;
-import android.app.Activity;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.os.Build;
-import android.os.Bundle;
-import android.widget.Toast;
-
-import androidx.annotation.NonNull;
-import androidx.core.app.ActivityCompat;
-import androidx.core.content.ContextCompat;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-public class MainActivity extends Activity {
- private final static int PERMISSIONS = 1;
- private static final String[] REQUIRED_SDK_PERMISSIONS = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE};
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- checkPermission();
- } else {
- next();
- }
- }
-
- private void checkPermission() {
- final List missingPermissions = new ArrayList<>();
- // check required permission
- for (final String permission : REQUIRED_SDK_PERMISSIONS) {
- final int result = ContextCompat.checkSelfPermission(this, permission);
- if (result != PackageManager.PERMISSION_GRANTED) {
- missingPermissions.add(permission);
- }
- }
- if (!missingPermissions.isEmpty()) {
- // request permission
- final String[] permissions = missingPermissions
- .toArray(new String[0]);
- ActivityCompat.requestPermissions(this, permissions, PERMISSIONS);
- } else {
- final int[] grantResults = new int[REQUIRED_SDK_PERMISSIONS.length];
- Arrays.fill(grantResults, PackageManager.PERMISSION_GRANTED);
- onRequestPermissionsResult(PERMISSIONS, REQUIRED_SDK_PERMISSIONS,
- grantResults);
- }
- }
-
- @Override
- public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
- @NonNull int[] grantResults) {
- if (requestCode == PERMISSIONS) {
- for (int index = 0; index < permissions.length; index++) {
- if (grantResults[index] != PackageManager.PERMISSION_GRANTED) {
- // permission not granted - toast and exit
- Toast.makeText(this, R.string.not_granted, Toast.LENGTH_LONG).show();
- finish();
- return;
- }
- }
- // permission were granted - run
- next();
- }
- }
-
- private void next() {
- Intent intent = new Intent(this, MtNativeActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- startActivity(intent);
- }
-}
diff -Nru minetest-5.2.0/build/android/src/main/java/net.minetest.minetest/MinetestAssetCopy.java minetest-5.3.0/build/android/src/main/java/net.minetest.minetest/MinetestAssetCopy.java
--- minetest-5.2.0/build/android/src/main/java/net.minetest.minetest/MinetestAssetCopy.java 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/build/android/src/main/java/net.minetest.minetest/MinetestAssetCopy.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,371 +0,0 @@
-package net.minetest.minetest;
-
-import android.annotation.SuppressLint;
-import android.app.Activity;
-import android.content.res.AssetFileDescriptor;
-import android.os.AsyncTask;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Environment;
-import android.util.Log;
-import android.view.Display;
-import android.view.View;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.util.Vector;
-
-public class MinetestAssetCopy extends Activity {
- private ProgressBar m_ProgressBar;
- private TextView m_Filename;
- private copyAssetTask m_AssetCopy;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.assetcopy);
- m_ProgressBar = findViewById(R.id.progressBar1);
- m_Filename = findViewById(R.id.textView1);
- Display display = getWindowManager().getDefaultDisplay();
- m_ProgressBar.getLayoutParams().width = (int) (display.getWidth() * 0.8);
- m_ProgressBar.invalidate();
-
- /* check if there's already a copy in progress and reuse in case it is*/
- MinetestAssetCopy prevActivity =
- (MinetestAssetCopy) getLastNonConfigurationInstance();
- if (prevActivity != null) {
- m_AssetCopy = prevActivity.m_AssetCopy;
- } else {
- m_AssetCopy = new copyAssetTask();
- m_AssetCopy.execute();
- }
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- makeFullScreen();
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- if (m_AssetCopy != null) {
- m_AssetCopy.cancel(true);
- }
- }
-
- private void makeFullScreen() {
- if (Build.VERSION.SDK_INT >= 19)
- this.getWindow().getDecorView().setSystemUiVisibility(
- View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
- }
-
- @Override
- public void onWindowFocusChanged(boolean hasFocus) {
- super.onWindowFocusChanged(hasFocus);
- if (hasFocus)
- makeFullScreen();
- }
-
- /* preserve asset copy background task to prevent restart of copying */
- /* this way of doing it is not recommended for latest android version */
- /* but the recommended way isn't available on android 2.x */
- public Object onRetainNonConfigurationInstance() {
- return this;
- }
-
- @SuppressLint("StaticFieldLeak")
- private class copyAssetTask extends AsyncTask {
- boolean m_copy_started = false;
- String m_Foldername = "media";
- Vector m_foldernames;
- Vector m_filenames;
- Vector m_tocopy;
- Vector m_asset_size_unknown;
-
- private long getFullSize(String filename) {
- long size = 0;
- try {
- InputStream src = getAssets().open(filename);
- byte[] buf = new byte[4096];
-
- int len;
- while ((len = src.read(buf)) > 0) {
- size += len;
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- return size;
- }
-
- @Override
- protected String doInBackground(String... files) {
- m_foldernames = new Vector<>();
- m_filenames = new Vector<>();
- m_tocopy = new Vector<>();
- m_asset_size_unknown = new Vector<>();
- String baseDir =
- Environment.getExternalStorageDirectory().getAbsolutePath()
- + "/";
-
-
- // prepare temp folder
- File TempFolder = new File(baseDir + "Minetest/tmp/");
-
- if (!TempFolder.exists()) {
- TempFolder.mkdir();
- } else {
- File[] todel = TempFolder.listFiles();
-
- for (File file : todel) {
- Log.v("MinetestAssetCopy", "deleting: " + file.getAbsolutePath());
- file.delete();
- }
- }
-
- // add a .nomedia file
- try {
- OutputStream dst = new FileOutputStream(baseDir + "Minetest/.nomedia");
- dst.close();
- } catch (IOException e) {
- Log.e("MinetestAssetCopy", "Failed to create .nomedia file");
- e.printStackTrace();
- }
-
-
- // build lists from prepared data
- BuildFolderList();
- BuildFileList();
-
- // scan filelist
- ProcessFileList();
-
- // doing work
- m_copy_started = true;
- m_ProgressBar.setMax(m_tocopy.size());
-
- for (int i = 0; i < m_tocopy.size(); i++) {
- try {
- String filename = m_tocopy.get(i);
- publishProgress(i);
-
- boolean asset_size_unknown = false;
- long filesize = -1;
-
- if (m_asset_size_unknown.contains(filename)) {
- File testme = new File(baseDir + "/" + filename);
-
- if (testme.exists())
- filesize = testme.length();
-
- asset_size_unknown = true;
- }
-
- InputStream src;
- try {
- src = getAssets().open(filename);
- } catch (IOException e) {
- Log.e("MinetestAssetCopy", "Copying file: " + filename + " FAILED (not in assets)");
- e.printStackTrace();
- continue;
- }
-
- // Transfer bytes from in to out
- byte[] buf = new byte[1024];
- int len = src.read(buf, 0, 1024);
-
- /* following handling is crazy but we need to deal with */
- /* compressed assets.Flash chips limited livetime due to */
- /* write operations, we can't allow large files to destroy */
- /* users flash. */
- if (asset_size_unknown) {
- if ((len > 0) && (len < buf.length) && (len == filesize)) {
- src.close();
- continue;
- }
-
- if (len == buf.length) {
- src.close();
- long size = getFullSize(filename);
- if (size == filesize) {
- continue;
- }
- src = getAssets().open(filename);
- len = src.read(buf, 0, 1024);
- }
- }
- if (len > 0) {
- int total_filesize = 0;
- OutputStream dst;
- try {
- dst = new FileOutputStream(baseDir + "/" + filename);
- } catch (IOException e) {
- Log.e("MinetestAssetCopy", "Copying file: " + baseDir +
- "/" + filename + " FAILED (couldn't open output file)");
- e.printStackTrace();
- src.close();
- continue;
- }
- dst.write(buf, 0, len);
- total_filesize += len;
-
- while ((len = src.read(buf)) > 0) {
- dst.write(buf, 0, len);
- total_filesize += len;
- }
-
- dst.close();
- Log.v("MinetestAssetCopy", "Copied file: " +
- m_tocopy.get(i) + " (" + total_filesize +
- " bytes)");
- } else if (len < 0) {
- Log.e("MinetestAssetCopy", "Copying file: " +
- m_tocopy.get(i) + " failed, size < 0");
- }
- src.close();
- } catch (IOException e) {
- Log.e("MinetestAssetCopy", "Copying file: " +
- m_tocopy.get(i) + " failed");
- e.printStackTrace();
- }
- }
- return "";
- }
-
- /**
- * update progress bar
- */
- protected void onProgressUpdate(Integer... progress) {
-
- if (m_copy_started) {
- String todisplay = m_tocopy.get(progress[0]);
- m_ProgressBar.setProgress(progress[0]);
- m_Filename.setText(todisplay);
- } else {
- String todisplay = m_Foldername;
- String full_text = "scanning " + todisplay + " ...";
- m_Filename.setText(full_text);
- }
- }
-
- /**
- * check all files and folders in filelist
- */
- void ProcessFileList() {
- String FlashBaseDir =
- Environment.getExternalStorageDirectory().getAbsolutePath();
-
- for (String current_path : m_filenames) {
- String FlashPath = FlashBaseDir + "/" + current_path;
-
- if (isAssetFolder(current_path)) {
- /* store information and update gui */
- m_Foldername = current_path;
- publishProgress(0);
-
- /* open file in order to check if it's a folder */
- File current_folder = new File(FlashPath);
- if (!current_folder.exists()) {
- if (!current_folder.mkdirs()) {
- Log.e("MinetestAssetCopy", "\t failed create folder: " +
- FlashPath);
- } else {
- Log.v("MinetestAssetCopy", "\t created folder: " +
- FlashPath);
- }
- }
-
- continue;
- }
-
- /* if it's not a folder it's most likely a file */
- boolean refresh = true;
-
- File testme = new File(FlashPath);
-
- long asset_filesize = -1;
- long stored_filesize;
-
- if (testme.exists()) {
- try {
- AssetFileDescriptor fd = getAssets().openFd(current_path);
- asset_filesize = fd.getLength();
- fd.close();
- } catch (IOException e) {
- m_asset_size_unknown.add(current_path);
- Log.e("MinetestAssetCopy", "Failed to open asset file \"" +
- FlashPath + "\" for size check");
- }
-
- stored_filesize = testme.length();
-
- if (asset_filesize == stored_filesize)
- refresh = false;
-
- }
-
- if (refresh)
- m_tocopy.add(current_path);
- }
- }
-
- /**
- * read list of folders prepared on package build
- */
- void BuildFolderList() {
- try {
- InputStream is = getAssets().open("index.txt");
- BufferedReader reader = new BufferedReader(new InputStreamReader(is));
-
- String line = reader.readLine();
- while (line != null) {
- m_foldernames.add(line);
- line = reader.readLine();
- }
- is.close();
- } catch (IOException e1) {
- Log.e("MinetestAssetCopy", "Error on processing index.txt");
- e1.printStackTrace();
- }
- }
-
- /**
- * read list of asset files prepared on package build
- */
- void BuildFileList() {
- long entrycount = 0;
- try {
- InputStream is = getAssets().open("filelist.txt");
- BufferedReader reader = new BufferedReader(new InputStreamReader(is));
-
- String line = reader.readLine();
- while (line != null) {
- m_filenames.add(line);
- line = reader.readLine();
- entrycount++;
- }
- is.close();
- } catch (IOException e1) {
- Log.e("MinetestAssetCopy", "Error on processing filelist.txt");
- e1.printStackTrace();
- }
- }
-
- protected void onPostExecute(String result) {
- finish();
- }
-
- boolean isAssetFolder(String path) {
- return m_foldernames.contains(path);
- }
- }
-}
diff -Nru minetest-5.2.0/build/android/src/main/java/net.minetest.minetest/MinetestTextEntry.java minetest-5.3.0/build/android/src/main/java/net.minetest.minetest/MinetestTextEntry.java
--- minetest-5.2.0/build/android/src/main/java/net.minetest.minetest/MinetestTextEntry.java 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/build/android/src/main/java/net.minetest.minetest/MinetestTextEntry.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,87 +0,0 @@
-package net.minetest.minetest;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.os.Bundle;
-import android.text.InputType;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.View.OnKeyListener;
-import android.widget.EditText;
-
-public class MinetestTextEntry extends Activity {
- private final int MultiLineTextInput = 1;
- private final int SingleLineTextInput = 2;
- private final int SingleLinePasswordInput = 3;
- private AlertDialog mTextInputDialog;
- private EditText mTextInputWidget;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- Bundle b = getIntent().getExtras();
- String acceptButton = b.getString("EnterButton");
- String hint = b.getString("hint");
- String current = b.getString("current");
- int editType = b.getInt("editType");
-
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- mTextInputWidget = new EditText(this);
- mTextInputWidget.setHint(hint);
- mTextInputWidget.setText(current);
- mTextInputWidget.setMinWidth(300);
- if (editType == SingleLinePasswordInput) {
- mTextInputWidget.setInputType(InputType.TYPE_CLASS_TEXT |
- InputType.TYPE_TEXT_VARIATION_PASSWORD);
- } else {
- mTextInputWidget.setInputType(InputType.TYPE_CLASS_TEXT);
- }
-
- builder.setView(mTextInputWidget);
-
- if (editType == MultiLineTextInput) {
- builder.setPositiveButton(acceptButton, new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int whichButton) {
- pushResult(mTextInputWidget.getText().toString());
- }
- });
- }
-
- builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
- public void onCancel(DialogInterface dialog) {
- cancelDialog();
- }
- });
-
- mTextInputWidget.setOnKeyListener(new OnKeyListener() {
- @Override
- public boolean onKey(View view, int KeyCode, KeyEvent event) {
- if (KeyCode == KeyEvent.KEYCODE_ENTER) {
-
- pushResult(mTextInputWidget.getText().toString());
- return true;
- }
- return false;
- }
- });
-
- mTextInputDialog = builder.create();
- mTextInputDialog.show();
- }
-
- private void pushResult(String text) {
- Intent resultData = new Intent();
- resultData.putExtra("text", text);
- setResult(Activity.RESULT_OK, resultData);
- mTextInputDialog.dismiss();
- finish();
- }
-
- private void cancelDialog() {
- setResult(Activity.RESULT_CANCELED);
- mTextInputDialog.dismiss();
- finish();
- }
-}
diff -Nru minetest-5.2.0/build/android/src/main/java/net.minetest.minetest/MtNativeActivity.java minetest-5.3.0/build/android/src/main/java/net.minetest.minetest/MtNativeActivity.java
--- minetest-5.2.0/build/android/src/main/java/net.minetest.minetest/MtNativeActivity.java 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/build/android/src/main/java/net.minetest.minetest/MtNativeActivity.java 1970-01-01 00:00:00.000000000 +0000
@@ -1,108 +0,0 @@
-package net.minetest.minetest;
-
-import android.app.NativeActivity;
-import android.content.Intent;
-import android.os.Build;
-import android.os.Bundle;
-import android.view.View;
-import android.view.WindowManager;
-
-public class MtNativeActivity extends NativeActivity {
-
- static {
- System.loadLibrary("c++_shared");
- System.loadLibrary("openal");
- System.loadLibrary("ogg");
- System.loadLibrary("vorbis");
- System.loadLibrary("iconv");
- System.loadLibrary("minetest");
- }
-
- private int m_MessagReturnCode;
- private String m_MessageReturnValue;
-
- public static native void putMessageBoxResult(String text);
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
- m_MessagReturnCode = -1;
- m_MessageReturnValue = "";
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- makeFullScreen();
- }
-
- private void makeFullScreen() {
- if (Build.VERSION.SDK_INT >= 19)
- this.getWindow().getDecorView().setSystemUiVisibility(
- View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
- }
-
- @Override
- public void onWindowFocusChanged(boolean hasFocus) {
- super.onWindowFocusChanged(hasFocus);
- if (hasFocus)
- makeFullScreen();
- }
-
- public void copyAssets() {
- Intent intent = new Intent(this, MinetestAssetCopy.class);
- startActivity(intent);
- }
-
- public void showDialog(String acceptButton, String hint, String current,
- int editType) {
-
- Intent intent = new Intent(this, MinetestTextEntry.class);
- Bundle params = new Bundle();
- params.putString("acceptButton", acceptButton);
- params.putString("hint", hint);
- params.putString("current", current);
- params.putInt("editType", editType);
- intent.putExtras(params);
- startActivityForResult(intent, 101);
- m_MessageReturnValue = "";
- m_MessagReturnCode = -1;
- }
-
- /* ugly code to workaround putMessageBoxResult not beeing found */
- public int getDialogState() {
- return m_MessagReturnCode;
- }
-
- public String getDialogValue() {
- m_MessagReturnCode = -1;
- return m_MessageReturnValue;
- }
-
- public float getDensity() {
- return getResources().getDisplayMetrics().density;
- }
-
- public int getDisplayWidth() {
- return getResources().getDisplayMetrics().widthPixels;
- }
-
- public int getDisplayHeight() {
- return getResources().getDisplayMetrics().heightPixels;
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode,
- Intent data) {
- if (requestCode == 101) {
- if (resultCode == RESULT_OK) {
- String text = data.getStringExtra("text");
- m_MessagReturnCode = 0;
- m_MessageReturnValue = text;
- } else {
- m_MessagReturnCode = 1;
- }
- }
- }
-}
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/build/android/src/main/res/drawable/background.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/build/android/src/main/res/drawable/background.png differ
diff -Nru minetest-5.2.0/build/android/src/main/res/drawable/bg.xml minetest-5.3.0/build/android/src/main/res/drawable/bg.xml
--- minetest-5.2.0/build/android/src/main/res/drawable/bg.xml 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/build/android/src/main/res/drawable/bg.xml 1970-01-01 00:00:00.000000000 +0000
@@ -1,4 +0,0 @@
-
-
\ No newline at end of file
diff -Nru minetest-5.2.0/build/android/src/main/res/layout/assetcopy.xml minetest-5.3.0/build/android/src/main/res/layout/assetcopy.xml
--- minetest-5.2.0/build/android/src/main/res/layout/assetcopy.xml 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/build/android/src/main/res/layout/assetcopy.xml 1970-01-01 00:00:00.000000000 +0000
@@ -1,24 +0,0 @@
-
-
-
-
-
-
-
-
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/build/android/src/main/res/mipmap/ic_launcher.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/build/android/src/main/res/mipmap/ic_launcher.png differ
diff -Nru minetest-5.2.0/build/android/src/main/res/values/strings.xml minetest-5.3.0/build/android/src/main/res/values/strings.xml
--- minetest-5.2.0/build/android/src/main/res/values/strings.xml 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/build/android/src/main/res/values/strings.xml 1970-01-01 00:00:00.000000000 +0000
@@ -1,5 +0,0 @@
-
-
- Preparing media…
- Required permission wasn\'t granted, Minetest can\'t run without it
-
\ No newline at end of file
diff -Nru minetest-5.2.0/build/android/src/main/res/values/styles.xml minetest-5.3.0/build/android/src/main/res/values/styles.xml
--- minetest-5.2.0/build/android/src/main/res/values/styles.xml 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/build/android/src/main/res/values/styles.xml 1970-01-01 00:00:00.000000000 +0000
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
-
diff -Nru minetest-5.2.0/build/android/src/main/res/values-v21/styles.xml minetest-5.3.0/build/android/src/main/res/values-v21/styles.xml
--- minetest-5.2.0/build/android/src/main/res/values-v21/styles.xml 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/build/android/src/main/res/values-v21/styles.xml 1970-01-01 00:00:00.000000000 +0000
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
-
diff -Nru minetest-5.2.0/builtin/common/async_event.lua minetest-5.3.0/builtin/common/async_event.lua
--- minetest-5.2.0/builtin/common/async_event.lua 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/builtin/common/async_event.lua 1970-01-01 00:00:00.000000000 +0000
@@ -1,40 +0,0 @@
-
-core.async_jobs = {}
-
-local function handle_job(jobid, serialized_retval)
- local retval = core.deserialize(serialized_retval)
- assert(type(core.async_jobs[jobid]) == "function")
- core.async_jobs[jobid](retval)
- core.async_jobs[jobid] = nil
-end
-
-if core.register_globalstep then
- core.register_globalstep(function(dtime)
- for i, job in ipairs(core.get_finished_jobs()) do
- handle_job(job.jobid, job.retval)
- end
- end)
-else
- core.async_event_handler = handle_job
-end
-
-function core.handle_async(func, parameter, callback)
- -- Serialize function
- local serialized_func = string.dump(func)
-
- assert(serialized_func ~= nil)
-
- -- Serialize parameters
- local serialized_param = core.serialize(parameter)
-
- if serialized_param == nil then
- return false
- end
-
- local jobid = core.do_async_callback(serialized_func, serialized_param)
-
- core.async_jobs[jobid] = callback
-
- return true
-end
-
diff -Nru minetest-5.2.0/builtin/common/misc_helpers.lua minetest-5.3.0/builtin/common/misc_helpers.lua
--- minetest-5.2.0/builtin/common/misc_helpers.lua 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/builtin/common/misc_helpers.lua 2020-07-09 21:13:20.000000000 +0000
@@ -20,6 +20,8 @@
-- dump's output is intended for humans.
--elseif tp == "function" then
-- return string.format("loadstring(%q)", string.dump(o))
+ elseif tp == "userdata" then
+ return tostring(o)
else
return string.format("<%s>", tp)
end
@@ -290,7 +292,8 @@
return
end
local undef = core.registered_nodes[unode.name]
- if undef and undef.on_rightclick then
+ local sneaking = placer and placer:get_player_control().sneak
+ if undef and undef.on_rightclick and not sneaking then
return undef.on_rightclick(pointed_thing.under, unode, placer,
itemstack, pointed_thing)
end
@@ -344,18 +347,12 @@
--Wrapper for rotate_and_place() to check for sneak and assume Creative mode
--implies infinite stacks when performing a 6d rotation.
--------------------------------------------------------------------------------
- local creative_mode_cache = core.settings:get_bool("creative_mode")
- local function is_creative(name)
- return creative_mode_cache or
- core.check_player_privs(name, {creative = true})
- end
-
core.rotate_node = function(itemstack, placer, pointed_thing)
local name = placer and placer:get_player_name() or ""
local invert_wall = placer and placer:get_player_control().sneak or false
return core.rotate_and_place(itemstack, placer, pointed_thing,
- is_creative(name),
- {invert_wall = invert_wall}, true)
+ core.is_creative_enabled(name),
+ {invert_wall = invert_wall}, true)
end
end
diff -Nru minetest-5.2.0/builtin/common/serialize.lua minetest-5.3.0/builtin/common/serialize.lua
--- minetest-5.2.0/builtin/common/serialize.lua 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/builtin/common/serialize.lua 2020-07-09 21:13:20.000000000 +0000
@@ -120,15 +120,8 @@
elseif tp == "function" then
return string.format("loadstring(%q)", string.dump(x))
elseif tp == "number" then
- -- Serialize integers with string.format to prevent
- -- scientific notation, which doesn't preserve
- -- precision and breaks things like node position
- -- hashes. Serialize floats normally.
- if math.floor(x) == x then
- return string.format("%d", x)
- else
- return tostring(x)
- end
+ -- Serialize numbers reversibly with string.format
+ return string.format("%.17g", x)
elseif tp == "table" then
local vals = {}
local idx_dumped = {}
diff -Nru minetest-5.2.0/builtin/common/tests/serialize_spec.lua minetest-5.3.0/builtin/common/tests/serialize_spec.lua
--- minetest-5.2.0/builtin/common/tests/serialize_spec.lua 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/builtin/common/tests/serialize_spec.lua 2020-07-09 21:13:20.000000000 +0000
@@ -18,6 +18,18 @@
assert.same(test_in, test_out)
end)
+ it("handles precise numbers", function()
+ local test_in = 0.2695949158945771
+ local test_out = core.deserialize(core.serialize(test_in))
+ assert.same(test_in, test_out)
+ end)
+
+ it("handles big integers", function()
+ local test_in = 269594915894577
+ local test_out = core.deserialize(core.serialize(test_in))
+ assert.same(test_in, test_out)
+ end)
+
it("handles recursive structures", function()
local test_in = { hello = "world" }
test_in.foo = test_in
diff -Nru minetest-5.2.0/builtin/common/tests/vector_spec.lua minetest-5.3.0/builtin/common/tests/vector_spec.lua
--- minetest-5.2.0/builtin/common/tests/vector_spec.lua 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/builtin/common/tests/vector_spec.lua 2020-07-09 21:13:20.000000000 +0000
@@ -43,4 +43,146 @@
it("add()", function()
assert.same({ x = 2, y = 4, z = 6 }, vector.add(vector.new(1, 2, 3), { x = 1, y = 2, z = 3 }))
end)
+
+ -- This function is needed because of floating point imprecision.
+ local function almost_equal(a, b)
+ if type(a) == "number" then
+ return math.abs(a - b) < 0.00000000001
+ end
+ return vector.distance(a, b) < 0.000000000001
+ end
+
+ describe("rotate_around_axis()", function()
+ it("rotates", function()
+ assert.True(almost_equal({x = -1, y = 0, z = 0},
+ vector.rotate_around_axis({x = 1, y = 0, z = 0}, {x = 0, y = 1, z = 0}, math.pi)))
+ assert.True(almost_equal({x = 0, y = 1, z = 0},
+ vector.rotate_around_axis({x = 0, y = 0, z = 1}, {x = 1, y = 0, z = 0}, math.pi / 2)))
+ assert.True(almost_equal({x = 4, y = 1, z = 1},
+ vector.rotate_around_axis({x = 4, y = 1, z = 1}, {x = 4, y = 1, z = 1}, math.pi / 6)))
+ end)
+ it("keeps distance to axis", function()
+ local rotate1 = {x = 1, y = 3, z = 1}
+ local axis1 = {x = 1, y = 3, z = 2}
+ local rotated1 = vector.rotate_around_axis(rotate1, axis1, math.pi / 13)
+ assert.True(almost_equal(vector.distance(axis1, rotate1), vector.distance(axis1, rotated1)))
+ local rotate2 = {x = 1, y = 1, z = 3}
+ local axis2 = {x = 2, y = 6, z = 100}
+ local rotated2 = vector.rotate_around_axis(rotate2, axis2, math.pi / 23)
+ assert.True(almost_equal(vector.distance(axis2, rotate2), vector.distance(axis2, rotated2)))
+ local rotate3 = {x = 1, y = -1, z = 3}
+ local axis3 = {x = 2, y = 6, z = 100}
+ local rotated3 = vector.rotate_around_axis(rotate3, axis3, math.pi / 2)
+ assert.True(almost_equal(vector.distance(axis3, rotate3), vector.distance(axis3, rotated3)))
+ end)
+ it("rotates back", function()
+ local rotate1 = {x = 1, y = 3, z = 1}
+ local axis1 = {x = 1, y = 3, z = 2}
+ local rotated1 = vector.rotate_around_axis(rotate1, axis1, math.pi / 13)
+ rotated1 = vector.rotate_around_axis(rotated1, axis1, -math.pi / 13)
+ assert.True(almost_equal(rotate1, rotated1))
+ local rotate2 = {x = 1, y = 1, z = 3}
+ local axis2 = {x = 2, y = 6, z = 100}
+ local rotated2 = vector.rotate_around_axis(rotate2, axis2, math.pi / 23)
+ rotated2 = vector.rotate_around_axis(rotated2, axis2, -math.pi / 23)
+ assert.True(almost_equal(rotate2, rotated2))
+ local rotate3 = {x = 1, y = -1, z = 3}
+ local axis3 = {x = 2, y = 6, z = 100}
+ local rotated3 = vector.rotate_around_axis(rotate3, axis3, math.pi / 2)
+ rotated3 = vector.rotate_around_axis(rotated3, axis3, -math.pi / 2)
+ assert.True(almost_equal(rotate3, rotated3))
+ end)
+ it("is right handed", function()
+ local v_before1 = {x = 0, y = 1, z = -1}
+ local v_after1 = vector.rotate_around_axis(v_before1, {x = 1, y = 0, z = 0}, math.pi / 4)
+ assert.True(almost_equal(vector.normalize(vector.cross(v_after1, v_before1)), {x = 1, y = 0, z = 0}))
+
+ local v_before2 = {x = 0, y = 3, z = 4}
+ local v_after2 = vector.rotate_around_axis(v_before2, {x = 1, y = 0, z = 0}, 2 * math.pi / 5)
+ assert.True(almost_equal(vector.normalize(vector.cross(v_after2, v_before2)), {x = 1, y = 0, z = 0}))
+
+ local v_before3 = {x = 1, y = 0, z = -1}
+ local v_after3 = vector.rotate_around_axis(v_before3, {x = 0, y = 1, z = 0}, math.pi / 4)
+ assert.True(almost_equal(vector.normalize(vector.cross(v_after3, v_before3)), {x = 0, y = 1, z = 0}))
+
+ local v_before4 = {x = 3, y = 0, z = 4}
+ local v_after4 = vector.rotate_around_axis(v_before4, {x = 0, y = 1, z = 0}, 2 * math.pi / 5)
+ assert.True(almost_equal(vector.normalize(vector.cross(v_after4, v_before4)), {x = 0, y = 1, z = 0}))
+
+ local v_before5 = {x = 1, y = -1, z = 0}
+ local v_after5 = vector.rotate_around_axis(v_before5, {x = 0, y = 0, z = 1}, math.pi / 4)
+ assert.True(almost_equal(vector.normalize(vector.cross(v_after5, v_before5)), {x = 0, y = 0, z = 1}))
+
+ local v_before6 = {x = 3, y = 4, z = 0}
+ local v_after6 = vector.rotate_around_axis(v_before6, {x = 0, y = 0, z = 1}, 2 * math.pi / 5)
+ assert.True(almost_equal(vector.normalize(vector.cross(v_after6, v_before6)), {x = 0, y = 0, z = 1}))
+ end)
+ end)
+
+ describe("rotate()", function()
+ it("rotates", function()
+ assert.True(almost_equal({x = -1, y = 0, z = 0},
+ vector.rotate({x = 1, y = 0, z = 0}, {x = 0, y = math.pi, z = 0})))
+ assert.True(almost_equal({x = 0, y = -1, z = 0},
+ vector.rotate({x = 1, y = 0, z = 0}, {x = 0, y = 0, z = math.pi / 2})))
+ assert.True(almost_equal({x = 1, y = 0, z = 0},
+ vector.rotate({x = 1, y = 0, z = 0}, {x = math.pi / 123, y = 0, z = 0})))
+ end)
+ it("is counterclockwise", function()
+ local v_before1 = {x = 0, y = 1, z = -1}
+ local v_after1 = vector.rotate(v_before1, {x = math.pi / 4, y = 0, z = 0})
+ assert.True(almost_equal(vector.normalize(vector.cross(v_after1, v_before1)), {x = 1, y = 0, z = 0}))
+
+ local v_before2 = {x = 0, y = 3, z = 4}
+ local v_after2 = vector.rotate(v_before2, {x = 2 * math.pi / 5, y = 0, z = 0})
+ assert.True(almost_equal(vector.normalize(vector.cross(v_after2, v_before2)), {x = 1, y = 0, z = 0}))
+
+ local v_before3 = {x = 1, y = 0, z = -1}
+ local v_after3 = vector.rotate(v_before3, {x = 0, y = math.pi / 4, z = 0})
+ assert.True(almost_equal(vector.normalize(vector.cross(v_after3, v_before3)), {x = 0, y = 1, z = 0}))
+
+ local v_before4 = {x = 3, y = 0, z = 4}
+ local v_after4 = vector.rotate(v_before4, {x = 0, y = 2 * math.pi / 5, z = 0})
+ assert.True(almost_equal(vector.normalize(vector.cross(v_after4, v_before4)), {x = 0, y = 1, z = 0}))
+
+ local v_before5 = {x = 1, y = -1, z = 0}
+ local v_after5 = vector.rotate(v_before5, {x = 0, y = 0, z = math.pi / 4})
+ assert.True(almost_equal(vector.normalize(vector.cross(v_after5, v_before5)), {x = 0, y = 0, z = 1}))
+
+ local v_before6 = {x = 3, y = 4, z = 0}
+ local v_after6 = vector.rotate(v_before6, {x = 0, y = 0, z = 2 * math.pi / 5})
+ assert.True(almost_equal(vector.normalize(vector.cross(v_after6, v_before6)), {x = 0, y = 0, z = 1}))
+ end)
+ end)
+
+ it("dir_to_rotation()", function()
+ -- Comparing rotations (pitch, yaw, roll) is hard because of certain ambiguities,
+ -- e.g. (pi, 0, pi) looks exactly the same as (0, pi, 0)
+ -- So instead we convert the rotation back to vectors and compare these.
+ local function forward_at_rot(rot)
+ return vector.rotate(vector.new(0, 0, 1), rot)
+ end
+ local function up_at_rot(rot)
+ return vector.rotate(vector.new(0, 1, 0), rot)
+ end
+ local rot1 = vector.dir_to_rotation({x = 1, y = 0, z = 0}, {x = 0, y = 1, z = 0})
+ assert.True(almost_equal({x = 1, y = 0, z = 0}, forward_at_rot(rot1)))
+ assert.True(almost_equal({x = 0, y = 1, z = 0}, up_at_rot(rot1)))
+ local rot2 = vector.dir_to_rotation({x = 1, y = 1, z = 0}, {x = 0, y = 0, z = 1})
+ assert.True(almost_equal({x = 1/math.sqrt(2), y = 1/math.sqrt(2), z = 0}, forward_at_rot(rot2)))
+ assert.True(almost_equal({x = 0, y = 0, z = 1}, up_at_rot(rot2)))
+ for i = 1, 1000 do
+ local rand_vec = vector.new(math.random(), math.random(), math.random())
+ if vector.length(rand_vec) ~= 0 then
+ local rot_1 = vector.dir_to_rotation(rand_vec)
+ local rot_2 = {
+ x = math.atan2(rand_vec.y, math.sqrt(rand_vec.z * rand_vec.z + rand_vec.x * rand_vec.x)),
+ y = -math.atan2(rand_vec.x, rand_vec.z),
+ z = 0
+ }
+ assert.True(almost_equal(rot_1, rot_2))
+ end
+ end
+
+ end)
end)
diff -Nru minetest-5.2.0/builtin/common/vector.lua minetest-5.3.0/builtin/common/vector.lua
--- minetest-5.2.0/builtin/common/vector.lua 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/builtin/common/vector.lua 2020-07-09 21:13:20.000000000 +0000
@@ -141,3 +141,96 @@
return {x = math.min(a.x, b.x), y = math.min(a.y, b.y), z = math.min(a.z, b.z)},
{x = math.max(a.x, b.x), y = math.max(a.y, b.y), z = math.max(a.z, b.z)}
end
+
+local function sin(x)
+ if x % math.pi == 0 then
+ return 0
+ else
+ return math.sin(x)
+ end
+end
+
+local function cos(x)
+ if x % math.pi == math.pi / 2 then
+ return 0
+ else
+ return math.cos(x)
+ end
+end
+
+function vector.rotate_around_axis(v, axis, angle)
+ local cosangle = cos(angle)
+ local sinangle = sin(angle)
+ axis = vector.normalize(axis)
+ -- https://en.wikipedia.org/wiki/Rodrigues%27_rotation_formula
+ local dot_axis = vector.multiply(axis, vector.dot(axis, v))
+ local cross = vector.cross(v, axis)
+ return vector.new(
+ cross.x * sinangle + (v.x - dot_axis.x) * cosangle + dot_axis.x,
+ cross.y * sinangle + (v.y - dot_axis.y) * cosangle + dot_axis.y,
+ cross.z * sinangle + (v.z - dot_axis.z) * cosangle + dot_axis.z
+ )
+end
+
+function vector.rotate(v, rot)
+ local sinpitch = sin(-rot.x)
+ local sinyaw = sin(-rot.y)
+ local sinroll = sin(-rot.z)
+ local cospitch = cos(rot.x)
+ local cosyaw = cos(rot.y)
+ local cosroll = math.cos(rot.z)
+ -- Rotation matrix that applies yaw, pitch and roll
+ local matrix = {
+ {
+ sinyaw * sinpitch * sinroll + cosyaw * cosroll,
+ sinyaw * sinpitch * cosroll - cosyaw * sinroll,
+ sinyaw * cospitch,
+ },
+ {
+ cospitch * sinroll,
+ cospitch * cosroll,
+ -sinpitch,
+ },
+ {
+ cosyaw * sinpitch * sinroll - sinyaw * cosroll,
+ cosyaw * sinpitch * cosroll + sinyaw * sinroll,
+ cosyaw * cospitch,
+ },
+ }
+ -- Compute matrix multiplication: `matrix` * `v`
+ return vector.new(
+ matrix[1][1] * v.x + matrix[1][2] * v.y + matrix[1][3] * v.z,
+ matrix[2][1] * v.x + matrix[2][2] * v.y + matrix[2][3] * v.z,
+ matrix[3][1] * v.x + matrix[3][2] * v.y + matrix[3][3] * v.z
+ )
+end
+
+function vector.dir_to_rotation(forward, up)
+ forward = vector.normalize(forward)
+ local rot = {x = math.asin(forward.y), y = -math.atan2(forward.x, forward.z), z = 0}
+ if not up then
+ return rot
+ end
+ assert(vector.dot(forward, up) < 0.000001,
+ "Invalid vectors passed to vector.dir_to_rotation().")
+ up = vector.normalize(up)
+ -- Calculate vector pointing up with roll = 0, just based on forward vector.
+ local forwup = vector.rotate({x = 0, y = 1, z = 0}, rot)
+ -- 'forwup' and 'up' are now in a plane with 'forward' as normal.
+ -- The angle between them is the absolute of the roll value we're looking for.
+ rot.z = vector.angle(forwup, up)
+
+ -- Since vector.angle never returns a negative value or a value greater
+ -- than math.pi, rot.z has to be inverted sometimes.
+ -- To determine wether this is the case, we rotate the up vector back around
+ -- the forward vector and check if it worked out.
+ local back = vector.rotate_around_axis(up, forward, -rot.z)
+
+ -- We don't use vector.equals for this because of floating point imprecision.
+ if (back.x - forwup.x) * (back.x - forwup.x) +
+ (back.y - forwup.y) * (back.y - forwup.y) +
+ (back.z - forwup.z) * (back.z - forwup.z) > 0.0000001 then
+ rot.z = -rot.z
+ end
+ return rot
+end
diff -Nru minetest-5.2.0/builtin/fstk/dialog.lua minetest-5.3.0/builtin/fstk/dialog.lua
--- minetest-5.2.0/builtin/fstk/dialog.lua 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/builtin/fstk/dialog.lua 2020-07-09 21:13:20.000000000 +0000
@@ -67,3 +67,22 @@
ui.add(self)
return self
end
+
+function messagebox(name, message)
+ return dialog_create(name,
+ function()
+ return ([[
+ formspec_version[3]
+ size[8,3]
+ textarea[0.375,0.375;7.25,1.2;;;%s]
+ button[3,1.825;2,0.8;ok;%s]
+ ]]):format(message, fgettext("OK"))
+ end,
+ function(this, fields)
+ if fields.ok then
+ this:delete()
+ return true
+ end
+ end,
+ nil)
+end
diff -Nru minetest-5.2.0/builtin/fstk/ui.lua minetest-5.3.0/builtin/fstk/ui.lua
--- minetest-5.2.0/builtin/fstk/ui.lua 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/builtin/fstk/ui.lua 2020-07-09 21:13:20.000000000 +0000
@@ -85,7 +85,7 @@
"box[0.5,1.2;13,5;#000]",
("textarea[0.5,1.2;13,5;;%s;%s]"):format(
error_title, error_message),
- "button[5,6.6;4,1;btn_error_confirm;" .. fgettext("Ok") .. "]"
+ "button[5,6.6;4,1;btn_error_confirm;" .. fgettext("OK") .. "]"
}
else
local active_toplevel_ui_elements = 0
diff -Nru minetest-5.2.0/builtin/game/auth.lua minetest-5.3.0/builtin/game/auth.lua
--- minetest-5.2.0/builtin/game/auth.lua 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/builtin/game/auth.lua 2020-07-09 21:13:20.000000000 +0000
@@ -41,7 +41,6 @@
return {
password = auth_entry.password,
privileges = privileges,
- -- Is set to nil if unknown
last_login = auth_entry.last_login,
}
end,
@@ -53,7 +52,7 @@
name = name,
password = password,
privileges = core.string_to_privs(core.settings:get("default_privs")),
- last_login = os.time(),
+ last_login = -1, -- Defer login time calculation until record_login (called by on_joinplayer)
})
end,
delete_auth = function(name)
diff -Nru minetest-5.2.0/builtin/game/chat.lua minetest-5.3.0/builtin/game/chat.lua
--- minetest-5.2.0/builtin/game/chat.lua 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/builtin/game/chat.lua 2020-07-09 21:13:20.000000000 +0000
@@ -239,57 +239,76 @@
end,
})
+local function handle_revoke_command(caller, revokename, revokeprivstr)
+ local caller_privs = core.get_player_privs(caller)
+ if not (caller_privs.privs or caller_privs.basic_privs) then
+ return false, "Your privileges are insufficient."
+ end
+
+ if not core.get_auth_handler().get_auth(revokename) then
+ return false, "Player " .. revokename .. " does not exist."
+ end
+
+ local revokeprivs = core.string_to_privs(revokeprivstr)
+ local privs = core.get_player_privs(revokename)
+ local basic_privs =
+ core.string_to_privs(core.settings:get("basic_privs") or "interact,shout")
+ for priv, _ in pairs(revokeprivs) do
+ if not basic_privs[priv] and not caller_privs.privs then
+ return false, "Your privileges are insufficient."
+ end
+ end
+
+ if revokeprivstr == "all" then
+ revokeprivs = privs
+ privs = {}
+ else
+ for priv, _ in pairs(revokeprivs) do
+ privs[priv] = nil
+ end
+ end
+
+ for priv, _ in pairs(revokeprivs) do
+ -- call the on_revoke callbacks
+ core.run_priv_callbacks(revokename, priv, caller, "revoke")
+ end
+
+ core.set_player_privs(revokename, privs)
+ core.log("action", caller..' revoked ('
+ ..core.privs_to_string(revokeprivs, ', ')
+ ..') privileges from '..revokename)
+ if revokename ~= caller then
+ core.chat_send_player(revokename, caller
+ .. " revoked privileges from you: "
+ .. core.privs_to_string(revokeprivs, ' '))
+ end
+ return true, "Privileges of " .. revokename .. ": "
+ .. core.privs_to_string(
+ core.get_player_privs(revokename), ' ')
+end
+
core.register_chatcommand("revoke", {
params = " ( | all)",
description = "Remove privileges from player",
privs = {},
func = function(name, param)
- if not core.check_player_privs(name, {privs=true}) and
- not core.check_player_privs(name, {basic_privs=true}) then
- return false, "Your privileges are insufficient."
- end
- local revoke_name, revoke_priv_str = string.match(param, "([^ ]+) (.+)")
- if not revoke_name or not revoke_priv_str then
+ local revokename, revokeprivstr = string.match(param, "([^ ]+) (.+)")
+ if not revokename or not revokeprivstr then
return false, "Invalid parameters (see /help revoke)"
- elseif not core.get_auth_handler().get_auth(revoke_name) then
- return false, "Player " .. revoke_name .. " does not exist."
- end
- local revoke_privs = core.string_to_privs(revoke_priv_str)
- local privs = core.get_player_privs(revoke_name)
- local basic_privs =
- core.string_to_privs(core.settings:get("basic_privs") or "interact,shout")
- for priv, _ in pairs(revoke_privs) do
- if not basic_privs[priv] and
- not core.check_player_privs(name, {privs=true}) then
- return false, "Your privileges are insufficient."
- end
- end
- if revoke_priv_str == "all" then
- revoke_privs = privs
- privs = {}
- else
- for priv, _ in pairs(revoke_privs) do
- privs[priv] = nil
- end
- end
-
- for priv, _ in pairs(revoke_privs) do
- -- call the on_revoke callbacks
- core.run_priv_callbacks(revoke_name, priv, name, "revoke")
end
+ return handle_revoke_command(name, revokename, revokeprivstr)
+ end,
+})
- core.set_player_privs(revoke_name, privs)
- core.log("action", name..' revoked ('
- ..core.privs_to_string(revoke_privs, ', ')
- ..') privileges from '..revoke_name)
- if revoke_name ~= name then
- core.chat_send_player(revoke_name, name
- .. " revoked privileges from you: "
- .. core.privs_to_string(revoke_privs, ' '))
+core.register_chatcommand("revokeme", {
+ params = " | all",
+ description = "Revoke privileges from yourself",
+ privs = {},
+ func = function(name, param)
+ if param == "" then
+ return false, "Invalid parameters (see /help revokeme)"
end
- return true, "Privileges of " .. revoke_name .. ": "
- .. core.privs_to_string(
- core.get_player_privs(revoke_name), ' ')
+ return handle_revoke_command(name, name, param)
end,
})
@@ -424,6 +443,9 @@
end
local teleportee = core.get_player_by_name(name)
if teleportee then
+ if teleportee:get_attach() then
+ return false, "Can't teleport, you're attached to an object!"
+ end
teleportee:set_pos(p)
return true, "Teleporting to "..core.pos_to_string(p)
end
@@ -441,6 +463,9 @@
end
if teleportee and p then
+ if teleportee:get_attach() then
+ return false, "Can't teleport, you're attached to an object!"
+ end
p = find_free_position_near(p)
teleportee:set_pos(p)
return true, "Teleporting to " .. target_name
@@ -461,6 +486,9 @@
teleportee = core.get_player_by_name(teleportee_name)
end
if teleportee and p.x and p.y and p.z then
+ if teleportee:get_attach() then
+ return false, "Can't teleport, player is attached to an object!"
+ end
teleportee:set_pos(p)
return true, "Teleporting " .. teleportee_name
.. " to " .. core.pos_to_string(p)
@@ -479,6 +507,9 @@
end
end
if teleportee and p then
+ if teleportee:get_attach() then
+ return false, "Can't teleport, player is attached to an object!"
+ end
p = find_free_position_near(p)
teleportee:set_pos(p)
return true, "Teleporting " .. teleportee_name
@@ -717,8 +748,9 @@
end
end
p.y = p.y + 1
- core.add_entity(p, entityname)
- return true, ("%q spawned."):format(entityname)
+ local obj = core.add_entity(p, entityname)
+ local msg = obj and "%q spawned." or "%q failed to spawn."
+ return true, msg:format(entityname)
end,
})
@@ -757,7 +789,7 @@
params = "[] [] []",
description = "Check who last touched a node or a node near it"
.. " within the time specified by . Default: range = 0,"
- .. " seconds = 86400 = 24h, limit = 5",
+ .. " seconds = 86400 = 24h, limit = 5. Set to inf for no time limit",
privs = {rollback=true},
func = function(name, param)
if not core.settings:get_bool("enable_rollback_recording") then
@@ -808,7 +840,7 @@
core.register_chatcommand("rollback", {
params = "( []) | (: [])",
- description = "Revert actions of a player. Default for is 60",
+ description = "Revert actions of a player. Default for is 60. Set to inf for no time limit",
privs = {rollback=true},
func = function(name, param)
if not core.settings:get_bool("enable_rollback_recording") then
@@ -1036,7 +1068,7 @@
param = name
end
local pauth = core.get_auth_handler().get_auth(param)
- if pauth and pauth.last_login then
+ if pauth and pauth.last_login and pauth.last_login ~= -1 then
-- Time in UTC, ISO 8601 format
return true, "Last login time was " ..
os.date("!%Y-%m-%dT%H:%M:%SZ", pauth.last_login)
diff -Nru minetest-5.2.0/builtin/game/constants.lua minetest-5.3.0/builtin/game/constants.lua
--- minetest-5.2.0/builtin/game/constants.lua 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/builtin/game/constants.lua 2020-07-09 21:13:20.000000000 +0000
@@ -24,7 +24,7 @@
-- Default maximal HP of a player
core.PLAYER_MAX_HP_DEFAULT = 20
-- Default maximal breath of a player
-core.PLAYER_MAX_BREATH_DEFAULT = 11
+core.PLAYER_MAX_BREATH_DEFAULT = 10
-- light.h
-- Maximum value for node 'light_source' parameter
diff -Nru minetest-5.2.0/builtin/game/deprecated.lua minetest-5.3.0/builtin/game/deprecated.lua
--- minetest-5.2.0/builtin/game/deprecated.lua 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/builtin/game/deprecated.lua 2020-07-09 21:13:20.000000000 +0000
@@ -70,3 +70,19 @@
core.setting_setbool = setting_proxy("set_bool")
core.setting_getbool = setting_proxy("get_bool")
core.setting_save = setting_proxy("write")
+
+--
+-- core.register_on_auth_fail
+--
+
+function core.register_on_auth_fail(func)
+ core.log("deprecated", "core.register_on_auth_fail " ..
+ "is obsolete and should be replaced by " ..
+ "core.register_on_authplayer instead.")
+
+ core.register_on_authplayer(function (player_name, ip, is_success)
+ if not is_success then
+ func(player_name, ip)
+ end
+ end)
+end
diff -Nru minetest-5.2.0/builtin/game/falling.lua minetest-5.3.0/builtin/game/falling.lua
--- minetest-5.2.0/builtin/game/falling.lua 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/builtin/game/falling.lua 2020-07-09 21:13:20.000000000 +0000
@@ -30,6 +30,8 @@
{y = math.pi/2, x = math.pi, z = 0}
}
+local gravity = tonumber(core.settings:get("movement_gravity")) or 9.81
+
--
-- Falling stuff
--
@@ -41,12 +43,13 @@
textures = {},
physical = true,
is_visible = false,
- collide_with_objects = false,
+ collide_with_objects = true,
collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
},
node = {},
meta = {},
+ floats = false,
set_node = function(self, node, meta)
self.node = node
@@ -71,6 +74,11 @@
return
end
self.meta = meta
+
+ -- Cache whether we're supposed to float on water
+ self.floats = core.get_item_group(node.name, "float") ~= 0
+
+ -- Set entity visuals
if def.drawtype == "torchlike" or def.drawtype == "signlike" then
local textures
if def.tiles and def.tiles[1] then
@@ -101,6 +109,7 @@
if core.is_colored_paramtype(def.paramtype2) then
itemstring = core.itemstring_with_palette(itemstring, node.param2)
end
+ -- FIXME: solution needed for paramtype2 == "leveled"
local vsize
if def.visual_scale then
local s = def.visual_scale * SCALE
@@ -113,6 +122,25 @@
glow = def.light_source,
})
end
+
+ -- Set collision box (certain nodeboxes only for now)
+ local nb_types = {fixed=true, leveled=true, connected=true}
+ if def.drawtype == "nodebox" and def.node_box and
+ nb_types[def.node_box.type] then
+ local box = table.copy(def.node_box.fixed)
+ if type(box[1]) == "table" then
+ box = #box == 1 and box[1] or nil -- We can only use a single box
+ end
+ if box then
+ if def.paramtype2 == "leveled" and (self.node.level or 0) > 0 then
+ box[5] = -0.5 + self.node.level / 64
+ end
+ self.object:set_properties({
+ collisionbox = box
+ })
+ end
+ end
+
-- Rotate entity
if def.drawtype == "torchlike" then
self.object:set_yaw(math.pi*0.25)
@@ -172,6 +200,7 @@
on_activate = function(self, staticdata)
self.object:set_armor_groups({immortal = 1})
+ self.object:set_acceleration({x = 0, y = -gravity, z = 0})
local ds = core.deserialize(staticdata)
if ds and ds.node then
@@ -183,85 +212,159 @@
end
end,
- on_step = function(self, dtime)
- -- Set gravity
- local acceleration = self.object:get_acceleration()
- if not vector.equals(acceleration, {x = 0, y = -10, z = 0}) then
- self.object:set_acceleration({x = 0, y = -10, z = 0})
- end
- -- Turn to actual node when colliding with ground, or continue to move
- local pos = self.object:get_pos()
- -- Position of bottom center point
- local bcp = {x = pos.x, y = pos.y - 0.7, z = pos.z}
- -- 'bcn' is nil for unloaded nodes
- local bcn = core.get_node_or_nil(bcp)
- -- Delete on contact with ignore at world edges
- if bcn and bcn.name == "ignore" then
- self.object:remove()
- return
+ try_place = function(self, bcp, bcn)
+ local bcd = core.registered_nodes[bcn.name]
+ -- Add levels if dropped on same leveled node
+ if bcd and bcd.paramtype2 == "leveled" and
+ bcn.name == self.node.name then
+ local addlevel = self.node.level
+ if (addlevel or 0) <= 0 then
+ addlevel = bcd.leveled
+ end
+ if core.add_node_level(bcp, addlevel) < addlevel then
+ return true
+ elseif bcd.buildable_to then
+ -- Node level has already reached max, don't place anything
+ return true
+ end
end
- local bcd = bcn and core.registered_nodes[bcn.name]
- if bcn and
- (not bcd or bcd.walkable or
- (core.get_item_group(self.node.name, "float") ~= 0 and
- bcd.liquidtype ~= "none")) then
- if bcd and bcd.leveled and
- bcn.name == self.node.name then
- local addlevel = self.node.level
- if not addlevel or addlevel <= 0 then
- addlevel = bcd.leveled
+
+ -- Decide if we're replacing the node or placing on top
+ local np = vector.new(bcp)
+ if bcd and bcd.buildable_to and
+ (not self.floats or bcd.liquidtype == "none") then
+ core.remove_node(bcp)
+ else
+ np.y = np.y + 1
+ end
+
+ -- Check what's here
+ local n2 = core.get_node(np)
+ local nd = core.registered_nodes[n2.name]
+ -- If it's not air or liquid, remove node and replace it with
+ -- it's drops
+ if n2.name ~= "air" and (not nd or nd.liquidtype == "none") then
+ if nd and nd.buildable_to == false then
+ nd.on_dig(np, n2, nil)
+ -- If it's still there, it might be protected
+ if core.get_node(np).name == n2.name then
+ return false
end
- if core.add_node_level(bcp, addlevel) == 0 then
+ else
+ core.remove_node(np)
+ end
+ end
+
+ -- Create node
+ local def = core.registered_nodes[self.node.name]
+ if def then
+ core.add_node(np, self.node)
+ if self.meta then
+ core.get_meta(np):from_table(self.meta)
+ end
+ if def.sounds and def.sounds.place then
+ core.sound_play(def.sounds.place, {pos = np}, true)
+ end
+ end
+ core.check_for_falling(np)
+ return true
+ end,
+
+ on_step = function(self, dtime, moveresult)
+ -- Fallback code since collision detection can't tell us
+ -- about liquids (which do not collide)
+ if self.floats then
+ local pos = self.object:get_pos()
+
+ local bcp = vector.round({x = pos.x, y = pos.y - 0.7, z = pos.z})
+ local bcn = core.get_node(bcp)
+
+ local bcd = core.registered_nodes[bcn.name]
+ if bcd and bcd.liquidtype ~= "none" then
+ if self:try_place(bcp, bcn) then
self.object:remove()
return
end
- elseif bcd and bcd.buildable_to and
- (core.get_item_group(self.node.name, "float") == 0 or
- bcd.liquidtype == "none") then
- core.remove_node(bcp)
- return
- end
- local np = {x = bcp.x, y = bcp.y + 1, z = bcp.z}
- -- Check what's here
- local n2 = core.get_node(np)
- local nd = core.registered_nodes[n2.name]
- -- If it's not air or liquid, remove node and replace it with
- -- it's drops
- if n2.name ~= "air" and (not nd or nd.liquidtype == "none") then
- core.remove_node(np)
- if nd and nd.buildable_to == false then
- -- Add dropped items
- local drops = core.get_node_drops(n2, "")
- for _, dropped_item in pairs(drops) do
- core.add_item(np, dropped_item)
+ end
+ end
+
+ assert(moveresult)
+ if not moveresult.collides then
+ return -- Nothing to do :)
+ end
+
+ local bcp, bcn
+ local player_collision
+ if moveresult.touching_ground then
+ for _, info in ipairs(moveresult.collisions) do
+ if info.type == "object" then
+ if info.axis == "y" and info.object:is_player() then
+ player_collision = info
end
- end
- -- Run script hook
- for _, callback in pairs(core.registered_on_dignodes) do
- callback(np, n2)
+ elseif info.axis == "y" then
+ bcp = info.node_pos
+ bcn = core.get_node(bcp)
+ break
end
end
- -- Create node and remove entity
- local def = core.registered_nodes[self.node.name]
- if def then
- core.add_node(np, self.node)
- if self.meta then
- local meta = core.get_meta(np)
- meta:from_table(self.meta)
- end
- if def.sounds and def.sounds.place then
- core.sound_play(def.sounds.place, {pos = np}, true)
- end
+ end
+
+ if not bcp then
+ -- We're colliding with something, but not the ground. Irrelevant to us.
+ if player_collision then
+ -- Continue falling through players by moving a little into
+ -- their collision box
+ -- TODO: this hack could be avoided in the future if objects
+ -- could choose who to collide with
+ local vel = self.object:get_velocity()
+ self.object:set_velocity({
+ x = vel.x,
+ y = player_collision.old_velocity.y,
+ z = vel.z
+ })
+ self.object:set_pos(vector.add(self.object:get_pos(),
+ {x = 0, y = -0.5, z = 0}))
end
+ return
+ elseif bcn.name == "ignore" then
+ -- Delete on contact with ignore at world edges
self.object:remove()
- core.check_for_falling(np)
return
end
- local vel = self.object:get_velocity()
- if vector.equals(vel, {x = 0, y = 0, z = 0}) then
- local npos = self.object:get_pos()
- self.object:set_pos(vector.round(npos))
+
+ local failure = false
+
+ local pos = self.object:get_pos()
+ local distance = vector.apply(vector.subtract(pos, bcp), math.abs)
+ if distance.x >= 1 or distance.z >= 1 then
+ -- We're colliding with some part of a node that's sticking out
+ -- Since we don't want to visually teleport, drop as item
+ failure = true
+ elseif distance.y >= 2 then
+ -- Doors consist of a hidden top node and a bottom node that is
+ -- the actual door. Despite the top node being solid, the moveresult
+ -- almost always indicates collision with the bottom node.
+ -- Compensate for this by checking the top node
+ bcp.y = bcp.y + 1
+ bcn = core.get_node(bcp)
+ local def = core.registered_nodes[bcn.name]
+ if not (def and def.walkable) then
+ failure = true -- This is unexpected, fail
+ end
+ end
+
+ -- Try to actually place ourselves
+ if not failure then
+ failure = not self:try_place(bcp, bcn)
+ end
+
+ if failure then
+ local drops = core.get_node_drops(self.node, "")
+ for _, item in pairs(drops) do
+ core.add_item(pos, item)
+ end
end
+ self.object:remove()
end
})
@@ -270,6 +373,7 @@
if not obj then
return false
end
+ -- remember node level, the entities' set_node() uses this
node.level = core.get_node_level(pos)
local meta = core.get_meta(pos)
local metatable = meta and meta:to_table() or {}
@@ -355,18 +459,23 @@
-- Only spawn falling node if node below is loaded
local n_bottom = core.get_node_or_nil(p_bottom)
local d_bottom = n_bottom and core.registered_nodes[n_bottom.name]
- if d_bottom and
-
- (core.get_item_group(n.name, "float") == 0 or
- d_bottom.liquidtype == "none") and
-
- (n.name ~= n_bottom.name or (d_bottom.leveled and
- core.get_node_level(p_bottom) <
- core.get_node_max_level(p_bottom))) and
-
- (not d_bottom.walkable or d_bottom.buildable_to) then
- convert_to_falling_node(p, n)
- return true
+ if d_bottom then
+ local same = n.name == n_bottom.name
+ -- Let leveled nodes fall if it can merge with the bottom node
+ if same and d_bottom.paramtype2 == "leveled" and
+ core.get_node_level(p_bottom) <
+ core.get_node_max_level(p_bottom) then
+ convert_to_falling_node(p, n)
+ return true
+ end
+ -- Otherwise only if the bottom node is considered "fall through"
+ if not same and
+ (not d_bottom.walkable or d_bottom.buildable_to) and
+ (core.get_item_group(n.name, "float") == 0 or
+ d_bottom.liquidtype == "none") then
+ convert_to_falling_node(p, n)
+ return true
+ end
end
end
diff -Nru minetest-5.2.0/builtin/game/features.lua minetest-5.3.0/builtin/game/features.lua
--- minetest-5.2.0/builtin/game/features.lua 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/builtin/game/features.lua 2020-07-09 21:13:20.000000000 +0000
@@ -16,6 +16,7 @@
formspec_version_element = true,
area_store_persistent_ids = true,
pathfinder_works = true,
+ object_step_has_moveresult = true,
}
function core.has_feature(arg)
diff -Nru minetest-5.2.0/builtin/game/item_entity.lua minetest-5.3.0/builtin/game/item_entity.lua
--- minetest-5.2.0/builtin/game/item_entity.lua 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/builtin/game/item_entity.lua 2020-07-09 21:13:20.000000000 +0000
@@ -27,14 +27,11 @@
visual = "wielditem",
visual_size = {x = 0.4, y = 0.4},
textures = {""},
- spritediv = {x = 1, y = 1},
- initial_sprite_basepos = {x = 0, y = 0},
is_visible = false,
},
itemstring = "",
moving_state = true,
- slippery_state = false,
physical_state = true,
-- Item expiry
age = 0,
@@ -57,7 +54,6 @@
local max_count = stack:get_stack_max()
local count = math.min(stack:get_count(), max_count)
local size = 0.2 + 0.1 * (count / max_count) ^ (1 / 3)
- local coll_height = size * 0.75
local def = core.registered_nodes[itemname]
local glow = def and math.floor(def.light_source / 2 + 0.5)
@@ -66,9 +62,7 @@
visual = "wielditem",
textures = {itemname},
visual_size = {x = size, y = size},
- collisionbox = {-size, -coll_height, -size,
- size, coll_height, size},
- selectionbox = {-size, -size, -size, size, size, size},
+ collisionbox = {-size, -size, -size, size, size, size},
automatic_rotate = math.pi * 0.5 * 0.2 / size,
wield_item = self.itemstring,
glow = glow,
@@ -157,7 +151,7 @@
end
end,
- on_step = function(self, dtime)
+ on_step = function(self, dtime, moveresult)
self.age = self.age + dtime
if time_to_live > 0 and self.age > time_to_live then
self.itemstring = ""
@@ -178,6 +172,38 @@
return
end
+ if self.force_out then
+ -- This code runs after the entity got a push from the is_stuck code.
+ -- It makes sure the entity is entirely outside the solid node
+ local c = self.object:get_properties().collisionbox
+ local s = self.force_out_start
+ local f = self.force_out
+ local ok = (f.x > 0 and pos.x + c[1] > s.x + 0.5) or
+ (f.y > 0 and pos.y + c[2] > s.y + 0.5) or
+ (f.z > 0 and pos.z + c[3] > s.z + 0.5) or
+ (f.x < 0 and pos.x + c[4] < s.x - 0.5) or
+ (f.z < 0 and pos.z + c[6] < s.z - 0.5)
+ if ok then
+ -- Item was successfully forced out
+ self.force_out = nil
+ self:enable_physics()
+ return
+ end
+ end
+
+ if not self.physical_state then
+ return -- Don't do anything
+ end
+
+ assert(moveresult,
+ "Collision info missing, this is caused by an out-of-date/buggy mod or game")
+
+ if not moveresult.collides then
+ -- future TODO: items should probably decelerate in air
+ return
+ end
+
+ -- Push item out when stuck inside solid node
local is_stuck = false
local snode = core.get_node_or_nil(pos)
if snode then
@@ -187,7 +213,6 @@
and (sdef.node_box == nil or sdef.node_box.type == "regular")
end
- -- Push item out when stuck inside solid node
if is_stuck then
local shootdir
local order = {
@@ -223,69 +248,49 @@
self.force_out_start = vector.round(pos)
return
end
- elseif self.force_out then
- -- This code runs after the entity got a push from the above code.
- -- It makes sure the entity is entirely outside the solid node
- local c = self.object:get_properties().collisionbox
- local s = self.force_out_start
- local f = self.force_out
- local ok = (f.x > 0 and pos.x + c[1] > s.x + 0.5) or
- (f.y > 0 and pos.y + c[2] > s.y + 0.5) or
- (f.z > 0 and pos.z + c[3] > s.z + 0.5) or
- (f.x < 0 and pos.x + c[4] < s.x - 0.5) or
- (f.z < 0 and pos.z + c[6] < s.z - 0.5)
- if ok then
- -- Item was successfully forced out
- self.force_out = nil
- self:enable_physics()
- end
end
- if not self.physical_state then
- return -- Don't do anything
+ node = nil -- ground node we're colliding with
+ if moveresult.touching_ground then
+ for _, info in ipairs(moveresult.collisions) do
+ if info.axis == "y" then
+ node = core.get_node(info.node_pos)
+ break
+ end
+ end
end
-- Slide on slippery nodes
- local vel = self.object:get_velocity()
local def = node and core.registered_nodes[node.name]
- local is_moving = (def and not def.walkable) or
- vel.x ~= 0 or vel.y ~= 0 or vel.z ~= 0
- local is_slippery = false
+ local keep_movement = false
- if def and def.walkable then
+ if def then
local slippery = core.get_item_group(node.name, "slippery")
- is_slippery = slippery ~= 0
- if is_slippery and (math.abs(vel.x) > 0.2 or math.abs(vel.z) > 0.2) then
+ local vel = self.object:get_velocity()
+ if slippery ~= 0 and (math.abs(vel.x) > 0.1 or math.abs(vel.z) > 0.1) then
-- Horizontal deceleration
- local slip_factor = 4.0 / (slippery + 4)
- self.object:set_acceleration({
- x = -vel.x * slip_factor,
+ local factor = math.min(4 / (slippery + 4) * dtime, 1)
+ self.object:set_velocity({
+ x = vel.x * (1 - factor),
y = 0,
- z = -vel.z * slip_factor
+ z = vel.z * (1 - factor)
})
- elseif vel.y == 0 then
- is_moving = false
+ keep_movement = true
end
end
- if self.moving_state == is_moving and
- self.slippery_state == is_slippery then
- -- Do not update anything until the moving state changes
- return
+ if not keep_movement then
+ self.object:set_velocity({x=0, y=0, z=0})
end
- self.moving_state = is_moving
- self.slippery_state = is_slippery
-
- if is_moving then
- self.object:set_acceleration({x = 0, y = -gravity, z = 0})
- else
- self.object:set_acceleration({x = 0, y = 0, z = 0})
- self.object:set_velocity({x = 0, y = 0, z = 0})
+ if self.moving_state == keep_movement then
+ -- Do not update anything until the moving state changes
+ return
end
+ self.moving_state = keep_movement
- --Only collect items if not moving
- if is_moving then
+ -- Only collect items if not moving
+ if self.moving_state then
return
end
-- Collect the items around to merge with
diff -Nru minetest-5.2.0/builtin/game/item.lua minetest-5.3.0/builtin/game/item.lua
--- minetest-5.2.0/builtin/game/item.lua 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/builtin/game/item.lua 2020-07-09 21:13:20.000000000 +0000
@@ -582,7 +582,7 @@
wielded = wdef.after_use(wielded, digger, node, dp) or wielded
else
-- Wear out tool
- if not core.settings:get_bool("creative_mode") then
+ if not core.is_creative_enabled(diggername) then
wielded:add_wear(dp.wear)
if wielded:get_count() == 0 and wdef.sound and wdef.sound.breaks then
core.sound_play(wdef.sound.breaks, {
@@ -675,6 +675,8 @@
-- Item definition defaults
--
+local default_stack_max = tonumber(minetest.settings:get("default_stack_max")) or 99
+
core.nodedef_default = {
-- Item properties
type="node",
@@ -684,7 +686,7 @@
inventory_image = "",
wield_image = "",
wield_scale = {x=1,y=1,z=1},
- stack_max = 99,
+ stack_max = default_stack_max,
usable = false,
liquids_pointable = false,
tool_capabilities = nil,
@@ -748,7 +750,7 @@
inventory_image = "",
wield_image = "",
wield_scale = {x=1,y=1,z=1},
- stack_max = 99,
+ stack_max = default_stack_max,
liquids_pointable = false,
tool_capabilities = nil,
@@ -786,7 +788,7 @@
inventory_image = "",
wield_image = "",
wield_scale = {x=1,y=1,z=1},
- stack_max = 99,
+ stack_max = default_stack_max,
liquids_pointable = false,
tool_capabilities = nil,
diff -Nru minetest-5.2.0/builtin/game/misc.lua minetest-5.3.0/builtin/game/misc.lua
--- minetest-5.2.0/builtin/game/misc.lua 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/builtin/game/misc.lua 2020-07-09 21:13:20.000000000 +0000
@@ -164,6 +164,12 @@
end
end
+-- To be overridden by Creative mods
+
+local creative_mode_cache = core.settings:get_bool("creative_mode")
+function core.is_creative_enabled(name)
+ return creative_mode_cache
+end
-- Checks if specified volume intersects a protected volume
diff -Nru minetest-5.2.0/builtin/game/register.lua minetest-5.3.0/builtin/game/register.lua
--- minetest-5.2.0/builtin/game/register.lua 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/builtin/game/register.lua 2020-07-09 21:13:20.000000000 +0000
@@ -607,9 +607,9 @@
core.registered_on_punchplayers, core.register_on_punchplayer = make_registration()
core.registered_on_priv_grant, core.register_on_priv_grant = make_registration()
core.registered_on_priv_revoke, core.register_on_priv_revoke = make_registration()
+core.registered_on_authplayers, core.register_on_authplayer = make_registration()
core.registered_can_bypass_userlimit, core.register_can_bypass_userlimit = make_registration()
core.registered_on_modchannel_message, core.register_on_modchannel_message = make_registration()
-core.registered_on_auth_fail, core.register_on_auth_fail = make_registration()
core.registered_on_player_inventory_actions, core.register_on_player_inventory_action = make_registration()
core.registered_allow_player_inventory_actions, core.register_allow_player_inventory_action = make_registration()
diff -Nru minetest-5.2.0/builtin/game/statbars.lua minetest-5.3.0/builtin/game/statbars.lua
--- minetest-5.2.0/builtin/game/statbars.lua 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/builtin/game/statbars.lua 2020-07-09 21:13:20.000000000 +0000
@@ -3,22 +3,26 @@
local health_bar_definition = {
hud_elem_type = "statbar",
- position = { x=0.5, y=1 },
+ position = {x = 0.5, y = 1},
text = "heart.png",
+ text2 = "heart_gone.png",
number = core.PLAYER_MAX_HP_DEFAULT,
+ item = core.PLAYER_MAX_HP_DEFAULT,
direction = 0,
- size = { x=24, y=24 },
- offset = { x=(-10*24)-25, y=-(48+24+16)},
+ size = {x = 24, y = 24},
+ offset = {x = (-10 * 24) - 25, y = -(48 + 24 + 16)},
}
local breath_bar_definition = {
hud_elem_type = "statbar",
- position = { x=0.5, y=1 },
+ position = {x = 0.5, y = 1},
text = "bubble.png",
+ text2 = "bubble_gone.png",
number = core.PLAYER_MAX_BREATH_DEFAULT,
+ item = core.PLAYER_MAX_BREATH_DEFAULT * 2,
direction = 0,
- size = { x=24, y=24 },
- offset = {x=25,y=-(48+24+16)},
+ size = {x = 24, y = 24},
+ offset = {x = 25, y= -(48 + 24 + 16)},
}
local hud_ids = {}
@@ -26,7 +30,7 @@
local function scaleToDefault(player, field)
-- Scale "hp" or "breath" to the default dimensions
local current = player["get_" .. field](player)
- local nominal = core["PLAYER_MAX_".. field:upper() .. "_DEFAULT"]
+ local nominal = core["PLAYER_MAX_" .. field:upper() .. "_DEFAULT"]
local max_display = math.max(nominal,
math.max(player:get_properties()[field .. "_max"], current))
return current / max_display * nominal
@@ -49,6 +53,7 @@
local hud = hud_ids[name]
local immortal = player:get_armor_groups().immortal == 1
+
if flags.healthbar and enable_damage and not immortal then
local number = scaleToDefault(player, "hp")
if hud.id_healthbar == nil then
@@ -63,19 +68,28 @@
hud.id_healthbar = nil
end
+ local show_breathbar = flags.breathbar and enable_damage and not immortal
+
+ local breath = player:get_breath()
local breath_max = player:get_properties().breath_max
- if flags.breathbar and enable_damage and not immortal and
- player:get_breath() < breath_max then
+ if show_breathbar and breath <= breath_max then
local number = 2 * scaleToDefault(player, "breath")
- if hud.id_breathbar == nil then
+ if not hud.id_breathbar and breath < breath_max then
local hud_def = table.copy(breath_bar_definition)
hud_def.number = number
hud.id_breathbar = player:hud_add(hud_def)
- else
+ elseif hud.id_breathbar then
player:hud_change(hud.id_breathbar, "number", number)
end
- elseif hud.id_breathbar then
- player:hud_remove(hud.id_breathbar)
+ end
+
+ if hud.id_breathbar and (not show_breathbar or breath == breath_max) then
+ minetest.after(1, function(player_name, breath_bar)
+ local player = minetest.get_player_by_name(player_name)
+ if player then
+ player:hud_remove(breath_bar)
+ end
+ end, name, hud.id_breathbar)
hud.id_breathbar = nil
end
end
diff -Nru minetest-5.2.0/builtin/init.lua minetest-5.3.0/builtin/init.lua
--- minetest-5.2.0/builtin/init.lua 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/builtin/init.lua 2020-07-09 21:13:20.000000000 +0000
@@ -36,6 +36,7 @@
if INIT == "game" then
dofile(gamepath .. "init.lua")
+ assert(not core.get_http_api)
elseif INIT == "mainmenu" then
local mm_script = core.settings:get("main_menu_script")
if mm_script and mm_script ~= "" then
diff -Nru minetest-5.2.0/builtin/mainmenu/async_event.lua minetest-5.3.0/builtin/mainmenu/async_event.lua
--- minetest-5.2.0/builtin/mainmenu/async_event.lua 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/builtin/mainmenu/async_event.lua 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,32 @@
+
+core.async_jobs = {}
+
+local function handle_job(jobid, serialized_retval)
+ local retval = core.deserialize(serialized_retval)
+ assert(type(core.async_jobs[jobid]) == "function")
+ core.async_jobs[jobid](retval)
+ core.async_jobs[jobid] = nil
+end
+
+core.async_event_handler = handle_job
+
+function core.handle_async(func, parameter, callback)
+ -- Serialize function
+ local serialized_func = string.dump(func)
+
+ assert(serialized_func ~= nil)
+
+ -- Serialize parameters
+ local serialized_param = core.serialize(parameter)
+
+ if serialized_param == nil then
+ return false
+ end
+
+ local jobid = core.do_async_callback(serialized_func, serialized_param)
+
+ core.async_jobs[jobid] = callback
+
+ return true
+end
+
diff -Nru minetest-5.2.0/builtin/mainmenu/dlg_config_world.lua minetest-5.3.0/builtin/mainmenu/dlg_config_world.lua
--- minetest-5.2.0/builtin/mainmenu/dlg_config_world.lua 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/builtin/mainmenu/dlg_config_world.lua 2020-07-09 21:13:20.000000000 +0000
@@ -23,7 +23,49 @@
return not name:find("[^a-z0-9_]")
end
+local function init_data(data)
+ data.list = filterlist.create(
+ pkgmgr.preparemodlist,
+ pkgmgr.comparemod,
+ function(element, uid)
+ if element.name == uid then
+ return true
+ end
+ end,
+ function(element, criteria)
+ if criteria.hide_game and
+ element.is_game_content then
+ return false
+ end
+
+ if criteria.hide_modpackcontents and
+ element.modpack ~= nil then
+ return false
+ end
+ return true
+ end,
+ {
+ worldpath = data.worldspec.path,
+ gameid = data.worldspec.gameid
+ })
+
+ if data.selected_mod > data.list:size() then
+ data.selected_mod = 0
+ end
+
+ data.list:set_filtercriteria({
+ hide_game = data.hide_gamemods,
+ hide_modpackcontents = data.hide_modpackcontents
+ })
+ data.list:add_sort_mechanism("alphabetic", sort_mod_list)
+ data.list:set_sortmode("alphabetic")
+end
+
local function get_formspec(data)
+ if not data.list then
+ init_data(data)
+ end
+
local mod = data.list:get_list()[data.selected_mod] or {name = ""}
local retval =
@@ -85,11 +127,14 @@
end
end
end
+
retval = retval ..
"button[3.25,7;2.5,0.5;btn_config_world_save;" ..
fgettext("Save") .. "]" ..
"button[5.75,7;2.5,0.5;btn_config_world_cancel;" ..
- fgettext("Cancel") .. "]"
+ fgettext("Cancel") .. "]" ..
+ "button[9,7;2.5,0.5;btn_config_world_cdb;" ..
+ fgettext("Find More Mods") .. "]"
if mod.name ~= "" and not mod.is_game_content then
if mod.is_modpack then
@@ -198,6 +243,16 @@
return true
end
+ if fields.btn_config_world_cdb then
+ this.data.list = nil
+
+ local dlg = create_store_dlg("mod")
+ dlg:set_parent(this)
+ this:hide()
+ dlg:show()
+ return true
+ end
+
if fields.btn_enable_all_mods then
local list = this.data.list:get_raw_list()
@@ -247,43 +302,5 @@
return
end
- dlg.data.list = filterlist.create(
- pkgmgr.preparemodlist,
- pkgmgr.comparemod,
- function(element, uid)
- if element.name == uid then
- return true
- end
- end,
- function(element, criteria)
- if criteria.hide_game and
- element.is_game_content then
- return false
- end
-
- if criteria.hide_modpackcontents and
- element.modpack ~= nil then
- return false
- end
- return true
- end,
- {
- worldpath = dlg.data.worldspec.path,
- gameid = dlg.data.worldspec.gameid
- }
- )
-
-
- if dlg.data.selected_mod > dlg.data.list:size() then
- dlg.data.selected_mod = 0
- end
-
- dlg.data.list:set_filtercriteria({
- hide_game = dlg.data.hide_gamemods,
- hide_modpackcontents = dlg.data.hide_modpackcontents
- })
- dlg.data.list:add_sort_mechanism("alphabetic", sort_mod_list)
- dlg.data.list:set_sortmode("alphabetic")
-
return dlg
end
diff -Nru minetest-5.2.0/builtin/mainmenu/dlg_contentstore.lua minetest-5.3.0/builtin/mainmenu/dlg_contentstore.lua
--- minetest-5.2.0/builtin/mainmenu/dlg_contentstore.lua 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/builtin/mainmenu/dlg_contentstore.lua 2020-07-09 21:13:20.000000000 +0000
@@ -1,5 +1,5 @@
--Minetest
---Copyright (C) 2018 rubenwardy
+--Copyright (C) 2018-20 rubenwardy
--
--This program is free software; you can redistribute it and/or modify
--it under the terms of the GNU Lesser General Public License as published by
@@ -15,8 +15,17 @@
--with this program; if not, write to the Free Software Foundation, Inc.,
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+if not minetest.get_http_api then
+ function create_store_dlg()
+ return messagebox("store",
+ fgettext("ContentDB is not available when Minetest was compiled without cURL"))
+ end
+ return
+end
+
local store = { packages = {}, packages_full = {} }
-local package_dialog = {}
+
+local http = minetest.get_http_api()
-- Screenshot
local screenshot_dir = core.get_cache_path() .. DIR_DELIM .. "cdb"
@@ -44,19 +53,15 @@
}
-
-
local function download_package(param)
if core.download_file(param.package.url, param.filename) then
return {
- package = param.package,
filename = param.filename,
successful = true,
}
else
core.log("error", "downloading " .. dump(param.package.url) .. " failed")
return {
- package = param.package,
successful = false,
}
end
@@ -70,9 +75,9 @@
local function callback(result)
if result.successful then
- local path, msg = pkgmgr.install(result.package.type,
- result.filename, result.package.name,
- result.package.path)
+ local path, msg = pkgmgr.install(package.type,
+ result.filename, package.name,
+ package.path)
if not path then
gamedata.errormessage = msg
else
@@ -80,33 +85,33 @@
local conf_path
local name_is_title = false
- if result.package.type == "mod" then
+ if package.type == "mod" then
local actual_type = pkgmgr.get_folder_type(path)
if actual_type.type == "modpack" then
conf_path = path .. DIR_DELIM .. "modpack.conf"
else
conf_path = path .. DIR_DELIM .. "mod.conf"
end
- elseif result.package.type == "game" then
+ elseif package.type == "game" then
conf_path = path .. DIR_DELIM .. "game.conf"
name_is_title = true
- elseif result.package.type == "txp" then
+ elseif package.type == "txp" then
conf_path = path .. DIR_DELIM .. "texture_pack.conf"
end
if conf_path then
local conf = Settings(conf_path)
if name_is_title then
- conf:set("name", result.package.title)
+ conf:set("name", package.title)
else
- conf:set("title", result.package.title)
- conf:set("name", result.package.name)
+ conf:set("title", package.title)
+ conf:set("name", package.name)
end
if not conf:get("description") then
- conf:set("description", result.package.short_description)
+ conf:set("description", package.short_description)
end
- conf:set("author", result.package.author)
- conf:set("release", result.package.release)
+ conf:set("author", package.author)
+ conf:set("release", package.release)
conf:write()
end
end
@@ -115,37 +120,22 @@
gamedata.errormessage = fgettext("Failed to download $1", package.name)
end
- if gamedata.errormessage == nil then
- core.button_handler({btn_hidden_close_download=result})
- else
- core.button_handler({btn_hidden_close_download={successful=false}})
- end
+ package.downloading = false
+ ui.update()
end
+ package.downloading = true
+
if not core.handle_async(download_package, params, callback) then
core.log("error", "ERROR: async event failed")
gamedata.errormessage = fgettext("Failed to download $1", package.name)
+ return
end
+end
- local new_dlg = dialog_create("store_downloading",
- function(data)
- return "size[7,2]label[0.25,0.75;" ..
- fgettext("Downloading and installing $1, please wait...", data.title) .. "]"
- end,
- function(this,fields)
- if fields["btn_hidden_close_download"] ~= nil then
- this:delete()
- return true
- end
-
- return false
- end,
- nil)
-
- new_dlg:set_parent(calling_dialog)
- new_dlg.data.title = package.title
- calling_dialog:hide()
- new_dlg:show()
+local function get_file_extension(path)
+ local parts = path:split(".")
+ return parts[#parts]
end
local function get_screenshot(package)
@@ -156,8 +146,9 @@
end
-- Get tmp screenshot path
+ local ext = get_file_extension(package.thumbnail)
local filepath = screenshot_dir .. DIR_DELIM ..
- package.type .. "-" .. package.author .. "-" .. package.name .. ".png"
+ ("%s-%s-%s.%s"):format(package.type, package.author, package.name, ext)
-- Return if already downloaded
local file = io.open(filepath, "r")
@@ -195,84 +186,12 @@
return defaulttexturedir .. "loading_screenshot.png"
end
-
-
-function package_dialog.get_formspec()
- local package = package_dialog.package
-
- store.update_paths()
-
- local formspec = {
- "size[9,4;true]",
- "image[0,1;4.5,3;", core.formspec_escape(get_screenshot(package)), ']',
- "label[3.8,1;",
- minetest.colorize(mt_color_green, core.formspec_escape(package.title)), "\n",
- minetest.colorize('#BFBFBF', "by " .. core.formspec_escape(package.author)), "]",
- "textarea[4,2;5.3,2;;;", core.formspec_escape(package.short_description), "]",
- "button[0,0;2,1;back;", fgettext("Back"), "]",
- }
-
- if not package.path then
- formspec[#formspec + 1] = "button[7,0;2,1;install;"
- formspec[#formspec + 1] = fgettext("Install")
- formspec[#formspec + 1] = "]"
- elseif package.installed_release < package.release then
- -- The install_ action also handles updating
- formspec[#formspec + 1] = "button[7,0;2,1;install;"
- formspec[#formspec + 1] = fgettext("Update")
- formspec[#formspec + 1] = "]"
- formspec[#formspec + 1] = "button[5,0;2,1;uninstall;"
- formspec[#formspec + 1] = fgettext("Uninstall")
- formspec[#formspec + 1] = "]"
- else
- formspec[#formspec + 1] = "button[7,0;2,1;uninstall;"
- formspec[#formspec + 1] = fgettext("Uninstall")
- formspec[#formspec + 1] = "]"
- end
-
- return table.concat(formspec, "")
-end
-
-function package_dialog.handle_submit(this, fields)
- if fields.back then
- this:delete()
- return true
- end
-
- if fields.install then
- start_install(this, package_dialog.package)
- return true
- end
-
- if fields.uninstall then
- local dlg_delmod = create_delete_content_dlg(package_dialog.package)
- dlg_delmod:set_parent(this)
- this:hide()
- dlg_delmod:show()
- return true
- end
-
- return false
-end
-
-function package_dialog.create(package)
- package_dialog.package = package
- return dialog_create("package_view",
- package_dialog.get_formspec,
- package_dialog.handle_submit,
- nil)
-end
-
function store.load()
- local tmpdir = os.tempfolder()
- local target = tmpdir .. DIR_DELIM .. "packages.json"
-
- assert(core.create_dir(tmpdir))
-
- local base_url = core.settings:get("contentdb_url")
+ local version = core.get_version()
+ local base_url = core.settings:get("contentdb_url")
local url = base_url ..
"/api/packages/?type=mod&type=game&type=txp&protocol_version=" ..
- core.get_max_supp_proto()
+ core.get_max_supp_proto() .. "&engine_version=" .. version.string
for _, item in pairs(core.settings:get("contentdb_flag_blacklist"):split(",")) do
item = item:trim()
@@ -281,31 +200,29 @@
end
end
- core.download_file(url, target)
+ local timeout = tonumber(minetest.settings:get("curl_file_download_timeout"))
+ local response = http.fetch_sync({ url = url, timeout = timeout })
+ if not response.succeeded then
+ return
+ end
- local file = io.open(target, "r")
- if file then
- store.packages_full = core.parse_json(file:read("*all")) or {}
- file:close()
+ store.packages_full = core.parse_json(response.data) or {}
- for _, package in pairs(store.packages_full) do
- package.url = base_url .. "/packages/" ..
+ for _, package in pairs(store.packages_full) do
+ package.url = base_url .. "/packages/" ..
package.author .. "/" .. package.name ..
"/releases/" .. package.release .. "/download/"
- local name_len = #package.name
- if package.type == "game" and name_len > 5 and package.name:sub(name_len - 4) == "_game" then
- package.id = package.author:lower() .. "/" .. package.name:sub(1, name_len - 5)
- else
- package.id = package.author:lower() .. "/" .. package.name
- end
+ local name_len = #package.name
+ if package.type == "game" and name_len > 5 and package.name:sub(name_len - 4) == "_game" then
+ package.id = package.author:lower() .. "/" .. package.name:sub(1, name_len - 5)
+ else
+ package.id = package.author:lower() .. "/" .. package.name
end
-
- store.packages = store.packages_full
- store.loaded = true
end
- core.delete_dir(tmpdir)
+ store.packages = store.packages_full
+ store.loaded = true
end
function store.update_paths()
@@ -395,34 +312,35 @@
cur_page = 1
end
+ local W = 15.75
+ local H = 9.5
+
local formspec
if #store.packages_full > 0 then
formspec = {
- "size[12,7;true]",
+ "formspec_version[3]",
+ "size[15.75,9.5]",
"position[0.5,0.55]",
- "field[0.2,0.1;7.8,1;search_string;;",
- core.formspec_escape(search_string), "]",
+ "container[0.375,0.375]",
+ "field[0,0;10.225,0.8;search_string;;", core.formspec_escape(search_string), "]",
"field_close_on_enter[search_string;false]",
- "button[7.7,-0.2;2,1;search;",
- fgettext("Search"), "]",
- "dropdown[9.7,-0.1;2.4;type;",
- table.concat(filter_types_titles, ","),
- ";", filter_type, "]",
- -- "textlist[0,1;2.4,5.6;a;",
- -- table.concat(taglist, ","), "]",
+ "button[10.225,0;2,0.8;search;", fgettext("Search"), "]",
+ "dropdown[12.6,0;2.4,0.8;type;", table.concat(filter_types_titles, ","), ";", filter_type, "]",
+ "container_end[]",
-- Page nav buttons
- "container[0,",
- num_per_page + 1.5, "]",
- "button[-0.1,0;3,1;back;",
- fgettext("Back to Main Menu"), "]",
- "button[7.1,0;1,1;pstart;<<]",
- "button[8.1,0;1,1;pback;<]",
- "label[9.2,0.2;",
- tonumber(cur_page), " / ",
- tonumber(dlgdata.pagemax), "]",
- "button[10.1,0;1,1;pnext;>]",
- "button[11.1,0;1,1;pend;>>]",
+ "container[0,", H - 0.8 - 0.375, "]",
+ "button[0.375,0;4,0.8;back;", fgettext("Back to Main Menu"), "]",
+
+ "container[", W - 0.375 - 0.8*4 - 2, ",0]",
+ "image_button[0,0;0.8,0.8;", core.formspec_escape(defaulttexturedir), "start_icon.png;pstart;]",
+ "image_button[0.8,0;0.8,0.8;", core.formspec_escape(defaulttexturedir), "prev_icon.png;pback;]",
+ "style[pagenum;border=false]",
+ "button[1.6,0;2,0.8;pagenum;", tonumber(cur_page), " / ", tonumber(dlgdata.pagemax), "]",
+ "image_button[3.6,0;0.8,0.8;", core.formspec_escape(defaulttexturedir), "next_icon.png;pnext;]",
+ "image_button[4.4,0;0.8,0.8;", core.formspec_escape(defaulttexturedir), "end_icon.png;pend;]",
+ "container_end[]",
+
"container_end[]",
}
@@ -433,73 +351,84 @@
end
else
formspec = {
- "size[12,7;true]",
+ "size[12,7]",
"position[0.5,0.55]",
"label[4,3;", fgettext("No packages could be retrieved"), "]",
- "button[-0.1,",
- num_per_page + 1.5,
- ";3,1;back;",
- fgettext("Back to Main Menu"), "]",
+ "container[0,", H - 0.8 - 0.375, "]",
+ "button[0,0;4,0.8;back;", fgettext("Back to Main Menu"), "]",
+ "container_end[]",
}
end
local start_idx = (cur_page - 1) * num_per_page + 1
for i=start_idx, math.min(#store.packages, start_idx+num_per_page-1) do
local package = store.packages[i]
- formspec[#formspec + 1] = "container[0.5,"
- formspec[#formspec + 1] = (i - start_idx) * 1.1 + 1
+ formspec[#formspec + 1] = "container[0.375,"
+ formspec[#formspec + 1] = (i - start_idx) * 1.375 + (2*0.375 + 0.8)
formspec[#formspec + 1] = "]"
-- image
- formspec[#formspec + 1] = "image[-0.4,0;1.5,1;"
+ formspec[#formspec + 1] = "image[0,0;1.5,1;"
formspec[#formspec + 1] = core.formspec_escape(get_screenshot(package))
formspec[#formspec + 1] = "]"
-- title
- formspec[#formspec + 1] = "label[1,-0.1;"
+ formspec[#formspec + 1] = "label[1.875,0.1;"
formspec[#formspec + 1] = core.formspec_escape(
minetest.colorize(mt_color_green, package.title) ..
minetest.colorize("#BFBFBF", " by " .. package.author))
formspec[#formspec + 1] = "]"
- -- description
- if package.path and package.installed_release < package.release then
- formspec[#formspec + 1] = "textarea[1.25,0.3;7.5,1;;;"
- else
- formspec[#formspec + 1] = "textarea[1.25,0.3;9,1;;;"
- end
- formspec[#formspec + 1] = core.formspec_escape(package.short_description)
- formspec[#formspec + 1] = "]"
-
-- buttons
- if not package.path then
- formspec[#formspec + 1] = "button[9.9,0;1.5,1;install_"
+ local description_width = W - 0.375*5 - 1 - 2*1.5
+ formspec[#formspec + 1] = "container["
+ formspec[#formspec + 1] = W - 0.375*2
+ formspec[#formspec + 1] = ",0.1]"
+
+ if package.downloading then
+ formspec[#formspec + 1] = "style[download;border=false]"
+
+ formspec[#formspec + 1] = "button[-3.5,0;2,0.8;download;"
+ formspec[#formspec + 1] = fgettext("Downloading...")
+ formspec[#formspec + 1] = "]"
+ elseif not package.path then
+ formspec[#formspec + 1] = "button[-3,0;1.5,0.8;install_"
formspec[#formspec + 1] = tostring(i)
formspec[#formspec + 1] = ";"
formspec[#formspec + 1] = fgettext("Install")
formspec[#formspec + 1] = "]"
else
if package.installed_release < package.release then
+ description_width = description_width - 1.5
+
-- The install_ action also handles updating
- formspec[#formspec + 1] = "button[8.4,0;1.5,1;install_"
+ formspec[#formspec + 1] = "button[-4.5,0;1.5,0.8;install_"
formspec[#formspec + 1] = tostring(i)
formspec[#formspec + 1] = ";"
formspec[#formspec + 1] = fgettext("Update")
formspec[#formspec + 1] = "]"
end
- formspec[#formspec + 1] = "button[9.9,0;1.5,1;uninstall_"
+ formspec[#formspec + 1] = "button[-3,0;1.5,0.8;uninstall_"
formspec[#formspec + 1] = tostring(i)
formspec[#formspec + 1] = ";"
formspec[#formspec + 1] = fgettext("Uninstall")
formspec[#formspec + 1] = "]"
end
- --formspec[#formspec + 1] = "button[9.9,0;1.5,1;view_"
- --formspec[#formspec + 1] = tostring(i)
- --formspec[#formspec + 1] = ";"
- --formspec[#formspec + 1] = fgettext("View")
- --formspec[#formspec + 1] = "]"
+ formspec[#formspec + 1] = "button[-1.5,0;1.5,0.8;view_"
+ formspec[#formspec + 1] = tostring(i)
+ formspec[#formspec + 1] = ";"
+ formspec[#formspec + 1] = fgettext("View")
+ formspec[#formspec + 1] = "]"
+ formspec[#formspec + 1] = "container_end[]"
+
+ -- description
+ formspec[#formspec + 1] = "textarea[1.855,0.3;"
+ formspec[#formspec + 1] = tostring(description_width)
+ formspec[#formspec + 1] = ",0.8;;;"
+ formspec[#formspec + 1] = core.formspec_escape(package.short_description)
+ formspec[#formspec + 1] = "]"
formspec[#formspec + 1] = "container_end[]"
end
@@ -576,10 +505,9 @@
end
if fields["view_" .. i] then
- local dlg = package_dialog.create(package)
- dlg:set_parent(this)
- this:hide()
- dlg:show()
+ local url = ("%s/packages/%s?protocol_version=%d"):format(
+ core.settings:get("contentdb_url"), package.id, core.get_max_supp_proto())
+ core.open_url(url)
return true
end
end
@@ -594,6 +522,17 @@
search_string = ""
cur_page = 1
+
+ if type then
+ -- table.indexof does not work on tables that contain `nil`
+ for i, v in pairs(filter_types_type) do
+ if v == type then
+ filter_type = i
+ break
+ end
+ end
+ end
+
store.filter_packages(search_string)
return dialog_create("store",
diff -Nru minetest-5.2.0/builtin/mainmenu/dlg_create_world.lua minetest-5.3.0/builtin/mainmenu/dlg_create_world.lua
--- minetest-5.2.0/builtin/mainmenu/dlg_create_world.lua 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/builtin/mainmenu/dlg_create_world.lua 2020-07-09 21:13:20.000000000 +0000
@@ -17,13 +17,110 @@
local worldname = ""
+local function table_to_flags(ftable)
+ -- Convert e.g. { jungles = true, caves = false } to "jungles,nocaves"
+ local str = {}
+ for flag, is_set in pairs(ftable) do
+ str[#str + 1] = is_set and flag or ("no" .. flag)
+ end
+ return table.concat(str, ",")
+end
+
+-- Same as check_flag but returns a string
+local function strflag(flags, flag)
+ return (flags[flag] == true) and "true" or "false"
+end
+
+local cb_caverns = { "caverns", fgettext("Caverns"), "caverns",
+ fgettext("Very large caverns deep in the underground") }
+local tt_sea_rivers = fgettext("Sea level rivers")
+
+local flag_checkboxes = {
+ v5 = {
+ cb_caverns,
+ },
+ v7 = {
+ cb_caverns,
+ { "ridges", fgettext("Rivers"), "ridges", tt_sea_rivers },
+ { "mountains", fgettext("Mountains"), "mountains" },
+ { "floatlands", fgettext("Floatlands (experimental)"), "floatlands",
+ fgettext("Floating landmasses in the sky") },
+ },
+ carpathian = {
+ cb_caverns,
+ { "rivers", fgettext("Rivers"), "rivers", tt_sea_rivers },
+ },
+ valleys = {
+ { "altitude-chill", fgettext("Altitude chill"), "altitude_chill",
+ fgettext("Reduces heat with altitude") },
+ { "altitude-dry", fgettext("Altitude dry"), "altitude_dry",
+ fgettext("Reduces humidity with altitude") },
+ { "humid-rivers", fgettext("Humid rivers"), "humid_rivers",
+ fgettext("Increases humidity around rivers") },
+ { "vary-river-depth", fgettext("Vary river depth"), "vary_river_depth",
+ fgettext("Low humidity and high heat causes shallow or dry rivers") },
+ },
+ flat = {
+ { "hills", fgettext("Hills"), "hills" },
+ { "lakes", fgettext("Lakes"), "lakes" },
+ },
+ fractal = {
+ { "terrain", fgettext("Additional terrain"), "terrain",
+ fgettext("Generate non-fractal terrain: Oceans and underground") },
+ },
+ v6 = {
+ { "trees", fgettext("Trees and jungle grass"), "trees" },
+ { "flat", fgettext("Flat terrain"), "flat" },
+ { "mudflow", fgettext("Mud flow"), "mudflow",
+ fgettext("Terrain surface erosion") },
+ -- Biome settings are in mgv6_biomes below
+ },
+}
+
+local mgv6_biomes = {
+ {
+ fgettext("Temperate, Desert, Jungle, Tundra, Taiga"),
+ {jungles = true, snowbiomes = true}
+ },
+ {
+ fgettext("Temperate, Desert, Jungle"),
+ {jungles = true, snowbiomes = false}
+ },
+ {
+ fgettext("Temperate, Desert"),
+ {jungles = false, snowbiomes = false}
+ },
+}
+
local function create_world_formspec(dialogdata)
+
+ -- Error out when no games found
+ if #pkgmgr.games == 0 then
+ return "size[12.25,3,true]" ..
+ "box[0,0;12,2;#ff8800]" ..
+ "textarea[0.3,0;11.7,2;;;"..
+ fgettext("You have no games installed.") .. "\n" ..
+ fgettext("Download one from minetest.net") .. "]" ..
+ "button[4.75,2.5;3,0.5;world_create_cancel;" .. fgettext("Cancel") .. "]"
+ end
+
local mapgens = core.get_mapgen_names()
local current_seed = core.settings:get("fixed_map_seed") or ""
local current_mg = core.settings:get("mg_name")
local gameid = core.settings:get("menu_last_game")
+ local flags = {
+ main = core.settings:get_flags("mg_flags"),
+ v5 = core.settings:get_flags("mgv5_spflags"),
+ v6 = core.settings:get_flags("mgv6_spflags"),
+ v7 = core.settings:get_flags("mgv7_spflags"),
+ fractal = core.settings:get_flags("mgfractal_spflags"),
+ carpathian = core.settings:get_flags("mgcarpathian_spflags"),
+ valleys = core.settings:get_flags("mgvalleys_spflags"),
+ flat = core.settings:get_flags("mgflat_spflags"),
+ }
+
local gameidx = 0
if gameid ~= nil then
local _
@@ -35,15 +132,29 @@
end
local game_by_gameidx = core.get_game(gameidx)
+ local disallowed_mapgen_settings = {}
if game_by_gameidx ~= nil then
local gamepath = game_by_gameidx.path
local gameconfig = Settings(gamepath.."/game.conf")
+ local allowed_mapgens = (gameconfig:get("allowed_mapgens") or ""):split()
+ for key, value in pairs(allowed_mapgens) do
+ allowed_mapgens[key] = value:trim()
+ end
+
local disallowed_mapgens = (gameconfig:get("disallowed_mapgens") or ""):split()
for key, value in pairs(disallowed_mapgens) do
disallowed_mapgens[key] = value:trim()
end
+ if #allowed_mapgens > 0 then
+ for i = #mapgens, 1, -1 do
+ if table.indexof(allowed_mapgens, mapgens[i]) == -1 then
+ table.remove(mapgens, i)
+ end
+ end
+ end
+
if disallowed_mapgens then
for i = #mapgens, 1, -1 do
if table.indexof(disallowed_mapgens, mapgens[i]) > 0 then
@@ -51,49 +162,193 @@
end
end
end
+
+ local ds = (gameconfig:get("disallowed_mapgen_settings") or ""):split()
+ for _, value in pairs(ds) do
+ disallowed_mapgen_settings[value:trim()] = true
+ end
end
local mglist = ""
- local selindex = 1
+ local selindex
local i = 1
+ local first_mg
for k,v in pairs(mapgens) do
+ if not first_mg then
+ first_mg = v
+ end
if current_mg == v then
selindex = i
end
i = i + 1
mglist = mglist .. v .. ","
end
+ if not selindex then
+ selindex = 1
+ current_mg = first_mg
+ end
mglist = mglist:sub(1, -2)
+ local mg_main_flags = function(mapgen, y)
+ if mapgen == "singlenode" then
+ return "", y
+ end
+ if disallowed_mapgen_settings["mg_flags"] then
+ return "", y
+ end
+
+ local form = "checkbox[0," .. y .. ";flag_mg_caves;" ..
+ fgettext("Caves") .. ";"..strflag(flags.main, "caves").."]"
+ y = y + 0.5
+
+ form = form .. "checkbox[0,"..y..";flag_mg_dungeons;" ..
+ fgettext("Dungeons") .. ";"..strflag(flags.main, "dungeons").."]"
+ y = y + 0.5
+
+ local d_name = fgettext("Decorations")
+ local d_tt
+ if mapgen == "v6" then
+ d_tt = fgettext("Structures appearing on the terrain (no effect on trees and jungle grass created by v6)")
+ else
+ d_tt = fgettext("Structures appearing on the terrain, typically trees and plants")
+ end
+ form = form .. "checkbox[0,"..y..";flag_mg_decorations;" ..
+ d_name .. ";" ..
+ strflag(flags.main, "decorations").."]" ..
+ "tooltip[flag_mg_decorations;" ..
+ d_tt ..
+ "]"
+ y = y + 0.5
+
+ form = form .. "tooltip[flag_mg_caves;" ..
+ fgettext("Network of tunnels and caves")
+ .. "]"
+ return form, y
+ end
+
+ local mg_specific_flags = function(mapgen, y)
+ if not flag_checkboxes[mapgen] then
+ return "", y
+ end
+ if disallowed_mapgen_settings["mg"..mapgen.."_spflags"] then
+ return "", y
+ end
+ local form = ""
+ for _,tab in pairs(flag_checkboxes[mapgen]) do
+ local id = "flag_mg"..mapgen.."_"..tab[1]
+ form = form .. ("checkbox[0,%f;%s;%s;%s]"):
+ format(y, id, tab[2], strflag(flags[mapgen], tab[3]))
+
+ if tab[4] then
+ form = form .. "tooltip["..id..";"..tab[4].."]"
+ end
+ y = y + 0.5
+ end
+
+ if mapgen ~= "v6" then
+ -- No special treatment
+ return form, y
+ end
+ -- Special treatment for v6 (add biome widgets)
+
+ -- Biome type (jungles, snowbiomes)
+ local biometype
+ if flags.v6.snowbiomes == true then
+ biometype = 1
+ elseif flags.v6.jungles == true then
+ biometype = 2
+ else
+ biometype = 3
+ end
+ y = y + 0.3
+
+ form = form .. "label[0,"..(y+0.1)..";" .. fgettext("Biomes") .. "]"
+ y = y + 0.6
+
+ form = form .. "dropdown[0,"..y..";6.3;mgv6_biomes;"
+ for b=1, #mgv6_biomes do
+ form = form .. mgv6_biomes[b][1]
+ if b < #mgv6_biomes then
+ form = form .. ","
+ end
+ end
+ form = form .. ";" .. biometype.. "]"
+
+ -- biomeblend
+ y = y + 0.55
+ form = form .. "checkbox[0,"..y..";flag_mgv6_biomeblend;" ..
+ fgettext("Biome blending") .. ";"..strflag(flags.v6, "biomeblend").."]" ..
+ "tooltip[flag_mgv6_biomeblend;" ..
+ fgettext("Smooth transition between biomes") .. "]"
+
+ return form, y
+ end
+
current_seed = core.formspec_escape(current_seed)
- local retval =
- "size[11.5,6.5,true]" ..
- "label[2,0;" .. fgettext("World name") .. "]"..
- "field[4.5,0.4;6,0.5;te_world_name;;" .. minetest.formspec_escape(worldname) .. "]" ..
-
- "label[2,1;" .. fgettext("Seed") .. "]"..
- "field[4.5,1.4;6,0.5;te_seed;;".. current_seed .. "]" ..
-
- "label[2,2;" .. fgettext("Mapgen") .. "]"..
- "dropdown[4.2,2;6.3;dd_mapgen;" .. mglist .. ";" .. selindex .. "]" ..
-
- "label[2,3;" .. fgettext("Game") .. "]"..
- "textlist[4.2,3;5.8,2.3;games;" .. pkgmgr.gamelist() ..
- ";" .. gameidx .. ";true]" ..
- "button[3.25,6;2.5,0.5;world_create_confirm;" .. fgettext("Create") .. "]" ..
- "button[5.75,6;2.5,0.5;world_create_cancel;" .. fgettext("Cancel") .. "]"
+ local y_start = 0.0
+ local y = y_start
+ local str_flags, str_spflags
+ local label_flags, label_spflags = "", ""
+ y = y + 0.3
+ str_flags, y = mg_main_flags(current_mg, y)
+ if str_flags ~= "" then
+ label_flags = "label[0,"..y_start..";" .. fgettext("Mapgen flags") .. "]"
+ y_start = y + 0.4
+ else
+ y_start = 0.0
+ end
+ y = y_start + 0.3
+ str_spflags = mg_specific_flags(current_mg, y)
+ if str_spflags ~= "" then
+ label_spflags = "label[0,"..y_start..";" .. fgettext("Mapgen-specific flags") .. "]"
+ end
- if #pkgmgr.games == 0 then
- retval = retval .. "box[2,4;8,1;#ff8800]label[2.25,4;" ..
- fgettext("You have no games installed.") .. "]label[2.25,4.4;" ..
- fgettext("Download one from minetest.net") .. "]"
- elseif #pkgmgr.games == 1 and pkgmgr.games[1].id == "minimal" then
- retval = retval .. "box[1.75,4;8.7,1;#ff8800]label[2,4;" ..
- fgettext("Warning: The minimal development test is meant for developers.") .. "]label[2,4.4;" ..
+ -- Warning if only devtest is installed
+ local devtest_only = ""
+ local gamelist_height = 2.3
+ if #pkgmgr.games == 1 and pkgmgr.games[1].id == "devtest" then
+ devtest_only = "box[0,0;5.8,1.7;#ff8800]" ..
+ "textarea[0.3,0;6,1.8;;;"..
+ fgettext("Warning: The Development Test is meant for developers.") .. "\n" ..
fgettext("Download a game, such as Minetest Game, from minetest.net") .. "]"
+ gamelist_height = 0.5
end
+ local retval =
+ "size[12.25,7,true]" ..
+
+ -- Left side
+ "container[0,0]"..
+ "field[0.3,0.6;6,0.5;te_world_name;" ..
+ fgettext("World name") ..
+ ";" .. core.formspec_escape(worldname) .. "]" ..
+
+ "field[0.3,1.7;6,0.5;te_seed;" ..
+ fgettext("Seed") ..
+ ";".. current_seed .. "]" ..
+
+ "label[0,2;" .. fgettext("Mapgen") .. "]"..
+ "dropdown[0,2.5;6.3;dd_mapgen;" .. mglist .. ";" .. selindex .. "]" ..
+
+ "label[0,3.35;" .. fgettext("Game") .. "]"..
+ "textlist[0,3.85;5.8,"..gamelist_height..";games;" ..
+ pkgmgr.gamelist() .. ";" .. gameidx .. ";false]" ..
+ "container[0,4.5]" ..
+ devtest_only ..
+ "container_end[]" ..
+ "container_end[]" ..
+
+ -- Right side
+ "container[6.2,0]"..
+ label_flags .. str_flags ..
+ label_spflags .. str_spflags ..
+ "container_end[]"..
+
+ -- Menu buttons
+ "button[3.25,6.5;3,0.5;world_create_confirm;" .. fgettext("Create") .. "]" ..
+ "button[6.25,6.5;3,0.5;world_create_cancel;" .. fgettext("Cancel") .. "]"
+
return retval
end
@@ -150,11 +405,53 @@
return true
end
+ for k,v in pairs(fields) do
+ local split = string.split(k, "_", nil, 3)
+ if split and split[1] == "flag" then
+ local setting
+ if split[2] == "mg" then
+ setting = "mg_flags"
+ else
+ setting = split[2].."_spflags"
+ end
+ -- We replaced the underscore of flag names with a dash.
+ local flag = string.gsub(split[3], "-", "_")
+ local ftable = core.settings:get_flags(setting)
+ if v == "true" then
+ ftable[flag] = true
+ else
+ ftable[flag] = false
+ end
+ local flags = table_to_flags(ftable)
+ core.settings:set(setting, flags)
+ return true
+ end
+ end
+
if fields["world_create_cancel"] then
this:delete()
return true
end
+ if fields["mgv6_biomes"] then
+ local entry = minetest.formspec_escape(fields["mgv6_biomes"])
+ for b=1, #mgv6_biomes do
+ if entry == mgv6_biomes[b][1] then
+ local ftable = core.settings:get_flags("mgv6_spflags")
+ ftable.jungles = mgv6_biomes[b][2].jungles
+ ftable.snowbiomes = mgv6_biomes[b][2].snowbiomes
+ local flags = table_to_flags(ftable)
+ core.settings:set("mgv6_spflags", flags)
+ return true
+ end
+ end
+ end
+
+ if fields["dd_mapgen"] then
+ core.settings:set("mg_name", fields["dd_mapgen"])
+ return true
+ end
+
return false
end
diff -Nru minetest-5.2.0/builtin/mainmenu/init.lua minetest-5.3.0/builtin/mainmenu/init.lua
--- minetest-5.2.0/builtin/mainmenu/init.lua 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/builtin/mainmenu/init.lua 2020-07-09 21:13:20.000000000 +0000
@@ -20,20 +20,18 @@
mt_color_green = "#72FF63"
mt_color_dark_green = "#25C191"
---for all other colors ask sfan5 to complete his work!
-
local menupath = core.get_mainmenu_path()
local basepath = core.get_builtin_path()
local menustyle = core.settings:get("main_menu_style")
defaulttexturedir = core.get_texturepath_share() .. DIR_DELIM .. "base" ..
DIR_DELIM .. "pack" .. DIR_DELIM
-dofile(basepath .. "common" .. DIR_DELIM .. "async_event.lua")
dofile(basepath .. "common" .. DIR_DELIM .. "filterlist.lua")
dofile(basepath .. "fstk" .. DIR_DELIM .. "buttonbar.lua")
dofile(basepath .. "fstk" .. DIR_DELIM .. "dialog.lua")
dofile(basepath .. "fstk" .. DIR_DELIM .. "tabview.lua")
dofile(basepath .. "fstk" .. DIR_DELIM .. "ui.lua")
+dofile(menupath .. DIR_DELIM .. "async_event.lua")
dofile(menupath .. DIR_DELIM .. "common.lua")
dofile(menupath .. DIR_DELIM .. "pkgmgr.lua")
dofile(menupath .. DIR_DELIM .. "textures.lua")
diff -Nru minetest-5.2.0/builtin/mainmenu/tab_credits.lua minetest-5.3.0/builtin/mainmenu/tab_credits.lua
--- minetest-5.2.0/builtin/mainmenu/tab_credits.lua 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/builtin/mainmenu/tab_credits.lua 2020-07-09 21:13:20.000000000 +0000
@@ -101,8 +101,8 @@
local logofile = defaulttexturedir .. "logo.png"
local version = core.get_version()
return "image[0.5,1;" .. core.formspec_escape(logofile) .. "]" ..
- "label[0.5,3.2;" .. version.project .. " " .. version.string .. "]" ..
- "label[0.5,3.5;http://minetest.net]" ..
+ "label[0.5,2.8;" .. version.project .. " " .. version.string .. "]" ..
+ "button[0.5,3;2,2;homepage;minetest.net]" ..
"tablecolumns[color;text]" ..
"tableoptions[background=#00000000;highlight=#00000000;border=false]" ..
"table[3.5,-0.25;8.5,6.05;list_credits;" ..
@@ -115,5 +115,10 @@
"#FFFF00," .. fgettext("Previous Contributors") .. ",," ..
buildCreditList(previous_contributors) .. "," ..
";1]"
- end
+ end,
+ cbf_button_handler = function(this, fields, name, tabdata)
+ if fields.homepage then
+ core.open_url("https://www.minetest.net")
+ end
+ end,
}
diff -Nru minetest-5.2.0/builtin/mainmenu/tab_local.lua minetest-5.3.0/builtin/mainmenu/tab_local.lua
--- minetest-5.2.0/builtin/mainmenu/tab_local.lua 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/builtin/mainmenu/tab_local.lua 2020-07-09 21:13:20.000000000 +0000
@@ -35,6 +35,15 @@
end
local function game_buttonbar_button_handler(fields)
+ if fields.game_open_cdb then
+ local maintab = ui.find_by_name("maintab")
+ local dlg = create_store_dlg("game")
+ dlg:set_parent(maintab)
+ maintab:hide()
+ dlg:show()
+ return true
+ end
+
for key,value in pairs(fields) do
for j=1,#pkgmgr.games,1 do
if ("game_btnbar_" .. pkgmgr.games[j].id == key) then
@@ -87,6 +96,9 @@
end
btnbar:add_button(btn_name, text, image, tooltip)
end
+
+ local plus_image = core.formspec_escape(defaulttexturedir .. "plus.png")
+ btnbar:add_button("game_open_cdb", "", plus_image, fgettext("Install games from ContentDB"))
end
else
function current_game()
@@ -207,40 +219,35 @@
local selected = core.get_textlist_index("sp_worlds")
gamedata.selected_world = menudata.worldlist:get_raw_index(selected)
- if core.settings:get_bool("enable_server") then
- if selected ~= nil and gamedata.selected_world ~= 0 then
- gamedata.playername = fields["te_playername"]
- gamedata.password = fields["te_passwd"]
- gamedata.port = fields["te_serverport"]
- gamedata.address = ""
-
- core.settings:set("port",gamedata.port)
- if fields["te_serveraddr"] ~= nil then
- core.settings:set("bind_address",fields["te_serveraddr"])
- end
+ if selected == nil or gamedata.selected_world == 0 then
+ gamedata.errormessage =
+ fgettext("No world created or selected!")
+ return true
+ end
- --update last game
- local world = menudata.worldlist:get_raw_element(gamedata.selected_world)
- if world then
- local game = pkgmgr.find_by_gameid(world.gameid)
- core.settings:set("menu_last_game", game.id)
- end
+ -- Update last game
+ local world = menudata.worldlist:get_raw_element(gamedata.selected_world)
+ if world then
+ local game = pkgmgr.find_by_gameid(world.gameid)
+ core.settings:set("menu_last_game", game.id)
+ end
- core.start()
- else
- gamedata.errormessage =
- fgettext("No world created or selected!")
+ if core.settings:get_bool("enable_server") then
+ gamedata.playername = fields["te_playername"]
+ gamedata.password = fields["te_passwd"]
+ gamedata.port = fields["te_serverport"]
+ gamedata.address = ""
+
+ core.settings:set("port",gamedata.port)
+ if fields["te_serveraddr"] ~= nil then
+ core.settings:set("bind_address",fields["te_serveraddr"])
end
else
- if selected ~= nil and gamedata.selected_world ~= 0 then
- gamedata.singleplayer = true
- core.start()
- else
- gamedata.errormessage =
- fgettext("No world created or selected!")
- end
- return true
+ gamedata.singleplayer = true
end
+
+ core.start()
+ return true
end
if fields["world_create"] ~= nil then
diff -Nru minetest-5.2.0/builtin/settingtypes.txt minetest-5.3.0/builtin/settingtypes.txt
--- minetest-5.2.0/builtin/settingtypes.txt 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/builtin/settingtypes.txt 2020-07-09 21:13:20.000000000 +0000
@@ -42,10 +42,10 @@
# Flags are always separated by comma without spaces.
# - default possible_flags
# * noise_params_2d:
-# Format is , , (, , ), , , , [, ]
+# Format is , , (, , ), , , , [, ]
# - default
# * noise_params_3d:
-# Format is , , (, , ), , , , [, ]
+# Format is , , (, , ), , , , [, ]
# - default
# * v3f:
# Format is (, , )
@@ -252,7 +252,7 @@
# Key for toggling display of minimap.
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
-keymap_minimap (Minimap key) key KEY_F9
+keymap_minimap (Minimap key) key KEY_KEY_V
# Key for taking screenshots.
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
@@ -424,7 +424,7 @@
# Key for switching between first- and third-person camera.
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
-keymap_camera_mode (Toggle camera mode key) key KEY_F7
+keymap_camera_mode (Toggle camera mode key) key KEY_KEY_C
# Key for increasing the viewing range.
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
@@ -561,9 +561,6 @@
# 1 = relief mapping (slower, more accurate).
parallax_occlusion_mode (Parallax occlusion mode) int 1 0 1
-# Strength of parallax.
-3d_paralax_strength (Parallax occlusion strength) float 0.025
-
# Number of parallax occlusion iterations.
parallax_occlusion_iterations (Parallax occlusion iterations) int 4
@@ -713,6 +710,9 @@
# Note that the interlaced mode requires shaders to be enabled.
3d_mode (3D mode) enum none none,anaglyph,interlaced,topbottom,sidebyside,crossview,pageflip
+# Strength of 3D mode parallax.
+3d_paralax_strength (3D mode parallax strength) float 0.025
+
# In-game chat console height, between 0.1 (10%) and 1.0 (100%).
console_height (Console height) float 0.6 0.1 1.0
@@ -903,8 +903,13 @@
# This font will be used for certain languages or if the default font is unavailable.
fallback_font_path (Fallback font path) filepath fonts/DroidSansFallbackFull.ttf
-# Path to save screenshots at.
-screenshot_path (Screenshot folder) path
+# Font size of the recent chat text and chat prompt in point (pt).
+# Value 0 will use the default font size.
+chat_font_size (Chat font size) int 0
+
+# Path to save screenshots at. Can be an absolute or relative path.
+# The folder will be created if it doesn't already exist.
+screenshot_path (Screenshot folder) path screenshots
# Format of screenshots.
screenshot_format (Screenshot format) enum png png,jpg,bmp,pcx,ppm,tga
@@ -954,6 +959,12 @@
# Note that the port field in the main menu overrides this setting.
remote_port (Remote port) int 30000 1 65535
+# Prometheus listener address.
+# If minetest is compiled with ENABLE_PROMETHEUS option enabled,
+# enable metrics listener for Prometheus on that address.
+# Metrics can be fetch on http://127.0.0.1:30000/metrics
+prometheus_listener_address (Prometheus listener address) string 127.0.0.1:30000
+
# Save the map received by the client on disk.
enable_local_map_saving (Saving map received from server) bool false
@@ -1078,6 +1089,10 @@
# Setting it to -1 disables the feature.
item_entity_ttl (Item entity TTL) int 900
+# Specifies the default stack size of nodes, items and tools.
+# Note that mods or games may explicitly set a stack for certain (or all) items.
+default_stack_max (Default stack size) int 99
+
# Enable players getting damage and dying.
enable_damage (Damage) bool false
@@ -1149,7 +1164,7 @@
# active block stuff, stated in mapblocks (16 nodes).
# In active blocks objects are loaded and ABMs run.
# This is also the minimum range in which active objects (mobs) are maintained.
-# This should be configured together with active_object_range.
+# This should be configured together with active_object_send_range_blocks.
active_block_range (Active block range) int 3
# From how far blocks are sent to clients, stated in mapblocks (16 nodes).
@@ -1372,7 +1387,7 @@
# Set the language. Leave empty to use the system language.
# A restart is required after changing this.
-language (Language) enum ,ar,ca,cs,da,de,dv,el,eo,es,et,eu,fil,fr,hu,id,it,ja,ja_KS,jbo,kk,kn,lo,lt,ms,my,nb,nl,nn,pl,pt,pt_BR,ro,ru,sl,sr_Cyrl,sv,sw,th,tr,uk,vi
+language (Language) enum ,ar,ca,cs,da,de,dv,el,en,eo,es,et,eu,fil,fr,hu,id,it,ja,ja_KS,jbo,kk,kn,lo,lt,ms,my,nb,nl,nn,pl,pt,pt_BR,ro,ru,sl,sr_Cyrl,sv,sw,th,tr,uk,vi
# Level of logging to be written to debug.txt:
# - (no logging)
@@ -1390,6 +1405,9 @@
# debug.txt is only moved if this setting is positive.
debug_log_size_max (Debug log file size threshold) int 50
+# Minimal level of logging to be written to chat.
+chat_log_level (Chat log level) enum error ,none,error,warning,action,info,verbose
+
# Enable IPv6 support (for both client and server).
# Required for IPv6 connections to work at all.
enable_ipv6 (IPv6) bool true
@@ -1593,12 +1611,53 @@
[*Mapgen V7]
# Map generation attributes specific to Mapgen v7.
-# 'ridges' enables the rivers.
+# 'ridges': Rivers.
+# 'floatlands': Floating land masses in the atmosphere.
+# 'caverns': Giant caves deep underground.
mgv7_spflags (Mapgen V7 specific flags) flags mountains,ridges,nofloatlands,caverns mountains,ridges,floatlands,caverns,nomountains,noridges,nofloatlands,nocaverns
# Y of mountain density gradient zero level. Used to shift mountains vertically.
mgv7_mount_zero_level (Mountain zero level) int 0
+# Lower Y limit of floatlands.
+mgv7_floatland_ymin (Floatland minimum Y) int 1024
+
+# Upper Y limit of floatlands.
+mgv7_floatland_ymax (Floatland maximum Y) int 4096
+
+# Y-distance over which floatlands taper from full density to nothing.
+# Tapering starts at this distance from the Y limit.
+# For a solid floatland layer, this controls the height of hills/mountains.
+# Must be less than or equal to half the distance between the Y limits.
+mgv7_floatland_taper (Floatland tapering distance) int 256
+
+# Exponent of the floatland tapering. Alters the tapering behaviour.
+# Value = 1.0 creates a uniform, linear tapering.
+# Values > 1.0 create a smooth tapering suitable for the default separated
+# floatlands.
+# Values < 1.0 (for example 0.25) create a more defined surface level with
+# flatter lowlands, suitable for a solid floatland layer.
+mgv7_float_taper_exp (Floatland taper exponent) float 2.0
+
+# Adjusts the density of the floatland layer.
+# Increase value to increase density. Can be positive or negative.
+# Value = 0.0: 50% of volume is floatland.
+# Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test
+# to be sure) creates a solid floatland layer.
+mgv7_floatland_density (Floatland density) float -0.6
+
+# Surface level of optional water placed on a solid floatland layer.
+# Water is disabled by default and will only be placed if this value is set
+# to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the
+# upper tapering).
+# ***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:
+# When enabling water placement the floatlands must be configured and tested
+# to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other
+# required value depending on 'mgv7_np_floatland'), to avoid
+# server-intensive extreme water flow and to avoid vast flooding of the
+# world surface below.
+mgv7_floatland_ywater (Floatland water level) int -31000
+
# Controls width of tunnels, a smaller value creates wider tunnels.
# Value >= 10.0 completely disables generation of tunnels and avoids the
# intensive noise calculations.
@@ -1668,6 +1727,12 @@
# 3D noise defining structure of river canyon walls.
mgv7_np_ridge (Ridge noise) noise_params_3d 0, 1, (100, 100, 100), 6467, 4, 0.75, 2.0
+# 3D noise defining structure of floatlands.
+# If altered from the default, the noise 'scale' (0.7 by default) may need
+# to be adjusted, as floatland tapering functions best when this noise has
+# a value range of approximately -2.0 to 2.0.
+mgv7_np_floatland (Floatland noise) noise_params_3d 0, 0.7, (384, 96, 384), 1009, 4, 0.75, 1.618
+
# 3D noise defining giant caverns.
mgv7_np_cavern (Cavern noise) noise_params_3d 0, 1, (384, 128, 384), 723, 5, 0.63, 2.0
@@ -2098,20 +2163,17 @@
enable_mapgen_debug_info (Mapgen debug) bool false
# Maximum number of blocks that can be queued for loading.
-emergequeue_limit_total (Absolute limit of emerge queues) int 512
+emergequeue_limit_total (Absolute limit of queued blocks to emerge) int 512
# Maximum number of blocks to be queued that are to be loaded from file.
-# Set to blank for an appropriate amount to be chosen automatically.
-emergequeue_limit_diskonly (Limit of emerge queues on disk) int 64
+# This limit is enforced per player.
+emergequeue_limit_diskonly (Per-player limit of queued blocks load from disk) int 64
# Maximum number of blocks to be queued that are to be generated.
-# Set to blank for an appropriate amount to be chosen automatically.
-emergequeue_limit_generate (Limit of emerge queues to generate) int 64
+# This limit is enforced per player.
+emergequeue_limit_generate (Per-player limit of queued blocks to generate) int 64
# Number of emerge threads to use.
-# WARNING: Currently there are multiple bugs that may cause crashes when
-# 'num_emerge_threads' is larger than 1. Until this warning is removed it is
-# strongly recommended this value is set to the default '1'.
# Value 0:
# - Automatic selection. The number of emerge threads will be
# - 'number of processors - 2', with a lower limit of 1.
diff -Nru minetest-5.2.0/client/shaders/nodes_shader/opengl_vertex.glsl minetest-5.3.0/client/shaders/nodes_shader/opengl_vertex.glsl
--- minetest-5.2.0/client/shaders/nodes_shader/opengl_vertex.glsl 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/client/shaders/nodes_shader/opengl_vertex.glsl 2020-07-09 21:13:20.000000000 +0000
@@ -101,8 +101,8 @@
float disp_x;
float disp_z;
-#if (MATERIAL_TYPE == TILE_MATERIAL_WAVING_LEAVES && ENABLE_WAVING_LEAVES) || \
- (MATERIAL_TYPE == TILE_MATERIAL_WAVING_PLANTS && ENABLE_WAVING_PLANTS)
+// OpenGL < 4.3 does not support continued preprocessor lines
+#if (MATERIAL_TYPE == TILE_MATERIAL_WAVING_LEAVES && ENABLE_WAVING_LEAVES) || (MATERIAL_TYPE == TILE_MATERIAL_WAVING_PLANTS && ENABLE_WAVING_PLANTS)
vec4 pos2 = mWorld * gl_Vertex;
float tOffset = (pos2.x + pos2.y) * 0.001 + pos2.z * 0.002;
disp_x = (smoothTriangleWave(animationTimer * 23.0 + tOffset) +
diff -Nru minetest-5.2.0/client/shaders/object_shader/opengl_fragment.glsl minetest-5.3.0/client/shaders/object_shader/opengl_fragment.glsl
--- minetest-5.2.0/client/shaders/object_shader/opengl_fragment.glsl 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/client/shaders/object_shader/opengl_fragment.glsl 2020-07-09 21:13:20.000000000 +0000
@@ -25,6 +25,38 @@
const float fogStart = FOG_START;
const float fogShadingParameter = 1 / ( 1 - fogStart);
+#ifdef ENABLE_TONE_MAPPING
+
+/* Hable's UC2 Tone mapping parameters
+ A = 0.22;
+ B = 0.30;
+ C = 0.10;
+ D = 0.20;
+ E = 0.01;
+ F = 0.30;
+ W = 11.2;
+ equation used: ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F
+*/
+
+vec3 uncharted2Tonemap(vec3 x)
+{
+ return ((x * (0.22 * x + 0.03) + 0.002) / (x * (0.22 * x + 0.3) + 0.06)) - 0.03333;
+}
+
+vec4 applyToneMapping(vec4 color)
+{
+ color = vec4(pow(color.rgb, vec3(2.2)), color.a);
+ const float gamma = 1.6;
+ const float exposureBias = 5.5;
+ color.rgb = uncharted2Tonemap(exposureBias * color.rgb);
+ // Precalculated white_scale from
+ //vec3 whiteScale = 1.0 / uncharted2Tonemap(vec3(W));
+ vec3 whiteScale = vec3(1.036015346);
+ color.rgb *= whiteScale;
+ return vec4(pow(color.rgb, vec3(1.0 / gamma)), color.a);
+}
+#endif
+
void get_texture_flags()
{
vec4 flags = texture2D(textureFlags, vec2(0.0, 0.0));
@@ -113,7 +145,14 @@
vec4 col = vec4(color.rgb, base.a);
+ col.rgb *= gl_Color.rgb;
+
col.rgb *= emissiveColor.rgb * vIDiff;
+
+#ifdef ENABLE_TONE_MAPPING
+ col = applyToneMapping(col);
+#endif
+
// Due to a bug in some (older ?) graphics stacks (possibly in the glsl compiler ?),
// the fog will only be rendered correctly if the last operation before the
// clamp() is an addition. Else, the clamp() seems to be ignored.
diff -Nru minetest-5.2.0/client/shaders/object_shader/opengl_vertex.glsl minetest-5.3.0/client/shaders/object_shader/opengl_vertex.glsl
--- minetest-5.2.0/client/shaders/object_shader/opengl_vertex.glsl 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/client/shaders/object_shader/opengl_vertex.glsl 2020-07-09 21:13:20.000000000 +0000
@@ -38,7 +38,16 @@
lightVec = sunPosition - worldPosition;
eyeVec = -(gl_ModelViewMatrix * gl_Vertex).xyz;
- vIDiff = directional_ambient(normalize(gl_Normal));
+
+#if (MATERIAL_TYPE == TILE_MATERIAL_PLAIN) || (MATERIAL_TYPE == TILE_MATERIAL_PLAIN_ALPHA)
+ vIDiff = 1.0;
+#else
+ // This is intentional comparison with zero without any margin.
+ // If normal is not equal to zero exactly, then we assume it's a valid, just not normalized vector
+ vIDiff = length(gl_Normal) == 0.0
+ ? 1.0
+ : directional_ambient(normalize(gl_Normal));
+#endif
gl_FrontColor = gl_BackColor = gl_Color;
}
diff -Nru minetest-5.2.0/client/shaders/wielded_shader/opengl_fragment.glsl minetest-5.3.0/client/shaders/wielded_shader/opengl_fragment.glsl
--- minetest-5.2.0/client/shaders/wielded_shader/opengl_fragment.glsl 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/client/shaders/wielded_shader/opengl_fragment.glsl 1970-01-01 00:00:00.000000000 +0000
@@ -1,127 +0,0 @@
-uniform sampler2D baseTexture;
-uniform sampler2D normalTexture;
-uniform sampler2D textureFlags;
-
-uniform vec4 skyBgColor;
-uniform float fogDistance;
-uniform vec3 eyePosition;
-
-varying vec3 vPosition;
-varying vec3 worldPosition;
-
-varying vec3 eyeVec;
-varying vec3 lightVec;
-
-bool normalTexturePresent = false;
-bool texTileableHorizontal = false;
-bool texTileableVertical = false;
-bool texSeamless = false;
-
-const float e = 2.718281828459;
-const float BS = 10.0;
-const float fogStart = FOG_START;
-const float fogShadingParameter = 1 / ( 1 - fogStart);
-
-void get_texture_flags()
-{
- vec4 flags = texture2D(textureFlags, vec2(0.0, 0.0));
- if (flags.r > 0.5) {
- normalTexturePresent = true;
- }
- if (flags.g > 0.5) {
- texTileableHorizontal = true;
- }
- if (flags.b > 0.5) {
- texTileableVertical = true;
- }
- if (texTileableHorizontal && texTileableVertical) {
- texSeamless = true;
- }
-}
-
-float intensity(vec3 color)
-{
- return (color.r + color.g + color.b) / 3.0;
-}
-
-float get_rgb_height(vec2 uv)
-{
- if (texSeamless) {
- return intensity(texture2D(baseTexture, uv).rgb);
- } else {
- return intensity(texture2D(baseTexture, clamp(uv, 0.0, 0.999)).rgb);
- }
-}
-
-vec4 get_normal_map(vec2 uv)
-{
- vec4 bump = texture2D(normalTexture, uv).rgba;
- bump.xyz = normalize(bump.xyz * 2.0 - 1.0);
- return bump;
-}
-
-void main(void)
-{
- vec3 color;
- vec4 bump;
- vec2 uv = gl_TexCoord[0].st;
- bool use_normalmap = false;
- get_texture_flags();
-
-#if USE_NORMALMAPS == 1
- if (normalTexturePresent) {
- bump = get_normal_map(uv);
- use_normalmap = true;
- }
-#endif
-
-#if GENERATE_NORMALMAPS == 1
- if (normalTexturePresent == false) {
- float tl = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y + SAMPLE_STEP));
- float t = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y - SAMPLE_STEP));
- float tr = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y + SAMPLE_STEP));
- float r = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y));
- float br = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y - SAMPLE_STEP));
- float b = get_rgb_height(vec2(uv.x, uv.y - SAMPLE_STEP));
- float bl = get_rgb_height(vec2(uv.x -SAMPLE_STEP, uv.y - SAMPLE_STEP));
- float l = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y));
- float dX = (tr + 2.0 * r + br) - (tl + 2.0 * l + bl);
- float dY = (bl + 2.0 * b + br) - (tl + 2.0 * t + tr);
- bump = vec4(normalize(vec3 (dX, dY, NORMALMAPS_STRENGTH)), 1.0);
- use_normalmap = true;
- }
-#endif
-
- vec4 base = texture2D(baseTexture, uv).rgba;
-
-#ifdef ENABLE_BUMPMAPPING
- if (use_normalmap) {
- vec3 L = normalize(lightVec);
- vec3 E = normalize(eyeVec);
- float specular = pow(clamp(dot(reflect(L, bump.xyz), E), 0.0, 1.0), 1.0);
- float diffuse = dot(-E,bump.xyz);
- color = (diffuse + 0.1 * specular) * base.rgb;
- } else {
- color = base.rgb;
- }
-#else
- color = base.rgb;
-#endif
-
- vec4 col = vec4(color.rgb, base.a);
- col *= gl_Color;
- // Due to a bug in some (older ?) graphics stacks (possibly in the glsl compiler ?),
- // the fog will only be rendered correctly if the last operation before the
- // clamp() is an addition. Else, the clamp() seems to be ignored.
- // E.g. the following won't work:
- // float clarity = clamp(fogShadingParameter
- // * (fogDistance - length(eyeVec)) / fogDistance), 0.0, 1.0);
- // As additions usually come for free following a multiplication, the new formula
- // should be more efficient as well.
- // Note: clarity = (1 - fogginess)
- float clarity = clamp(fogShadingParameter
- - fogShadingParameter * length(eyeVec) / fogDistance, 0.0, 1.0);
- col = mix(skyBgColor, col, clarity);
-
- gl_FragColor = vec4(col.rgb, base.a);
-}
diff -Nru minetest-5.2.0/client/shaders/wielded_shader/opengl_vertex.glsl minetest-5.3.0/client/shaders/wielded_shader/opengl_vertex.glsl
--- minetest-5.2.0/client/shaders/wielded_shader/opengl_vertex.glsl 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/client/shaders/wielded_shader/opengl_vertex.glsl 1970-01-01 00:00:00.000000000 +0000
@@ -1,32 +0,0 @@
-uniform mat4 mWorldViewProj;
-uniform mat4 mWorld;
-
-uniform vec3 eyePosition;
-uniform float animationTimer;
-
-varying vec3 vPosition;
-varying vec3 worldPosition;
-
-varying vec3 eyeVec;
-varying vec3 lightVec;
-varying vec3 tsEyeVec;
-varying vec3 tsLightVec;
-
-const float e = 2.718281828459;
-const float BS = 10.0;
-
-void main(void)
-{
- gl_TexCoord[0] = gl_MultiTexCoord0;
- gl_Position = mWorldViewProj * gl_Vertex;
-
- vPosition = gl_Position.xyz;
- worldPosition = (mWorld * gl_Vertex).xyz;
-
- vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0);
-
- lightVec = sunPosition - worldPosition;
- eyeVec = -(gl_ModelViewMatrix * gl_Vertex).xyz;
-
- gl_FrontColor = gl_BackColor = gl_Color;
-}
diff -Nru minetest-5.2.0/clientmods/preview/init.lua minetest-5.3.0/clientmods/preview/init.lua
--- minetest-5.2.0/clientmods/preview/init.lua 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/clientmods/preview/init.lua 2020-07-09 21:13:20.000000000 +0000
@@ -31,6 +31,7 @@
end)
core.after(1, function()
+ print("armor: " .. dump(core.localplayer:get_armor_groups()))
id = core.localplayer:hud_add({
hud_elem_type = "text",
name = "example",
@@ -78,7 +79,7 @@
return false
end
- local pos = vector.add(core.localplayer:get_pos(), core.camera:get_offset())
+ local pos = core.camera:get_pos()
local pos2 = vector.add(pos, vector.multiply(core.camera:get_look_dir(), 100))
local rc = core.raycast(pos, pos2)
@@ -125,19 +126,6 @@
end,
})
-core.register_chatcommand("colorize_test", {
- func = function(param)
- return true, core.colorize("red", param)
- end,
-})
-
-core.register_chatcommand("test_node", {
- func = function(param)
- core.display_chat_message(dump(core.get_node({x=0, y=0, z=0})))
- core.display_chat_message(dump(core.get_node_or_nil({x=0, y=0, z=0})))
- end,
-})
-
local function preview_minimap()
local minimap = core.ui.minimap
if not minimap then
@@ -157,7 +145,7 @@
core.after(2, function()
print("[PREVIEW] loaded " .. modname .. " mod")
modstorage:set_string("current_mod", modname)
- print(modstorage:get_string("current_mod"))
+ assert(modstorage:get_string("current_mod") == modname)
preview_minimap()
end)
@@ -184,30 +172,12 @@
core.register_on_punchnode(function(pos, node)
print("The local player punched a node!")
- local itemstack = core.get_wielded_item()
- --[[
- -- getters
- print(dump(itemstack:is_empty()))
- print(dump(itemstack:get_name()))
- print(dump(itemstack:get_count()))
- print(dump(itemstack:get_wear()))
- print(dump(itemstack:get_meta()))
- print(dump(itemstack:get_metadata()
- print(dump(itemstack:is_known()))
- --print(dump(itemstack:get_definition()))
- print(dump(itemstack:get_tool_capabilities()))
- print(dump(itemstack:to_string()))
- print(dump(itemstack:to_table()))
- -- setters
- print(dump(itemstack:set_name("default:dirt")))
- print(dump(itemstack:set_count("95")))
- print(dump(itemstack:set_wear(934)))
- print(dump(itemstack:get_meta()))
- print(dump(itemstack:get_metadata()))
- --]]
+ local itemstack = core.localplayer:get_wielded_item()
print(dump(itemstack:to_table()))
print("pos:" .. dump(pos))
print("node:" .. dump(node))
+ local meta = core.get_meta(pos)
+ print("punched meta: " .. (meta and dump(meta:to_table()) or "(missing)"))
return false
end)
diff -Nru minetest-5.2.0/cmake/Modules/FindGettextLib.cmake minetest-5.3.0/cmake/Modules/FindGettextLib.cmake
--- minetest-5.2.0/cmake/Modules/FindGettextLib.cmake 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/cmake/Modules/FindGettextLib.cmake 2020-07-09 21:13:20.000000000 +0000
@@ -55,10 +55,10 @@
include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(GetText DEFAULT_MSG ${GETTEXT_REQUIRED_VARS})
+find_package_handle_standard_args(GettextLib DEFAULT_MSG ${GETTEXT_REQUIRED_VARS})
-if(GETTEXT_FOUND)
+if(GETTEXTLIB_FOUND)
# BSD variants require special linkage as they don't use glibc
if(${CMAKE_SYSTEM_NAME} MATCHES "BSD|DragonFly")
set(GETTEXT_LIBRARY "intl")
diff -Nru minetest-5.2.0/cmake/Modules/FindJson.cmake minetest-5.3.0/cmake/Modules/FindJson.cmake
--- minetest-5.2.0/cmake/Modules/FindJson.cmake 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/cmake/Modules/FindJson.cmake 2020-07-09 21:13:20.000000000 +0000
@@ -11,14 +11,14 @@
find_path(JSON_INCLUDE_DIR json/allocator.h PATH_SUFFIXES jsoncpp)
include(FindPackageHandleStandardArgs)
- find_package_handle_standard_args(JSONCPP DEFAULT_MSG JSON_LIBRARY JSON_INCLUDE_DIR)
+ find_package_handle_standard_args(Json DEFAULT_MSG JSON_LIBRARY JSON_INCLUDE_DIR)
- if(JSONCPP_FOUND)
+ if(JSON_FOUND)
message(STATUS "Using system JSONCPP library.")
endif()
endif()
-if(NOT JSONCPP_FOUND)
+if(NOT JSON_FOUND)
message(STATUS "Using bundled JSONCPP library.")
set(JSON_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib/jsoncpp)
set(JSON_LIBRARY jsoncpp)
diff -Nru minetest-5.2.0/cmake/Modules/FindLuaJIT.cmake minetest-5.3.0/cmake/Modules/FindLuaJIT.cmake
--- minetest-5.2.0/cmake/Modules/FindLuaJIT.cmake 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/cmake/Modules/FindLuaJIT.cmake 2020-07-09 21:13:20.000000000 +0000
@@ -55,7 +55,7 @@
INCLUDE(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set LUAJIT_FOUND to TRUE if
# all listed variables are TRUE
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(LuaJit
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LuaJIT
REQUIRED_VARS LUA_LIBRARY LUA_INCLUDE_DIR
VERSION_VAR LUA_VERSION_STRING)
diff -Nru minetest-5.2.0/cmake/Modules/FindVorbis.cmake minetest-5.3.0/cmake/Modules/FindVorbis.cmake
--- minetest-5.2.0/cmake/Modules/FindVorbis.cmake 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/cmake/Modules/FindVorbis.cmake 2020-07-09 21:13:20.000000000 +0000
@@ -20,13 +20,13 @@
# Handle the QUIETLY and REQUIRED arguments and set VORBIS_FOUND
# to TRUE if all listed variables are TRUE.
include(FindPackageHandleStandardArgs)
- find_package_handle_standard_args(VORBIS DEFAULT_MSG
+ find_package_handle_standard_args(Vorbis DEFAULT_MSG
OGG_INCLUDE_DIR VORBIS_INCLUDE_DIR
OGG_LIBRARY VORBIS_LIBRARY VORBISFILE_LIBRARY)
else(NOT GP2XWIZ)
find_path(VORBIS_INCLUDE_DIR tremor/ivorbisfile.h)
find_library(VORBIS_LIBRARY NAMES vorbis_dec)
- find_package_handle_standard_args(VORBIS DEFAULT_MSG
+ find_package_handle_standard_args(Vorbis DEFAULT_MSG
VORBIS_INCLUDE_DIR VORBIS_LIBRARY)
endif(NOT GP2XWIZ)
diff -Nru minetest-5.2.0/CMakeLists.txt minetest-5.3.0/CMakeLists.txt
--- minetest-5.2.0/CMakeLists.txt 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/CMakeLists.txt 2020-07-09 21:13:20.000000000 +0000
@@ -16,7 +16,7 @@
# Also remember to set PROTOCOL_VERSION in network/networkprotocol.h when releasing
set(VERSION_MAJOR 5)
-set(VERSION_MINOR 2)
+set(VERSION_MINOR 3)
set(VERSION_PATCH 0)
set(VERSION_EXTRA "" CACHE STRING "Stuff to append to version string")
@@ -49,6 +49,7 @@
set(BUILD_CLIENT TRUE CACHE BOOL "Build client")
set(BUILD_SERVER FALSE CACHE BOOL "Build server")
+set(BUILD_UNITTESTS TRUE CACHE BOOL "Build unittests")
set(WARN_ALL TRUE CACHE BOOL "Enable -Wall for Release build")
@@ -102,7 +103,7 @@
set(XDG_APPS_DIR "${CMAKE_INSTALL_PREFIX}/share/applications")
set(APPDATADIR "${CMAKE_INSTALL_PREFIX}/share/metainfo")
set(ICONDIR "${CMAKE_INSTALL_PREFIX}/share/icons")
- set(LOCALEDIR "${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}/locale")
+ set(LOCALEDIR "${CMAKE_INSTALL_PREFIX}/share/locale")
endif()
endif()
@@ -166,7 +167,7 @@
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/games/minetest_game" DESTINATION "${SHAREDIR}/games/"
COMPONENT "SUBGAME_MINETEST_GAME" OPTIONAL PATTERN ".git*" EXCLUDE )
-install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/games/minimal" DESTINATION "${SHAREDIR}/games/"
+install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/games/devtest" DESTINATION "${SHAREDIR}/games/"
COMPONENT "SUBGAME_MINIMAL" OPTIONAL PATTERN ".git*" EXCLUDE )
if(BUILD_CLIENT)
@@ -253,8 +254,8 @@
)
cpack_add_component(SUBGAME_MINIMAL
- DISPLAY_NAME "Minimal development test"
- DESCRIPTION "A minimal subgame helping to develop the engine."
+ DISPLAY_NAME "Development Test"
+ DESCRIPTION "A minimal test game helping to develop the engine."
DISABLED #DISABLED does not mean it is disabled, and is just not selected by default.
GROUP "Subgames"
)
@@ -325,4 +326,3 @@
COMMENT "Generating API documentation with Doxygen" VERBATIM
)
endif()
-
diff -Nru minetest-5.2.0/debian/changelog minetest-5.3.0/debian/changelog
--- minetest-5.2.0/debian/changelog 2020-04-05 17:47:10.000000000 +0000
+++ minetest-5.3.0/debian/changelog 2020-07-09 21:13:28.000000000 +0000
@@ -1,8 +1,8 @@
-minetest (5.2.0-ppa0~ubuntu18.04.1) bionic; urgency=low
+minetest (5.3.0-ppa0~ubuntu18.04.1) bionic; urgency=low
* Auto build.
- -- rubenwardy Sun, 05 Apr 2020 17:47:10 +0000
+ -- rubenwardy Thu, 09 Jul 2020 21:13:28 +0000
minetest (0.0-0) UNRELEASED; urgency=medium
diff -Nru minetest-5.2.0/debian/git-build-recipe.manifest minetest-5.3.0/debian/git-build-recipe.manifest
--- minetest-5.2.0/debian/git-build-recipe.manifest 2020-04-05 17:47:10.000000000 +0000
+++ minetest-5.3.0/debian/git-build-recipe.manifest 2020-07-09 21:13:28.000000000 +0000
@@ -1,4 +1,4 @@
-# git-build-recipe format 0.4 deb-version 5.2.0-ppa0
-lp:minetest-c55 git-commit:24147d99c00b3b7677a2c2f8f47e036a6371d03b
+# git-build-recipe format 0.4 deb-version 5.3.0-ppa0
+lp:minetest-c55 git-commit:057f0b82c23d5ad4efe044fe0f0d8753eb3a8bcf
nest packaging lp:~minetestdevs/minetest-c55/+git/packaging debian git-commit:0bc3635323bdd991ba507ff4d7fd7e8f97e210c8
-nest minetest_game lp:~minetestdevs/minetest-c55/+git/upstream_game games/minetest_game git-commit:8863527bb62c0cb3bf19d6d2acf6ecb817e61cc2
+nest minetest_game lp:~minetestdevs/minetest-c55/+git/upstream_game games/minetest_game git-commit:8c01a5b288ce50e2f9e4ba9df26296d814842f06
diff -Nru minetest-5.2.0/doc/client_lua_api.txt minetest-5.3.0/doc/client_lua_api.txt
--- minetest-5.2.0/doc/client_lua_api.txt 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/doc/client_lua_api.txt 2020-07-09 21:13:20.000000000 +0000
@@ -1,4 +1,4 @@
-Minetest Lua Client Modding API Reference 5.2.0
+Minetest Lua Client Modding API Reference 5.3.0
================================================
* More information at
* Developer Wiki:
@@ -112,7 +112,7 @@
wants to register. Subsequent execution depends on minetest calling the
registered callbacks.
-**NOTE**: Client mods currently can't provide and textures, sounds or models by
+**NOTE**: Client mods currently can't provide textures, sounds, or models by
themselves. Any media referenced in function calls must already be loaded
(provided by mods that exist on the server).
@@ -734,6 +734,13 @@
* `spec` is a `SimpleSoundSpec`
* `parameters` is a sound parameter table
* `minetest.sound_stop(handle)`
+ * `handle` is a handle returned by `minetest.sound_play`
+* `minetest.sound_fade(handle, step, gain)`
+ * `handle` is a handle returned by `minetest.sound_play`
+ * `step` determines how fast a sound will fade.
+ Negative step will lower the sound volume, positive step will increase
+ the sound volume.
+ * `gain` the target gain for the fade.
### Timing
* `minetest.after(time, func, ...)`
@@ -797,8 +804,6 @@
* get max available level for leveled node
### Player
-* `minetest.get_wielded_item()`
- * Returns the itemstack the local player is holding
* `minetest.send_chat_message(message)`
* Act as if `message` was typed by the player into the terminal.
* `minetest.run_server_chatcommand(cmd, param)`
@@ -962,7 +967,7 @@
* `get_camera_mode()`
* Returns 0, 1, or 2 as described above
* `get_fov()`
- * Returns:
+ * Returns a table with X, Y, maximum and actual FOV in degrees:
```lua
{
@@ -999,6 +1004,10 @@
* returns player HP
* `get_name()`
* returns player name
+* `get_wield_index()`
+ * returns the index of the wielded item
+* `get_wielded_item()`
+ * returns the itemstack the player is holding
* `is_attached()`
* returns true if player is attached
* `is_touching_ground()`
@@ -1022,7 +1031,8 @@
jump = float,
gravity = float,
sneak = boolean,
- sneak_glitch = boolean
+ sneak_glitch = boolean,
+ new_move = boolean,
}
```
@@ -1074,8 +1084,26 @@
* returns last look horizontal angle
* `get_last_look_vertical()`:
* returns last look vertical angle
-* `get_key_pressed()`:
- * returns last key typed by the player
+* `get_control()`:
+ * returns pressed player controls
+
+```lua
+ {
+ up = boolean,
+ down = boolean,
+ left = boolean,
+ right = boolean,
+ jump = boolean,
+ aux1 = boolean,
+ sneak = boolean,
+ zoom = boolean,
+ LMB = boolean,
+ RMB = boolean,
+ }
+```
+
+* `get_armor_groups()`
+ * returns a table with the armor group ratings
* `hud_add(definition)`
* add a HUD element described by HUD def, returns ID number on success and `nil` on failure.
* See [`HUD definition`](#hud-definition-hud_add-hud_get)
@@ -1388,12 +1416,35 @@
* `offset`: offset in pixels from position.
### `waypoint`
+
Displays distance to selected world position.
* `name`: The name of the waypoint.
* `text`: Distance suffix. Can be blank.
-* `number:` An integer containing the RGB value of the color used to draw the text.
+* `precision`: Waypoint precision, integer >= 0. Defaults to 10.
+ If set to 0, distance is not shown. Shown value is `floor(distance*precision)/precision`.
+ When the precision is an integer multiple of 10, there will be `log_10(precision)` digits after the decimal point.
+ `precision = 1000`, for example, will show 3 decimal places (eg: `0.999`).
+ `precision = 2` will show multiples of `0.5`; precision = 5 will show multiples of `0.2` and so on:
+ `precision = n` will show multiples of `1/n`
+* `number:` An integer containing the RGB value of the color used to draw the
+ text.
* `world_pos`: World position of the waypoint.
+* `offset`: offset in pixels from position.
+* `alignment`: The alignment of the waypoint.
+
+### `image_waypoint`
+
+Same as `image`, but does not accept a `position`; the position is instead determined by `world_pos`, the world position of the waypoint.
+
+* `scale`: The scale of the image, with 1 being the original texture size.
+ Only the X coordinate scale is used (positive values).
+ Negative values represent that percentage of the screen it
+ should take; e.g. `x=-100` means 100% (width).
+* `text`: The name of the texture that is displayed.
+* `alignment`: The alignment of the image.
+* `world_pos`: World position of the waypoint.
+* `offset`: offset in pixels from position.
### Particle definition (`add_particle`)
diff -Nru minetest-5.2.0/doc/Doxyfile.in minetest-5.3.0/doc/Doxyfile.in
--- minetest-5.2.0/doc/Doxyfile.in 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/doc/Doxyfile.in 2020-07-09 21:13:20.000000000 +0000
@@ -20,18 +20,10 @@
"USE_GETTEXT=1"
# Input
-RECURSIVE = NO
+RECURSIVE = YES
STRIP_FROM_PATH = @CMAKE_CURRENT_SOURCE_DIR@/src
INPUT = @CMAKE_CURRENT_SOURCE_DIR@/doc/main_page.dox \
- @CMAKE_CURRENT_SOURCE_DIR@/src/ \
- @CMAKE_CURRENT_SOURCE_DIR@/src/client \
- @CMAKE_CURRENT_SOURCE_DIR@/src/network \
- @CMAKE_CURRENT_SOURCE_DIR@/src/util \
- @CMAKE_CURRENT_SOURCE_DIR@/src/script \
- @CMAKE_CURRENT_SOURCE_DIR@/src/script/common \
- @CMAKE_CURRENT_SOURCE_DIR@/src/script/cpp_api \
- @CMAKE_CURRENT_SOURCE_DIR@/src/script/lua_api \
- @CMAKE_CURRENT_SOURCE_DIR@/src/threading
+ @CMAKE_CURRENT_SOURCE_DIR@/src/
# Dot graphs
HAVE_DOT = @DOXYGEN_DOT_FOUND@
diff -Nru minetest-5.2.0/doc/fst_api.txt minetest-5.3.0/doc/fst_api.txt
--- minetest-5.2.0/doc/fst_api.txt 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/doc/fst_api.txt 2020-07-09 21:13:20.000000000 +0000
@@ -101,6 +101,9 @@
^ cbf_events: function to handle events
function(dialog, event)
+messagebox(name, message)
+^ creates a message dialog
+
Class reference dialog:
methods:
@@ -113,13 +116,13 @@
^ hide dialog
- delete()
^ delete dialog from ui
-
+
members:
- data
^ variable data attached to this dialog
- parent
^ parent component to return to on exit
-
+
File: fst/buttonbar.lua
-----------------------
diff -Nru minetest-5.2.0/doc/lua_api.txt minetest-5.3.0/doc/lua_api.txt
--- minetest-5.2.0/doc/lua_api.txt 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/doc/lua_api.txt 2020-07-09 21:13:20.000000000 +0000
@@ -64,9 +64,21 @@
* `game.conf`, with the following keys:
* `name`: Required, human readable name e.g. `name = Minetest`
* `description`: Short description to be shown in the content tab
+ * `allowed_mapgens = `
+ e.g. `allowed_mapgens = v5,v6,flat`
+ Mapgens not in this list are removed from the list of mapgens for
+ the game.
+ If not specified, all mapgens are allowed.
* `disallowed_mapgens = `
e.g. `disallowed_mapgens = v5,v6,flat`
These mapgens are removed from the list of mapgens for the game.
+ When both `allowed_mapgens` and `disallowed_mapgens` are
+ specified, `allowed_mapgens` is applied before
+ `disallowed_mapgens`.
+ * `disallowed_mapgen_settings= `
+ e.g. `disallowed_mapgen_settings = mgv5_spflags`
+ These settings are hidden for this game in the world creation
+ dialog and game start menu.
* `minetest.conf`:
Used to set default settings when running this game.
* `settingtypes.txt`:
@@ -889,6 +901,7 @@
* `player_damage`: Played when the local player takes damage (gain = 0.5)
* `player_falling_damage`: Played when the local player takes
damage by falling (gain = 0.5)
+ * `player_jump`: Played when the local player jumps
* `default_dig_`: Default node digging sound
(see node sound definition for details)
@@ -1010,22 +1023,24 @@
* Values range 0 - 179. The value stored in `param2` is multiplied by two to
get the actual rotation in degrees of the node.
* `paramtype2 = "meshoptions"`
- * Only valid for "plantlike" drawtype. The value of `param2` becomes a
- bitfield which can be used to change how the client draws plantlike nodes.
- * Bits 0, 1 and 2 form a mesh selector.
- Currently the following meshes are choosable:
+ * Only valid for "plantlike" drawtype. `param2` encodes the shape and
+ optional modifiers of the "plant". `param2` is a bitfield.
+ * Bits 0 to 2 select the shape.
+ Use only one of the values below:
* 0 = a "x" shaped plant (ordinary plant)
* 1 = a "+" shaped plant (just rotated 45 degrees)
* 2 = a "*" shaped plant with 3 faces instead of 2
* 3 = a "#" shaped plant with 4 faces instead of 2
* 4 = a "#" shaped plant with 4 faces that lean outwards
* 5-7 are unused and reserved for future meshes.
- * Bits 3 through 7 are optional flags that can be combined and give these
- effects:
- * bit 3 (0x08) - Makes the plant slightly vary placement horizontally
- * bit 4 (0x10) - Makes the plant mesh 1.4x larger
- * bit 5 (0x20) - Moves each face randomly a small bit down (1/8 max)
- * bits 6-7 are reserved for future use.
+ * Bits 3 to 7 are used to enable any number of optional modifiers.
+ Just add the corresponding value(s) below to `param2`:
+ * 8 - Makes the plant slightly vary placement horizontally
+ * 16 - Makes the plant mesh 1.4x larger
+ * 32 - Moves each face randomly a small bit down (1/8 max)
+ * values 64 and 128 (bits 6-7) are reserved for future use.
+ * Example: `param2 = 0` selects a normal "x" shaped plant
+ * Example: `param2 = 17` selects a "+" shaped plant, 1.4x larger (1+16)
* `paramtype2 = "color"`
* `param2` tells which color is picked from the palette.
The palette should have 256 pixels.
@@ -1054,7 +1069,7 @@
There are a bunch of different looking node types.
-Look for examples in `games/minimal` or `games/minetest_game`.
+Look for examples in `games/devtest` or `games/minetest_game`.
* `normal`
* A node-sized cube.
@@ -1278,9 +1293,9 @@
percentage of the screen, ranging in value from `0` to `1`.
The name field is not yet used, but should contain a description of what the
-HUD element represents. The direction field is the direction in which something
-is drawn.
+HUD element represents.
+The `direction` field is the direction in which something is drawn.
`0` draws from left to right, `1` draws from right to left, `2` draws from
top to bottom, and `3` draws from bottom to top.
@@ -1299,7 +1314,21 @@
The `z_index` field specifies the order of HUD elements from back to front.
Lower z-index elements are displayed behind higher z-index elements. Elements
with same z-index are displayed in an arbitrary order. Default 0.
-Supports negative values.
+Supports negative values. By convention, the following values are recommended:
+
+* -400: Graphical effects, such as vignette
+* -300: Name tags, waypoints
+* -200: Wieldhand
+* -100: Things that block the player's view, e.g. masks
+* 0: Default. For standard in-game HUD elements like crosshair, hotbar,
+ minimap, builtin statbars, etc.
+* 100: Temporary text messages or notification icons
+* 1000: Full-screen effects such as full-black screen or credits.
+ This includes effects that cover the entire screen
+* Other: If your HUD element doesn't fit into any category, pick a number
+ between the suggested values
+
+
Below are the specific uses for fields in each type; fields not listed for that
type are ignored.
@@ -1327,15 +1356,21 @@
text. Specify `0xFFFFFF` for white text, `0xFF0000` for red, and so on.
* `alignment`: The alignment of the text.
* `offset`: offset in pixels from position.
+* `size`: size of the text.
+ The player-set font size is multiplied by size.x (y value isn't used).
### `statbar`
-Displays a horizontal bar made up of half-images.
+Displays a horizontal bar made up of half-images with an optional background.
-* `text`: The name of the texture that is used.
+* `text`: The name of the texture to use.
+* `text2`: Optional texture name to enable a background / "off state"
+ texture (useful to visualize the maximal value). Both textures
+ must have the same size.
* `number`: The number of half-textures that are displayed.
If odd, will end with a vertically center-split texture.
-* `direction`
+* `item`: Same as `number` but for the "off state" texture
+* `direction`: To which direction the images will extend to
* `offset`: offset in pixels from position.
* `size`: If used, will force full-image size to this value (override texture
pack image size)
@@ -1354,10 +1389,30 @@
* `name`: The name of the waypoint.
* `text`: Distance suffix. Can be blank.
+* `precision`: Waypoint precision, integer >= 0. Defaults to 10.
+ If set to 0, distance is not shown. Shown value is `floor(distance*precision)/precision`.
+ When the precision is an integer multiple of 10, there will be `log_10(precision)` digits after the decimal point.
+ `precision = 1000`, for example, will show 3 decimal places (eg: `0.999`).
+ `precision = 2` will show multiples of `0.5`; precision = 5 will show multiples of `0.2` and so on:
+ `precision = n` will show multiples of `1/n`
* `number:` An integer containing the RGB value of the color used to draw the
text.
* `world_pos`: World position of the waypoint.
+* `offset`: offset in pixels from position.
+* `alignment`: The alignment of the waypoint.
+
+### `image_waypoint`
+Same as `image`, but does not accept a `position`; the position is instead determined by `world_pos`, the world position of the waypoint.
+
+* `scale`: The scale of the image, with 1 being the original texture size.
+ Only the X coordinate scale is used (positive values).
+ Negative values represent that percentage of the screen it
+ should take; e.g. `x=-100` means 100% (width).
+* `text`: The name of the texture that is displayed.
+* `alignment`: The alignment of the image.
+* `world_pos`: World position of the waypoint.
+* `offset`: offset in pixels from position.
@@ -1611,6 +1666,7 @@
* `2`: the node always gets the digging time 0.5 seconds (rail, sign)
* `3`: the node always gets the digging time 0 seconds (torch)
* `disable_jump`: Player (and possibly other things) cannot jump from node
+ or if their feet are in the node. Note: not supported for `new_move = false`
* `fall_damage_add_percent`: damage speed = `speed * (1 + value/100)`
* `falling_node`: if there is no walkable block under the node it will fall
* `float`: the node will not fall through liquids
@@ -2071,6 +2127,26 @@
* End of a container, following elements are no longer relative to this
container.
+### `scroll_container[,;,;;;]`
+
+* Start of a scroll_container block. All contained elements will ...
+ * take the scroll_container coordinate as position origin,
+ * be additionally moved by the current value of the scrollbar with the name
+ `scrollbar name` times `scroll factor` along the orientation `orientation` and
+ * be clipped to the rectangle defined by `X`, `Y`, `W` and `H`.
+* `orientation`: possible values are `vertical` and `horizontal`.
+* `scroll factor`: optional, defaults to `0.1`.
+* Nesting is possible.
+* Some elements might work a little different if they are in a scroll_container.
+* Note: If you want the scroll_container to actually work, you also need to add a
+ scrollbar element with the specified name. Furthermore, it is highly recommended
+ to use a scrollbaroptions element on this scrollbar.
+
+### `scroll_container_end[]`
+
+* End of a scroll_container, following elements are no longer bound to this
+ container.
+
### `list[;;,;,;]`
* Show an inventory list if it has been sent to the client. Nothing will
@@ -2178,12 +2254,12 @@
* 9-sliced background. See https://en.wikipedia.org/wiki/9-slice_scaling
* Middle is a rect which defines the middle of the 9-slice.
- * `x` - The middle will be x pixels from all sides.
- * `x,y` - The middle will be x pixels from the horizontal and y from the vertical.
- * `x,y,x2,y2` - The middle will start at x,y, and end at x2, y2. Negative x2 and y2 values
- will be added to the width and height of the texture, allowing it to be used as the
- distance from the far end.
- * All numbers in middle are integers.
+ * `x` - The middle will be x pixels from all sides.
+ * `x,y` - The middle will be x pixels from the horizontal and y from the vertical.
+ * `x,y,x2,y2` - The middle will start at x,y, and end at x2, y2. Negative x2 and y2 values
+ will be added to the width and height of the texture, allowing it to be used as the
+ distance from the far end.
+ * All numbers in middle are integers.
* Example for formspec 8x4 in 16x resolution:
image shall be sized 8 times 16px times 4 times 16px
* If `auto_clip` is `true`, the background is clipped to the formspec size
@@ -2332,8 +2408,8 @@
* `name` fieldname data is transferred to Lua
* `caption 1`...: name shown on top of tab
* `current_tab`: index of selected tab 1...
-* `transparent` (optional): show transparent
-* `draw_border` (optional): draw border
+* `transparent` (optional): if true, tabs are semi-transparent
+* `draw_border` (optional): if true, draw a thin line at tab base
### `tabheader[,;;;,,...,;;;]`
@@ -2498,16 +2574,28 @@
* `span=`: number of following columns to affect
(default: infinite).
-### `style[,,...;;;...]`
+### `style[,;;;...]`
-* Set the style for the named element(s) `name`.
+* Set the style for the element(s) matching `selector` by name.
+* `selector` can be one of:
+ * `` - An element name. Includes `*`, which represents every element.
+ * `:` - An element name, a colon, and one or more states.
+* `state` is a list of states separated by the `+` character.
+ * If a state is provided, the style will only take effect when the element is in that state.
+ * All provided states must be active for the style to apply.
* Note: this **must** be before the element is defined.
* See [Styling Formspecs].
-### `style_type[,,...;;;...]`
+### `style_type[,;;;...]`
-* Sets the style for all elements of type(s) `type` which appear after this element.
+* Set the style for the element(s) matching `selector` by type.
+* `selector` can be one of:
+ * `` - An element type. Includes `*`, which represents every element.
+ * `:` - An element type, a colon, and one or more states.
+* `state` is a list of states separated by the `+` character.
+ * If a state is provided, the style will only take effect when the element is in that state.
+ * All provided states must be active for the style to apply.
* See [Styling Formspecs].
Migrating to Real Coordinates
@@ -2550,23 +2638,34 @@
Formspec elements can be themed using the style elements:
- style[,,...;;;...]
- style_type[,,...;;;...]
+ style[,;;;...]
+ style[:,:;;;...]
+ style_type[,;;;...]
+ style_type[:,:;;;...]
Where a prop is:
property_name=property_value
+For example:
+
+ style_type[button;bgcolor=#006699]
+ style[world_delete;bgcolor=red;textcolor=yellow]
+ button[4,3.95;2.6,1;world_delete;Delete]
+
A name/type can optionally be a comma separated list of names/types, like so:
world_delete,world_create,world_configure
button,image_button
-For example:
+A `*` type can be used to select every element in the formspec.
- style_type[button;bgcolor=#006699]
- style[world_delete;bgcolor=red;textcolor=yellow]
- button[4,3.95;2.6,1;world_delete;Delete]
+Any name/type in the list can also be accompanied by a `+`-separated list of states, like so:
+
+ world_delete:hovered+pressed
+ button:pressed
+
+States allow you to apply styles in response to changes in the element, instead of applying at all times.
Setting a property to nothing will reset it to the default value. For example:
@@ -2607,14 +2706,22 @@
* alpha - boolean, whether to draw alpha in bgimg. Default true.
* bgcolor - color, sets button tint.
* bgcolor_hovered - color when hovered. Defaults to a lighter bgcolor when not provided.
+ * This is deprecated, use states instead.
* bgcolor_pressed - color when pressed. Defaults to a darker bgcolor when not provided.
+ * This is deprecated, use states instead.
* bgimg - standard background image. Defaults to none.
* bgimg_hovered - background image when hovered. Defaults to bgimg when not provided.
+ * This is deprecated, use states instead.
* bgimg_middle - Makes the bgimg textures render in 9-sliced mode and defines the middle rect.
- See background9[] documentation for more details
+ See background9[] documentation for more details. This property also pads the
+ button's content when set.
* bgimg_pressed - background image when pressed. Defaults to bgimg when not provided.
+ * This is deprecated, use states instead.
* border - boolean, draw border. Set to false to hide the bevelled button pane. Default true.
+ * content_offset - 2d vector, shifts the position of the button's content without resizing it.
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
+ * padding - rect, adds space between the edges of the button and the content. This value is
+ relative to bgimg_middle.
* textcolor - color, default white.
* checkbox
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
@@ -2638,12 +2745,22 @@
* image_button (additional properties)
* fgimg - standard image. Defaults to none.
* fgimg_hovered - image when hovered. Defaults to fgimg when not provided.
+ * This is deprecated, use states instead.
* fgimg_pressed - image when pressed. Defaults to fgimg when not provided.
+ * This is deprecated, use states instead.
* NOTE: The parameters of any given image_button will take precedence over fgimg/fgimg_pressed
* tabheader
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
* textcolor - color. Default white.
+### Valid States
+
+* *all elements*
+ * default - Equivalent to providing no states
+* button, button_exit, image_button, item_image_button
+ * hovered - Active when the mouse is hovering over the element
+ * pressed - Active when the button is pressed
+
Markup Language
---------------
@@ -2896,6 +3013,24 @@
* `vector.divide(v, x)`:
* Returns a scaled vector or Schur quotient.
+For the following functions `a` is an angle in radians and `r` is a rotation
+vector ({x = , y = , z = }) where pitch, yaw and roll are
+angles in radians.
+
+* `vector.rotate(v, r)`:
+ * Applies the rotation `r` to `v` and returns the result.
+ * `vector.rotate({x = 0, y = 0, z = 1}, r)` and
+ `vector.rotate({x = 0, y = 1, z = 0}, r)` return vectors pointing
+ forward and up relative to an entity's rotation `r`.
+* `vector.rotate_around_axis(v1, v2, a)`:
+ * Returns `v1` rotated around axis `v2` by `a` radians according to
+ the right hand rule.
+* `vector.dir_to_rotation(direction[, up])`:
+ * Returns a rotation vector for `direction` pointing forward using `up`
+ as the up vector.
+ * If `up` is omitted, the roll of the returned vector defaults to zero.
+ * Otherwise `direction` and `up` need to be vectors in a 90 degree angle to each other.
+
@@ -3096,8 +3231,22 @@
`minetest.translate`, but is in translation files.
* `@n` acts as a literal newline as well.
+Server side translations
+------------------------
+
+On some specific cases, server translation could be useful. For example, filter
+a list on labels and send results to client. A method is supplied to achieve
+that:
+
+`minetest.get_translated_string(lang_code, string)`: Translates `string` using
+translations for `lang_code` language. It gives the same result as if the string
+was translated by the client.
+The `lang_code` to use for a given player can be retrieved from
+the table returned by `minetest.get_player_information(name)`.
+IMPORTANT: This functionality should only be used for sorting, filtering or similar purposes.
+You do not need to use this to get translated strings to show up on the client.
Perlin noise
============
@@ -3170,9 +3319,9 @@
preferable for this to be different from other seeds, but sometimes it is useful
to be able to create identical noise patterns.
-When used in mapgen this is actually a 'seed offset', it is added to the
-'world seed' to create the seed used by the noise, to ensure the noise has a
-different pattern in different worlds.
+In some noise APIs the world seed is added to the seed specified in noise
+parameters. This is done to make the resulting noise pattern vary in different
+worlds, and be 'world-specific'.
### `octaves`
@@ -4053,6 +4202,8 @@
area_store_persistent_ids = true,
-- Whether minetest.find_path is functional (5.2.0)
pathfinder_works = true,
+ -- Whether Collision info is available to an objects' on_step (5.3.0)
+ object_step_has_moveresult = true,
}
* `minetest.has_feature(arg)`: returns `boolean, missing_features`
@@ -4064,16 +4215,18 @@
{
address = "127.0.0.1", -- IP address of client
ip_version = 4, -- IPv4 / IPv6
+ connection_uptime = 200, -- seconds since client connected
+ protocol_version = 32, -- protocol version used by client
+ formspec_version = 2, -- supported formspec version
+ lang_code = "fr" -- Language code used for translation
+ -- the following keys can be missing if no stats have been collected yet
min_rtt = 0.01, -- minimum round trip time
max_rtt = 0.2, -- maximum round trip time
avg_rtt = 0.02, -- average round trip time
min_jitter = 0.01, -- minimum packet time jitter
max_jitter = 0.5, -- maximum packet time jitter
avg_jitter = 0.03, -- average packet time jitter
- connection_uptime = 200, -- seconds since client connected
- protocol_version = 32, -- protocol version used by client
- formspec_version = 2, -- supported formspec version
- -- following information is available on debug build only!!!
+ -- the following information is available in a debug build only!!!
-- DO NOT USE IN MODS
--ser_vers = 26, -- serialization version used by client
--major = 0, -- major version number
@@ -4246,7 +4399,7 @@
* Called after generating a piece of world. Modifying nodes inside the area
is a bit faster than usually.
* `minetest.register_on_newplayer(function(ObjectRef))`
- * Called after a new player has been created
+ * Called when a new player enters the world for the first time
* `minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch, tool_capabilities, dir, damage))`
* Called when a player is punched
* Note: This callback is invoked even if the punched player is dead.
@@ -4287,19 +4440,23 @@
* Called _before_ repositioning of player occurs
* return true in func to disable regular player placement
* `minetest.register_on_prejoinplayer(function(name, ip))`
- * Called before a player joins the game
- * If it returns a string, the player is disconnected with that string as
+ * Called when a client connects to the server, prior to authentication
+ * If it returns a string, the client is disconnected with that string as
reason.
-* `minetest.register_on_joinplayer(function(ObjectRef))`
+* `minetest.register_on_joinplayer(function(ObjectRef, last_login))`
* Called when a player joins the game
+ * `last_login`: The timestamp of the previous login, or nil if player is new
* `minetest.register_on_leaveplayer(function(ObjectRef, timed_out))`
* Called when a player leaves the game
* `timed_out`: True for timeout, false for other reasons.
+* `minetest.register_on_authplayer(function(name, ip, is_success))`
+ * Called when a client attempts to log into an account.
+ * `name`: The name of the account being authenticated.
+ * `ip`: The IP address of the client
+ * `is_success`: Whether the client was successfully authenticated
+ * For newly registered accounts, `is_success` will always be true
* `minetest.register_on_auth_fail(function(name, ip))`
- * Called when a client attempts to log into an account but supplies the
- wrong password.
- * `ip`: The IP address of the client.
- * `name`: The account the client attempted to log into.
+ * Deprecated: use `minetest.register_on_authplayer(name, ip, is_success)` instead.
* `minetest.register_on_cheat(function(ObjectRef, cheat))`
* Called when a player cheats
* `cheat`: `{type=}`, where `` is one of:
@@ -4362,7 +4519,7 @@
* The same as before, except that it is called before the player crafts, to
make craft prediction, and it should not change anything.
* `minetest.register_allow_player_inventory_action(function(player, action, inventory, inventory_info))`
- * Determinates how much of a stack may be taken, put or moved to a
+ * Determines how much of a stack may be taken, put or moved to a
player inventory.
* `player` (type `ObjectRef`) is the player who modified the inventory
`inventory` (type `InvRef`).
@@ -4569,8 +4726,11 @@
* Return value: Table with all node positions with a node air above
* Area volume is limited to 4,096,000 nodes
* `minetest.get_perlin(noiseparams)`
+ * Return world-specific perlin noise.
+ * The actual seed used is the noiseparams seed plus the world seed.
* `minetest.get_perlin(seeddiff, octaves, persistence, spread)`
- * Return world-specific perlin noise (`int(worldseed)+seeddiff`)
+ * Deprecated: use `minetest.get_perlin(noiseparams)` instead.
+ * Return world-specific perlin noise.
* `minetest.get_voxel_manip([pos1, pos2])`
* Return voxel manipulator object.
* Loads the manipulator from the map if positions are passed.
@@ -4751,7 +4911,7 @@
* `minetest.add_node_level(pos, level)`
* increase level of leveled node by level, default `level` equals `1`
* if `totallevel > maxlevel`, returns rest (`total-max`)
- * can be negative for decreasing
+ * `level` must be between -127 and 127
* `minetest.fix_light(pos1, pos2)`: returns `true`/`false`
* resets the light in a cuboid-shaped part of
the map and removes lighting bugs.
@@ -5063,6 +5223,20 @@
* Returns a code (0: successful, 1: no such player, 2: player is connected)
* `minetest.remove_player_auth(name)`: remove player authentication data
* Returns boolean indicating success (false if player nonexistant)
+* `minetest.dynamic_add_media(filepath)`
+ * Adds the file at the given path to the media sent to clients by the server
+ on startup and also pushes this file to already connected clients.
+ The file must be a supported image, sound or model format. It must not be
+ modified, deleted, moved or renamed after calling this function.
+ The list of dynamically added media is not persisted.
+ * Returns boolean indicating success (duplicate files count as error)
+ * The media will be ready to use (in e.g. entity textures, sound_play)
+ immediately after calling this function.
+ Old clients that lack support for this feature will not see the media
+ unless they reconnect to the server.
+ * Since media transferred this way does not use client caching or HTTP
+ transfers, dynamic media should not be used with big files or performance
+ will suffer.
Bans
----
@@ -5318,7 +5492,7 @@
* Example: `minetest.rgba(10, 20, 30, 40)`, returns `"#0A141E28"`
* `minetest.encode_base64(string)`: returns string encoded in base64
* Encodes a string in base64.
-* `minetest.decode_base64(string)`: returns string
+* `minetest.decode_base64(string)`: returns string or nil for invalid base64
* Decodes a string encoded in base64.
* `minetest.is_protected(pos, name)`: returns boolean
* Returning `true` restricts the player `name` from modifying (i.e. digging,
@@ -5340,6 +5514,13 @@
* `minetest.record_protection_violation(pos, name)`
* This function calls functions registered with
`minetest.register_on_protection_violation`.
+* `minetest.is_creative_enabled(name)`: returns boolean
+ * Returning `true` means that Creative Mode is enabled for player `name`.
+ * `name` will be `""` for non-players or if the player is unknown.
+ * This function should be overridden by Creative Mode-related mods to
+ implement a per-player Creative Mode.
+ * By default, this function returns `true` if the setting
+ `creative_mode` is `true` and `false` otherwise.
* `minetest.is_area_protected(pos1, pos2, player_name, interval)`
* Returns the position of the first node that `player_name` may not modify
in the specified cuboid between `pos1` and `pos2`.
@@ -5403,8 +5584,8 @@
insecure functions if the calling mod has been listed as trusted in the
`secure.trusted_mods` setting or security is disabled, otherwise returns
`nil`.
- * Only works at init time and must be called from the mod's main scope (not
- from a function).
+ * Only works at init time and must be called from the mod's main scope
+ (ie: the init.lua of the mod, not from another Lua file or within a function).
* **DO NOT ALLOW ANY OTHER MODS TO ACCESS THE RETURNED ENVIRONMENT, STORE
IT IN A LOCAL VARIABLE!**
@@ -5897,15 +6078,18 @@
* max: bubbles bar is not shown
* See [Object properties] for more information
* Is limited to range 0 ... 65535 (2^16 - 1)
-* `set_fov(fov, is_multiplier)`: Sets player's FOV
+* `set_fov(fov, is_multiplier, transition_time)`: Sets player's FOV
* `fov`: FOV value.
* `is_multiplier`: Set to `true` if the FOV value is a multiplier.
Defaults to `false`.
- * Set to 0 to clear FOV override.
-* `get_fov()`:
- * Returns player's FOV override in degrees, and a boolean depending on whether
- the value is a multiplier.
- * Returns 0 as first value if player's FOV hasn't been overridden.
+ * `transition_time`: If defined, enables smooth FOV transition.
+ Interpreted as the time (in seconds) to reach target FOV.
+ If set to 0, FOV change is instantaneous. Defaults to 0.
+ * Set `fov` to 0 to clear FOV override.
+* `get_fov()`: Returns the following:
+ * Server-sent FOV value. Returns 0 if an FOV override doesn't exist.
+ * Boolean indicating whether the FOV value is a multiplier.
+ * Time (in seconds) taken for the FOV transition. Set by `set_fov`.
* `set_attribute(attribute, value)`: DEPRECATED, use get_meta() instead
* Sets an extra attribute with value on player.
* `value` must be a string, or a number which will be converted to a
@@ -5928,13 +6112,14 @@
* `get_formspec_prepend(formspec)`: returns a formspec string.
* `get_player_control()`: returns table with player pressed keys
* The table consists of fields with boolean value representing the pressed
- keys, the fields are jump, right, left, LMB, RMB, sneak, aux1, down, up.
+ keys, the fields are jump, right, left, LMB, RMB, sneak, aux1, down, up, zoom.
* example: `{jump=false, right=true, left=false, LMB=false, RMB=false,
- sneak=true, aux1=false, down=false, up=false}`
+ sneak=true, aux1=false, down=false, up=false, zoom=false}`
+ * The `zoom` field is available since 5.3
* `get_player_control_bits()`: returns integer with bit packed player pressed
keys.
* bit nr/meaning: 0/up, 1/down, 2/left, 3/right, 4/jump, 5/aux1, 6/sneak,
- 7/LMB, 8/RMB
+ 7/LMB, 8/RMB, 9/zoom (zoom available since 5.3)
* `set_physics_override(override_table)`
* `override_table` is a table with the following fields:
* `speed`: multiplier to default walking speed value (default: `1`)
@@ -5992,7 +6177,7 @@
* `sky_color`: A table containing the following values, alpha is ignored:
* `day_sky`: ColorSpec, for the top half of the `"regular"`
sky during the day. (default: `#8cbafa`)
- * `day_horizon`: ColorSpec, for the bottom half of the
+ * `day_horizon`: ColorSpec, for the bottom half of the
`"regular"` sky during the day. (default: `#9bc1f0`)
* `dawn_sky`: ColorSpec, for the top half of the `"regular"`
sky during dawn/sunset. (default: `#b4bafa`)
@@ -6010,7 +6195,7 @@
sky during the night. (default: `#4090ff`)
The resulting sky color will be a dark version of the ColorSpec.
Warning: The darkening of the ColorSpec is subject to change.
- * `indoors`: ColorSpec, for when you're either indoors or
+ * `indoors`: ColorSpec, for when you're either indoors or
underground. Only applies to the `"regular"` sky.
(default: `#646464`)
* `fog_sun_tint`: ColorSpec, changes the fog tinting for the sun
@@ -6054,7 +6239,7 @@
* `parameters` is a table with the following optional fields:
* `visible`: Boolean for whether the stars are visible.
(default: `true`)
- * `count`: Integer number to set the number of stars in
+ * `count`: Integer number to set the number of stars in
the skybox. Only applies to `"skybox"` and `"regular"` sky types.
(default: `1000`)
* `star_color`: ColorSpec, sets the colors of the stars,
@@ -6127,10 +6312,15 @@
-------------
A perlin noise generator.
-It can be created via `PerlinNoise(seed, octaves, persistence, spread)`
-or `PerlinNoise(noiseparams)`.
-Alternatively with `minetest.get_perlin(seeddiff, octaves, persistence, spread)`
-or `minetest.get_perlin(noiseparams)`.
+It can be created via `PerlinNoise()` or `minetest.get_perlin()`.
+For `minetest.get_perlin()`, the actual seed used is the noiseparams seed
+plus the world seed, to create world-specific noise.
+
+`PerlinNoise(noiseparams)`
+`PerlinNoise(seed, octaves, persistence, spread)` (Deprecated).
+
+`minetest.get_perlin(noiseparams)`
+`minetest.get_perlin(seeddiff, octaves, persistence, spread)` (Deprecated).
### Methods
@@ -6144,6 +6334,8 @@
It can be created via `PerlinNoiseMap(noiseparams, size)` or
`minetest.get_perlin_map(noiseparams, size)`.
+For `minetest.get_perlin_map()`, the actual seed used is the noiseparams seed
+plus the world seed, to create world-specific noise.
Format of `size` is `{x=dimx, y=dimy, z=dimz}`. The `z` component is omitted
for 2D noise, and it must be must be larger than 1 for 3D noise (otherwise
@@ -6416,6 +6608,7 @@
automatic_rotate = 0,
-- Set constant rotation in radians per second, positive or negative.
+ -- Object rotates along the local Y-axis, and works with set_rotation.
-- Set to 0 to disable constant rotation.
stepheight = 0,
@@ -6454,6 +6647,12 @@
-- deleted when the block gets unloaded.
-- The get_staticdata() callback is never called then.
-- Defaults to 'true'.
+
+ damage_texture_modifier = "^[brighten",
+ -- Texture modifier to be applied for a short duration when object is hit
+
+ shaded = true,
+ -- Setting this to 'false' disables diffuse lighting of entity
}
Entity definition
@@ -6474,7 +6673,10 @@
on_activate = function(self, staticdata, dtime_s),
- on_step = function(self, dtime),
+ on_step = function(self, dtime, moveresult),
+ -- Called every server step
+ -- dtime: Elapsed time
+ -- moveresult: Table with collision info (only available if physical=true)
on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir),
@@ -6489,6 +6691,25 @@
-- for more info) by using a '_' prefix
}
+Collision info passed to `on_step`:
+
+ {
+ touching_ground = boolean,
+ collides = boolean,
+ standing_on_object = boolean,
+ collisions = {
+ {
+ type = string, -- "node" or "object",
+ axis = string, -- "x", "y" or "z"
+ node_pos = vector, -- if type is "node"
+ object = ObjectRef, -- if type is "object"
+ old_velocity = vector,
+ new_velocity = vector,
+ },
+ ...
+ }
+ }
+
ABM (ActiveBlockModifier) definition
------------------------------------
@@ -6655,6 +6876,8 @@
wield_scale = {x = 1, y = 1, z = 1},
+ -- The default value of 99 may be configured by
+ -- users using the setting "default_stack_max"
stack_max = 99,
range = 4.0,
@@ -6760,7 +6983,7 @@
visual_scale = 1.0,
-- Supported for drawtypes "plantlike", "signlike", "torchlike",
- -- "firelike", "mesh".
+ -- "firelike", "mesh", "nodebox", "allfaces".
-- For plantlike and firelike, the image will start at the bottom of the
-- node. For torchlike, the image will start at the surface to which the
-- node "attaches". For the other drawtypes the image will be centered
@@ -6843,11 +7066,15 @@
-- If true, a new liquid source can be created by placing two or more
-- sources nearby
- leveled = 16,
+ leveled = 0,
-- Only valid for "nodebox" drawtype with 'type = "leveled"'.
-- Allows defining the nodebox height without using param2.
-- The nodebox height is 'leveled' / 64 nodes.
- -- The maximum value of 'leveled' is 127.
+ -- The maximum value of 'leveled' is `leveled_max`.
+
+ leveled_max = 127,
+ -- Maximum value for `leveled` (0-127), enforced in
+ -- `minetest.set_node_level` and `minetest.add_node_level`.
liquid_range = 8, -- Number of flowing nodes around source (max. 8)
@@ -7020,6 +7247,7 @@
-- node is deleted from the world or the drops are added. This is
-- generally the result of either the node being dug or an attached node
-- becoming detached.
+ -- oldmeta is the NodeMetaRef of the oldnode before deletion.
-- drops is a table of ItemStacks, so any metadata to be preserved can
-- be added directly to one or more of the dropped items. See
-- "ItemStackMetaRef".
@@ -7044,10 +7272,14 @@
on_punch = function(pos, node, puncher, pointed_thing),
-- default: minetest.node_punch
+ -- Called when puncher (an ObjectRef) punches the node at pos.
-- By default calls minetest.register_on_punchnode callbacks.
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing),
-- default: nil
+ -- Called when clicker (an ObjectRef) "rightclicks"
+ -- ("rightclick" here stands for the placement key) while pointing at
+ -- the node at pos with 'node' being the node table.
-- itemstack will hold clicker's wielded item.
-- Shall return the leftover itemstack.
-- Note: pointed_thing can be nil, if a mod calls this function.
@@ -7265,6 +7497,10 @@
Used by `minetest.register_biome`.
+The maximum number of biomes that can be used is 65535. However, using an
+excessive number of biomes will slow down map generation. Depending on desired
+performance and computing power the practical limit is much lower.
+
{
name = "tundra",
@@ -7612,6 +7848,8 @@
text = "",
+ text2 = "",
+
number = 2,
item = 3,
@@ -7647,6 +7885,8 @@
size = 1,
-- Scales the visual size of the particle texture.
+ -- If `node` is set, size can be set to 0 to spawn a randomly-sized
+ -- particle (just like actual node dig particles).
collisiondetection = false,
-- If true collides with `walkable` nodes and, depending on the
@@ -7665,6 +7905,7 @@
-- If true faces player using y axis only
texture = "image.png",
+ -- The texture of the particle
playername = "singleplayer",
-- Optional, if specified spawns particle only on the player's client
@@ -7675,6 +7916,17 @@
glow = 0
-- Optional, specify particle self-luminescence in darkness.
-- Values 0-14.
+
+ node = {name = "ignore", param2 = 0},
+ -- Optional, if specified the particle will have the same appearance as
+ -- node dig particles for the given node.
+ -- `texture` and `animation` will be ignored if this is set.
+
+ node_tile = 0,
+ -- Optional, only valid in combination with `node`
+ -- If set to a valid number 1-6, specifies the tile from which the
+ -- particle texture is picked.
+ -- Otherwise, the default behavior is used. (currently: any random tile)
}
@@ -7704,7 +7956,9 @@
maxsize = 1,
-- The particles' properties are random values between the min and max
-- values.
- -- pos, velocity, acceleration, expirationtime, size
+ -- applies to: pos, velocity, acceleration, expirationtime, size
+ -- If `node` is set, min and maxsize can be set to 0 to spawn
+ -- randomly-sized particles (just like actual node dig particles).
collisiondetection = false,
-- If true collide with `walkable` nodes and, depending on the
@@ -7727,6 +7981,7 @@
-- If true face player using y axis only
texture = "image.png",
+ -- The texture of the particle
playername = "singleplayer",
-- Optional, if specified spawns particles only on the player's client
@@ -7737,6 +7992,17 @@
glow = 0
-- Optional, specify particle self-luminescence in darkness.
-- Values 0-14.
+
+ node = {name = "ignore", param2 = 0},
+ -- Optional, if specified the particles will have the same appearance as
+ -- node dig particles for the given node.
+ -- `texture` and `animation` will be ignored if this is set.
+
+ node_tile = 0,
+ -- Optional, only valid in combination with `node`
+ -- If set to a valid number 1-6, specifies the tile from which the
+ -- particle texture is picked.
+ -- Otherwise, the default behavior is used. (currently: any random tile)
}
`HTTPRequest` definition
diff -Nru minetest-5.2.0/doc/menu_lua_api.txt minetest-5.3.0/doc/menu_lua_api.txt
--- minetest-5.2.0/doc/menu_lua_api.txt 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/doc/menu_lua_api.txt 2020-07-09 21:13:20.000000000 +0000
@@ -1,36 +1,55 @@
-Minetest Lua Mainmenu API Reference 5.2.0
+Minetest Lua Mainmenu API Reference 5.3.0
=========================================
Introduction
-------------
+
The main menu is defined as a formspec by Lua in builtin/mainmenu/
Description of formspec language to show your menu is in lua_api.txt
+
Callbacks
---------
-core.buttonhandler(fields): called when a button is pressed.
+
+core.button_handler(fields): called when a button is pressed.
^ fields = {name1 = value1, name2 = value2, ...}
core.event_handler(event)
^ event: "MenuQuit", "KeyEnter", "ExitButton" or "EditBoxEnter"
+
Gamedata
--------
+
The "gamedata" table is read when calling core.start(). It should contain:
{
- playername = ,
- password = ,
- address = ,
- port = ,
- selected_world = , -- 0 for client mode
- singleplayer = ,
+ playername = ,
+ password = ,
+ address = ,
+ port = ,
+ selected_world = , -- 0 for client mode
+ singleplayer = ,
}
+
Functions
---------
+
core.start()
core.close()
+core.get_min_supp_proto()
+^ returns the minimum supported network protocol version
+core.get_max_supp_proto()
+^ returns the maximum supported network protocol version
+core.open_url(url)
+^ opens the URL in a web browser, returns false on failure.
+^ Must begin with http:// or https://
+core.get_version() (possible in async calls)
+^ returns current core version
+
+
+Filesystem
+----------
-Filesystem:
core.get_builtin_path()
^ returns path to builtin root
core.create_dir(absolute_path) (possible in async calls)
@@ -48,12 +67,6 @@
^ zipfile to extract
^ destination folder to extract to
^ returns true/false
-core.download_file(url,target) (possible in async calls)
-^ url to download
-^ target to store to
-^ returns true/false
-core.get_version() (possible in async calls)
-^ returns current core version
core.sound_play(spec, looped) -> handle
^ spec = SimpleSoundSpec (see lua-api.txt)
^ looped = bool
@@ -67,7 +80,82 @@
registered in the core (possible in async calls)
core.get_cache_path() -> path of cache
-Formspec:
+
+HTTP Requests
+-------------
+
+* core.download_file(url, target) (possible in async calls)
+ * url to download, and target to store to
+ * returns true/false
+* `minetest.get_http_api()` (possible in async calls)
+ * returns `HTTPApiTable` containing http functions.
+ * The returned table contains the functions `fetch_sync`, `fetch_async` and
+ `fetch_async_get` described below.
+ * Function only exists if minetest server was built with cURL support.
+* `HTTPApiTable.fetch_sync(HTTPRequest req)`: returns HTTPRequestResult
+ * Performs given request synchronously
+* `HTTPApiTable.fetch_async(HTTPRequest req)`: returns handle
+ * Performs given request asynchronously and returns handle for
+ `HTTPApiTable.fetch_async_get`
+* `HTTPApiTable.fetch_async_get(handle)`: returns HTTPRequestResult
+ * Return response data for given asynchronous HTTP request
+
+### `HTTPRequest` definition
+
+Used by `HTTPApiTable.fetch` and `HTTPApiTable.fetch_async`.
+
+ {
+ url = "http://example.org",
+
+ timeout = 10,
+ -- Timeout for connection in seconds. Default is 3 seconds.
+
+ post_data = "Raw POST request data string" OR {field1 = "data1", field2 = "data2"},
+ -- Optional, if specified a POST request with post_data is performed.
+ -- Accepts both a string and a table. If a table is specified, encodes
+ -- table as x-www-form-urlencoded key-value pairs.
+ -- If post_data is not specified, a GET request is performed instead.
+
+ user_agent = "ExampleUserAgent",
+ -- Optional, if specified replaces the default minetest user agent with
+ -- given string
+
+ extra_headers = { "Accept-Language: en-us", "Accept-Charset: utf-8" },
+ -- Optional, if specified adds additional headers to the HTTP request.
+ -- You must make sure that the header strings follow HTTP specification
+ -- ("Key: Value").
+
+ multipart = boolean
+ -- Optional, if true performs a multipart HTTP request.
+ -- Default is false.
+ }
+
+### `HTTPRequestResult` definition
+
+Passed to `HTTPApiTable.fetch` callback. Returned by
+`HTTPApiTable.fetch_async_get`.
+
+ {
+ completed = true,
+ -- If true, the request has finished (either succeeded, failed or timed
+ -- out)
+
+ succeeded = true,
+ -- If true, the request was successful
+
+ timeout = false,
+ -- If true, the request timed out
+
+ code = 200,
+ -- HTTP status code
+
+ data = "response"
+ }
+
+
+Formspec
+--------
+
core.update_formspec(formspec)
core.get_table_index(tablename) -> index
^ can also handle textlists
@@ -82,7 +170,10 @@
core.set_formspec_prepend(formspec)
^ string to be added to every mainmenu formspec, to be used for theming.
-GUI:
+
+GUI
+---
+
core.set_background(type, texturepath,[tile],[minsize])
^ type: "background", "overlay", "header" or "footer"
^ tile: tile the image instead of scaling (background only)
@@ -102,83 +193,96 @@
^ returns nil or selected file/folder
core.get_screen_info()
^ returns {
- density = ,
- display_width = ,
- display_height = ,
- window_width = ,
- window_height =
- }
+ density = ,
+ display_width = ,
+ display_height = ,
+ window_width = ,
+ window_height =
+ }
+
-### Content and Packages
+Content and Packages
+--------------------
Content - an installed mod, modpack, game, or texture pack (txt)
Package - content which is downloadable from the content db, may or may not be installed.
* core.get_modpath() (possible in async calls)
- * returns path to global modpath
+ * returns path to global modpath
* core.get_clientmodpath() (possible in async calls)
- * returns path to global client-side modpath
+ * returns path to global client-side modpath
* core.get_gamepath() (possible in async calls)
- * returns path to global gamepath
+ * returns path to global gamepath
* core.get_texturepath() (possible in async calls)
- * returns path to default textures
+ * returns path to default textures
* core.get_game(index)
- * returns:
+ * returns:
- {
- id = ,
- path = ,
- gamemods_path = ,
- name = ,
- menuicon_path = ,
- author = "author",
- DEPRECATED:
- addon_mods_paths = {[1] = ,},
- }
+ {
+ id = ,
+ path = ,
+ gamemods_path = ,
+ name = ,
+ menuicon_path = ,
+ author = "author",
+ DEPRECATED:
+ addon_mods_paths = {[1] = ,},
+ }
* core.get_games() -> table of all games in upper format (possible in async calls)
* core.get_content_info(path)
- * returns
+ * returns
- {
- name = "name of content",
- type = "mod" or "modpack" or "game" or "txp",
- description = "description",
- author = "author",
- path = "path/to/content",
- depends = {"mod", "names"}, -- mods only
- optional_depends = {"mod", "names"}, -- mods only
- }
+ {
+ name = "name of content",
+ type = "mod" or "modpack" or "game" or "txp",
+ description = "description",
+ author = "author",
+ path = "path/to/content",
+ depends = {"mod", "names"}, -- mods only
+ optional_depends = {"mod", "names"}, -- mods only
+ }
-Favorites:
+Favorites
+---------
+
core.get_favorites(location) -> list of favorites (possible in async calls)
^ location: "local" or "online"
^ returns {
- [1] = {
- clients = ,
- clients_max = ,
- version = ,
- password = ,
- creative = ,
- damage = ,
- pvp = ,
- description = ,
- name = ,
- address = ,
- port =
- },
+ [1] = {
+ clients = ,
+ clients_max = ,
+ version = ,
+ password = ,
+ creative = ,
+ damage = ,
+ pvp = ,
+ description = ,
+ name = ,
+ address = ,
+ port =
+ clients_list =
+ mods =
+ },
+ ...
}
core.delete_favorite(id, location) -> success
-Logging:
+
+Logging
+-------
+
core.debug(line) (possible in async calls)
^ Always printed to stderr and logfile (print() is redirected here)
core.log(line) (possible in async calls)
core.log(loglevel, line) (possible in async calls)
^ loglevel one of "error", "action", "info", "verbose"
-Settings:
+
+Settings
+--------
+
core.settings:set(name, value)
core.settings:get(name) -> string or nil (possible in async calls)
core.settings:set_bool(name, value)
@@ -188,19 +292,25 @@
For a complete list of methods of the Settings object see
[lua_api.txt](https://github.com/minetest/minetest/blob/master/doc/lua_api.txt)
-Worlds:
+
+Worlds
+------
+
core.get_worlds() -> list of worlds (possible in async calls)
^ returns {
- [1] = {
- path = ,
- name = ,
- gameid = ,
- },
+ [1] = {
+ path = ,
+ name = ,
+ gameid = ,
+ },
}
core.create_world(worldname, gameid)
core.delete_world(index)
-Helpers:
+
+Helpers
+-------
+
core.get_us_time()
^ returns time with microsecond precision
core.gettext(string) -> string
@@ -225,13 +335,10 @@
minetest.decode_base64(string) (possible in async calls)
^ Decodes a string encoded in base64.
-Version compat:
-core.get_min_supp_proto()
-^ returns the minimum supported network protocol version
-core.get_max_supp_proto()
-^ returns the maximum supported network protocol version
-Async:
+Async
+-----
+
core.handle_async(async_job,parameters,finished)
^ execute a function asynchronously
^ async_job is a function receiving one parameter and returning one parameter
@@ -242,11 +349,13 @@
Limitations of Async operations
-No access to global lua variables, don't even try
-Limited set of available functions
- e.g. No access to functions modifying menu like core.start,core.close,
- core.show_path_select_dialog
+ e.g. No access to functions modifying menu like core.start,core.close,
+ core.show_path_select_dialog
+
Background music
----------------
+
The main menu supports background music.
It looks for a `main_menu` sound in `$USER_PATH/sounds`. The same naming
conventions as for normal sounds apply.
diff -Nru minetest-5.2.0/doc/minetest.6 minetest-5.3.0/doc/minetest.6
--- minetest-5.2.0/doc/minetest.6 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/doc/minetest.6 2020-07-09 21:13:20.000000000 +0000
@@ -105,12 +105,12 @@
leveldb, redis, postgresql, and dummy.
.TP
.B \-\-migrate-auth
-Migrate from current auth backend to another. Possible values are sqlite3 and
-files.
+Migrate from current auth backend to another. Possible values are sqlite3,
+leveldb, and files.
.TP
.B \-\-migrate-players
Migrate from current players backend to another. Possible values are sqlite3,
-postgresql, dummy, and files.
+leveldb, postgresql, dummy, and files.
.TP
.B \-\-terminal
Display an interactive terminal over ncurses during execution.
diff -Nru minetest-5.2.0/doc/mkdocs/lua_highlight.patch minetest-5.3.0/doc/mkdocs/lua_highlight.patch
--- minetest-5.2.0/doc/mkdocs/lua_highlight.patch 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/doc/mkdocs/lua_highlight.patch 2020-07-09 21:13:20.000000000 +0000
@@ -1,4 +1,4 @@
-@@ -77,7 +77,7 @@
+@@ -75,7 +75,7 @@
css_class="codehilite", lang=None, style='default',
noclasses=False, tab_length=4, hl_lines=None, use_pygments=True):
self.src = src
@@ -7,13 +7,3 @@
self.linenums = linenums
self.guess_lang = guess_lang
self.css_class = css_class
-@@ -119,7 +119,8 @@
- cssclass=self.css_class,
- style=self.style,
- noclasses=self.noclasses,
-- hl_lines=self.hl_lines)
-+ hl_lines=self.hl_lines,
-+ wrapcode=True)
- return highlight(self.src, lexer, formatter)
- else:
- # just escape and build markup usable by JS highlighting libs
diff -Nru minetest-5.2.0/doc/README.android minetest-5.3.0/doc/README.android
--- minetest-5.2.0/doc/README.android 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/doc/README.android 2020-07-09 21:13:20.000000000 +0000
@@ -1,6 +1,5 @@
-Minetest Android port
-=====================
-Date: 2014 06 28
+Minetest: Android version
+=========================
Controls
--------
@@ -40,25 +39,6 @@
main menu is too big or small on your device, try changing this
value.
-Known issues
-------------
-Not all issues are fixed by now:
-
-* Unable to exit from volume menu -- don't use the volume menu, use Android's
- volume controls instead.
-* 512 MB RAM seems to be inadequate -- this depends on the server you join.
- Try to play on more lightweight servers.
-
-Versioning
-----------
-Android version numbers are 4 digits instead of Minetest's 3 digits. The last
-number of Android's version represents the Android internal version code. This
-version code is strictly incremental. It's incremented for each official
-Minetest Android build.
-
-E.g. prerelease Minetest Android builds have been 0.4.9.3, while the first
-official version most likely will be 0.4.10.4
-
Requirements
------------
@@ -69,9 +49,9 @@
version that was tested at the time this README was drafted; newer/older
versions may or may not work.
-* android SDK (api-26)
-* android NDK (r17c)
-* wget (1.13.4)
+* Android SDK 29
+* Android NDK r21
+* Android Studio 3 [optional]
Additionally, you'll need to have an Internet connection available on the
build system, as the Android build will download some source packages.
@@ -79,16 +59,15 @@
Build
-----
-Debug build:
-* Enter "build/android" subdirectory
-* Execute "make"
-* Answer the questions about where SDK and NDK are located on your filesystem
-* Wait for build to finish
-
-After the build is finished, the resulting apk can be fond in
-build/android/bin/. It will be called Minetest-debug.apk
-
-Release build:
+The new build system Minetest Android is fully functional and is designed to
+speed up and simplify the work, as well as adding the possibility of
+cross-platform build.
+You can use `./gradlew assemblerelease` or `./gradlew assembledebug` from the
+command line or use Android Studio and click the build button.
+
+When using gradlew, the newest NDK will be downloaded and installed
+automatically. Or you can create a `local.properties` file and specify
+`sdk.dir` and `ndk.dir` yourself.
* In order to make a release build you'll have to have a keystore setup to sign
the resulting apk package. How this is done is not part of this README. There
@@ -97,32 +76,6 @@
* Once your keystore is setup, enter build/android subdirectory and create a new
file "ant.properties" there. Add following lines to that file:
-
+
> key.store=
> key.alias=Minetest
-
-* Execute "make release"
-* Enter your keystore as well as your Mintest key password once asked. Be
- careful it's shown on console in clear text!
-* The result can be found at "bin/Minetest-release.apk"
-
-Other things that may be nice to know
-------------
-* The environment for Android development tools is saved within Android build
- build folder. If you want direct access to it do:
-
- > make envpaths
- > . and_env
-
- After you've done this you'll have your path and path variables set correct
- to use adb and all other Android development tools
-
-* You can build a single dependency by calling make and the dependency's name,
- e.g.:
-
- > make irrlicht
-
-* You can completely cleanup a dependency by calling make and the "clean" target,
- e.g.:
-
- > make clean_irrlicht
diff -Nru minetest-5.2.0/doc/texture_packs.txt minetest-5.3.0/doc/texture_packs.txt
--- minetest-5.2.0/doc/texture_packs.txt 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/doc/texture_packs.txt 2020-07-09 21:13:20.000000000 +0000
@@ -64,6 +64,8 @@
* `bubble.png`: the bubble texture when the player is drowning
(default size: 12×12)
+* `bubble_gone.png`: like `bubble.png`, but denotes lack of breath
+ (transparent by default, same size as bubble.png)
* `crack_anylength.png`: node overlay texture when digging
@@ -76,6 +78,8 @@
* `heart.png`: used to display the health points of the player
(default size: 12×12)
+* `heart_gone.png`: like `heart.png`, but denotes lack of health points
+ (transparent by default, same size as heart.png)
* `minimap_mask_round.png`: round minimap mask, white gets replaced by the map
* `minimap_mask_square.png`: mask used for the square minimap
@@ -145,34 +149,51 @@
Texture Overrides
-----------------
-You can override the textures of a node from a texture pack using
-texture overrides. To do this, create a file in a texture pack
-called override.txt
+You can override the textures of nodes and items from a
+texture pack using texture overrides. To do this, create one or
+more files in a texture pack called override.txt
Each line in an override.txt file is a rule. It consists of
- nodename face-selector texture
+ itemname target texture
For example,
default:dirt_with_grass sides default_stone.png
-You can use ^ operators as usual:
+or
+
+ default:sword_steel inventory my_steel_sword.png
+
+You can list multiple targets on one line as a comma-separated list:
+
+ default:tree top,bottom my_special_tree.png
+
+You can use texture modifiers, as usual:
default:dirt_with_grass sides default_stone.png^[brighten
-Here are face selectors you can choose from:
+Finally, if a line is empty or starts with '#' it will be considered
+a comment and not read as a rule. You can use this to better organize
+your override.txt files.
+
+Here are targets you can choose from:
-| face-selector | behavior |
+| target | behavior |
|---------------|---------------------------------------------------|
-| left | x- |
-| right | x+ |
-| front | z- |
-| back | z+ |
-| top | y+ |
-| bottom | y- |
-| sides | x-, x+, z-, z+ |
+| left | x- face |
+| right | x+ face |
+| front | z- face |
+| back | z+ face |
+| top | y+ face |
+| bottom | y- face |
+| sides | x-, x+, z-, z+ faces |
| all | All faces. You can also use '*' instead of 'all'. |
+| inventory | The inventory texture |
+| wield | The texture used when held by the player |
+
+Nodes support all targets, but other items only support 'inventory'
+and 'wield'
Designing leaves textures for the leaves rendering options
----------------------------------------------------------
diff -Nru minetest-5.2.0/Dockerfile minetest-5.3.0/Dockerfile
--- minetest-5.2.0/Dockerfile 2020-04-05 17:47:01.000000000 +0000
+++ minetest-5.3.0/Dockerfile 2020-07-09 21:13:20.000000000 +0000
@@ -1,32 +1,59 @@
-FROM debian:stretch
+FROM alpine:3.11
-USER root
-RUN apt-get update -y && \
- apt-get -y install build-essential libirrlicht-dev cmake libbz2-dev libpng-dev libjpeg-dev \
- libsqlite3-dev libcurl4-gnutls-dev zlib1g-dev libgmp-dev libjsoncpp-dev git
+ENV MINETEST_GAME_VERSION master
-COPY . /usr/src/minetest
-
-RUN mkdir -p /usr/src/minetest/cmakebuild && cd /usr/src/minetest/cmakebuild && \
- cmake -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_BUILD_TYPE=Release -DRUN_IN_PLACE=FALSE \
+COPY .git /usr/src/minetest/.git
+COPY CMakeLists.txt /usr/src/minetest/CMakeLists.txt
+COPY README.md /usr/src/minetest/README.md
+COPY minetest.conf.example /usr/src/minetest/minetest.conf.example
+COPY builtin /usr/src/minetest/builtin
+COPY cmake /usr/src/minetest/cmake
+COPY doc /usr/src/minetest/doc
+COPY fonts /usr/src/minetest/fonts
+COPY lib /usr/src/minetest/lib
+COPY misc /usr/src/minetest/misc
+COPY po /usr/src/minetest/po
+COPY src /usr/src/minetest/src
+COPY textures /usr/src/minetest/textures
+
+WORKDIR /usr/src/minetest
+
+RUN apk add --no-cache git build-base irrlicht-dev cmake bzip2-dev libpng-dev \
+ jpeg-dev libxxf86vm-dev mesa-dev sqlite-dev libogg-dev \
+ libvorbis-dev openal-soft-dev curl-dev freetype-dev zlib-dev \
+ gmp-dev jsoncpp-dev postgresql-dev ca-certificates && \
+ git clone --depth=1 -b ${MINETEST_GAME_VERSION} https://github.com/minetest/minetest_game.git ./games/minetest_game && \
+ rm -fr ./games/minetest_game/.git
+
+WORKDIR /usr/src/
+RUN git clone --recursive https://github.com/jupp0r/prometheus-cpp/ && \
+ mkdir prometheus-cpp/build && \
+ cd prometheus-cpp/build && \
+ cmake .. \
+ -DCMAKE_INSTALL_PREFIX=/usr/local \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DENABLE_TESTING=0 && \
+ make -j2 && \
+ make install
+
+WORKDIR /usr/src/minetest
+RUN mkdir build && \
+ cd build && \
+ cmake .. \
+ -DCMAKE_INSTALL_PREFIX=/usr/local \
+ -DCMAKE_BUILD_TYPE=Release \
-DBUILD_SERVER=TRUE \
- -DBUILD_CLIENT=FALSE \
- -DENABLE_SYSTEM_JSONCPP=1 \
- .. && \
- make -j2 && \
- rm -Rf ../games/minetest_game && git clone --depth 1 https://github.com/minetest/minetest_game ../games/minetest_game && \
- rm -Rf ../games/minetest_game/.git && \
- make install
-
-FROM debian:stretch
-
-USER root
-RUN groupadd minetest && useradd -m -g minetest -d /var/lib/minetest minetest && \
- apt-get update -y && \
- apt-get -y install libcurl3-gnutls libjsoncpp1 liblua5.1-0 libluajit-5.1-2 libpq5 libsqlite3-0 \
- libstdc++6 zlib1g libc6 && \
- apt-get clean && rm -rf /var/cache/apt/archives/* && \
- rm -rf /var/lib/apt/lists/*
+ -DENABLE_PROMETHEUS=TRUE \
+ -DBUILD_UNITTESTS=FALSE \
+ -DBUILD_CLIENT=FALSE && \
+ make -j2 && \
+ make install
+
+FROM alpine:3.11
+
+RUN apk add --no-cache sqlite-libs curl gmp libstdc++ libgcc libpq && \
+ adduser -D minetest --uid 30000 -h /var/lib/minetest && \
+ chown -R minetest:minetest /var/lib/minetest
WORKDIR /var/lib/minetest
@@ -34,8 +61,8 @@
COPY --from=0 /usr/local/bin/minetestserver /usr/local/bin/minetestserver
COPY --from=0 /usr/local/share/doc/minetest/minetest.conf.example /etc/minetest/minetest.conf
-USER minetest
+USER minetest:minetest
-EXPOSE 30000/udp
+EXPOSE 30000/udp 30000/tcp
CMD ["/usr/local/bin/minetestserver", "--config", "/etc/minetest/minetest.conf"]
diff -Nru minetest-5.2.0/games/devtest/game.conf minetest-5.3.0/games/devtest/game.conf
--- minetest-5.2.0/games/devtest/game.conf 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/game.conf 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,2 @@
+name = Development Test
+description = Testing environment to help with testing the engine features of Minetest. It can also be helpful in mod development.
diff -Nru minetest-5.2.0/games/devtest/LICENSE.txt minetest-5.3.0/games/devtest/LICENSE.txt
--- minetest-5.2.0/games/devtest/LICENSE.txt 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/LICENSE.txt 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,4 @@
+License information for Development Test
+----------------------------------------
+
+The same license as for Minetest applies.
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/menu/background.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/menu/background.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/menu/header.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/menu/header.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/menu/icon.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/menu/icon.png differ
diff -Nru minetest-5.2.0/games/devtest/mods/basenodes/init.lua minetest-5.3.0/games/devtest/mods/basenodes/init.lua
--- minetest-5.2.0/games/devtest/mods/basenodes/init.lua 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/basenodes/init.lua 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,334 @@
+local WATER_ALPHA = 160
+local WATER_VISC = 1
+local LAVA_VISC = 7
+
+--
+-- Node definitions
+--
+
+-- Register nodes
+
+minetest.register_node("basenodes:stone", {
+ description = "Stone",
+ tiles = {"default_stone.png"},
+ groups = {cracky=3},
+})
+
+minetest.register_node("basenodes:desert_stone", {
+ description = "Desert Stone",
+ tiles = {"default_desert_stone.png"},
+ groups = {cracky=3},
+})
+
+minetest.register_node("basenodes:dirt_with_grass", {
+ description = "Dirt with Grass",
+ tiles ={"default_grass.png",
+ -- a little dot on the bottom to distinguish it from dirt
+ "default_dirt.png^basenodes_dirt_with_grass_bottom.png",
+ {name = "default_dirt.png^default_grass_side.png",
+ tileable_vertical = false}},
+ groups = {crumbly=3, soil=1},
+})
+
+minetest.register_node("basenodes:dirt_with_snow", {
+ description = "Dirt with Snow",
+ tiles ={"basenodes_dirt_with_snow.png",
+ -- a little dot on the bottom to distinguish it from dirt
+ "default_dirt.png^basenodes_dirt_with_snow_bottom.png",
+ {name = "default_dirt.png^default_snow_side.png",
+ tileable_vertical = false}},
+ groups = {crumbly=3, soil=1},
+})
+
+minetest.register_node("basenodes:dirt", {
+ description = "Dirt",
+ tiles ={"default_dirt.png"},
+ groups = {crumbly=3, soil=1},
+})
+
+minetest.register_node("basenodes:sand", {
+ description = "Sand",
+ tiles ={"default_sand.png"},
+ groups = {crumbly=3},
+})
+
+minetest.register_node("basenodes:desert_sand", {
+ description = "Desert Sand",
+ tiles ={"default_desert_sand.png"},
+ groups = {crumbly=3},
+})
+
+minetest.register_node("basenodes:gravel", {
+ description = "Gravel",
+ tiles ={"default_gravel.png"},
+ groups = {crumbly=2},
+})
+
+minetest.register_node("basenodes:junglegrass", {
+ description = "Jungle Grass",
+ drawtype = "plantlike",
+ tiles ={"default_junglegrass.png"},
+ inventory_image = "default_junglegrass.png",
+ wield_image = "default_junglegrass.png",
+ paramtype = "light",
+ walkable = false,
+ groups = {snappy=3},
+})
+
+minetest.register_node("basenodes:tree", {
+ description = "Normal Tree Trunk",
+ tiles = {"default_tree_top.png", "default_tree_top.png", "default_tree.png"},
+ is_ground_content = false,
+ groups = {choppy=2,oddly_breakable_by_hand=1},
+})
+
+minetest.register_node("basenodes:leaves", {
+ description = "Normal Leaves",
+ drawtype = "allfaces_optional",
+ tiles = {"default_leaves.png"},
+ paramtype = "light",
+ is_ground_content = false,
+ groups = {snappy=3},
+})
+
+minetest.register_node("basenodes:jungletree", {
+ description = "Jungle Tree Trunk",
+ tiles = {"default_jungletree_top.png", "default_jungletree_top.png", "default_jungletree.png"},
+ is_ground_content = false,
+ groups = {choppy=2,oddly_breakable_by_hand=1},
+})
+
+minetest.register_node("basenodes:jungleleaves", {
+ description = "Jungle Leaves",
+ drawtype = "allfaces_optional",
+ tiles = {"default_jungleleaves.png"},
+ paramtype = "light",
+ is_ground_content = false,
+ groups = {snappy=3},
+})
+
+minetest.register_node("basenodes:pine_tree", {
+ description = "Pine Tree Trunk",
+ tiles = {"default_pine_tree_top.png", "default_pine_tree_top.png", "default_pine_tree.png"},
+ is_ground_content = false,
+ groups = {choppy=2,oddly_breakable_by_hand=1},
+})
+
+minetest.register_node("basenodes:pine_needles", {
+ description = "Pine Needles",
+ drawtype = "allfaces_optional",
+ tiles = {"default_pine_needles.png"},
+ paramtype = "light",
+ is_ground_content = false,
+ groups = {snappy=3},
+})
+
+minetest.register_node("basenodes:water_source", {
+ description = "Water Source",
+ drawtype = "liquid",
+ tiles = {"default_water.png"},
+ special_tiles = {
+ {name = "default_water.png", backface_culling = false},
+ {name = "default_water.png", backface_culling = true},
+ },
+ alpha = WATER_ALPHA,
+ paramtype = "light",
+ walkable = false,
+ pointable = false,
+ diggable = false,
+ buildable_to = true,
+ is_ground_content = false,
+ drowning = 1,
+ liquidtype = "source",
+ liquid_alternative_flowing = "basenodes:water_flowing",
+ liquid_alternative_source = "basenodes:water_source",
+ liquid_viscosity = WATER_VISC,
+ post_effect_color = {a = 64, r = 100, g = 100, b = 200},
+ groups = {water = 3, liquid = 3},
+})
+
+minetest.register_node("basenodes:water_flowing", {
+ description = "Flowing Water",
+ drawtype = "flowingliquid",
+ tiles = {"default_water_flowing.png"},
+ special_tiles = {
+ {name = "default_water_flowing.png", backface_culling = false},
+ {name = "default_water_flowing.png", backface_culling = false},
+ },
+ alpha = WATER_ALPHA,
+ paramtype = "light",
+ paramtype2 = "flowingliquid",
+ walkable = false,
+ pointable = false,
+ diggable = false,
+ buildable_to = true,
+ is_ground_content = false,
+ drowning = 1,
+ liquidtype = "flowing",
+ liquid_alternative_flowing = "basenodes:water_flowing",
+ liquid_alternative_source = "basenodes:water_source",
+ liquid_viscosity = WATER_VISC,
+ post_effect_color = {a = 64, r = 100, g = 100, b = 200},
+ groups = {water = 3, liquid = 3},
+})
+
+minetest.register_node("basenodes:river_water_source", {
+ description = "River Water Source",
+ drawtype = "liquid",
+ tiles = { "default_river_water.png" },
+ special_tiles = {
+ {name = "default_river_water.png", backface_culling = false},
+ {name = "default_river_water.png", backface_culling = true},
+ },
+ alpha = WATER_ALPHA,
+ paramtype = "light",
+ walkable = false,
+ pointable = false,
+ diggable = false,
+ buildable_to = true,
+ is_ground_content = false,
+ drowning = 1,
+ liquidtype = "source",
+ liquid_alternative_flowing = "basenodes:river_water_flowing",
+ liquid_alternative_source = "basenodes:river_water_source",
+ liquid_viscosity = 1,
+ liquid_renewable = false,
+ liquid_range = 2,
+ post_effect_color = {a = 103, r = 30, g = 76, b = 90},
+ groups = {water = 3, liquid = 3, },
+})
+
+minetest.register_node("basenodes:river_water_flowing", {
+ description = "Flowing River Water",
+ drawtype = "flowingliquid",
+ tiles = {"default_river_water_flowing.png"},
+ special_tiles = {
+ {name = "default_river_water_flowing.png", backface_culling = false},
+ {name = "default_river_water_flowing.png", backface_culling = false},
+ },
+ alpha = WATER_ALPHA,
+ paramtype = "light",
+ paramtype2 = "flowingliquid",
+ walkable = false,
+ pointable = false,
+ diggable = false,
+ buildable_to = true,
+ is_ground_content = false,
+ drowning = 1,
+ liquidtype = "flowing",
+ liquid_alternative_flowing = "basenodes:river_water_flowing",
+ liquid_alternative_source = "basenodes:river_water_source",
+ liquid_viscosity = 1,
+ liquid_renewable = false,
+ liquid_range = 2,
+ post_effect_color = {a = 103, r = 30, g = 76, b = 90},
+ groups = {water = 3, liquid = 3, },
+})
+
+minetest.register_node("basenodes:lava_flowing", {
+ description = "Flowing Lava",
+ drawtype = "flowingliquid",
+ tiles = {"default_lava_flowing.png"},
+ special_tiles = {
+ {name="default_lava_flowing.png", backface_culling = false},
+ {name="default_lava_flowing.png", backface_culling = false},
+ },
+ paramtype = "light",
+ light_source = minetest.LIGHT_MAX,
+ walkable = false,
+ pointable = false,
+ diggable = false,
+ buildable_to = true,
+ is_ground_content = false,
+ drowning = 1,
+ damage_per_second = 4,
+ liquidtype = "flowing",
+ liquid_alternative_flowing = "basenodes:lava_flowing",
+ liquid_alternative_source = "basenodes:lava_source",
+ liquid_viscosity = LAVA_VISC,
+ post_effect_color = {a=192, r=255, g=64, b=0},
+ groups = {lava=3, liquid=1},
+})
+
+minetest.register_node("basenodes:lava_source", {
+ description = "Lava Source",
+ drawtype = "liquid",
+ tiles = { "default_lava.png" },
+ special_tiles = {
+ {name = "default_lava.png", backface_culling = false},
+ {name = "default_lava.png", backface_culling = true},
+ },
+ paramtype = "light",
+ light_source = minetest.LIGHT_MAX,
+ walkable = false,
+ pointable = false,
+ diggable = false,
+ buildable_to = true,
+ is_ground_content = false,
+ drowning = 1,
+ damage_per_second = 4,
+ liquidtype = "source",
+ liquid_alternative_flowing = "basenodes:lava_flowing",
+ liquid_alternative_source = "basenodes:lava_source",
+ liquid_viscosity = LAVA_VISC,
+ post_effect_color = {a=192, r=255, g=64, b=0},
+ groups = {lava=3, liquid=1},
+})
+
+minetest.register_node("basenodes:cobble", {
+ description = "Cobblestone",
+ tiles ={"default_cobble.png"},
+ is_ground_content = false,
+ groups = {cracky=3},
+})
+
+minetest.register_node("basenodes:mossycobble", {
+ description = "Mossy Cobblestone",
+ tiles ={"default_mossycobble.png"},
+ is_ground_content = false,
+ groups = {cracky=3},
+})
+
+minetest.register_node("basenodes:apple", {
+ description = "Apple",
+ drawtype = "plantlike",
+ tiles ={"default_apple.png"},
+ inventory_image = "default_apple.png",
+ paramtype = "light",
+ is_ground_content = false,
+ sunlight_propagates = true,
+ walkable = false,
+ groups = {dig_immediate=3},
+
+ -- Make eatable because why not?
+ on_use = minetest.item_eat(2),
+})
+
+minetest.register_node("basenodes:ice", {
+ description = "Ice",
+ tiles ={"default_ice.png"},
+ groups = {cracky=3},
+})
+
+-- The snow nodes intentionally have different tints to make them more
+-- distinguishable
+minetest.register_node("basenodes:snow", {
+ description = "Snow Sheet",
+ tiles = {"basenodes_snow_sheet.png"},
+ groups = {crumbly=3},
+ walkable = false,
+ paramtype = "light",
+ drawtype = "nodebox",
+ node_box = {
+ type = "fixed",
+ fixed = {-0.5, -0.5, -0.5, 0.5, -0.25, 0.5},
+ },
+})
+
+minetest.register_node("basenodes:snowblock", {
+ description = "Snow Block",
+ tiles ={"default_snow.png"},
+ groups = {crumbly=3},
+})
+
+
diff -Nru minetest-5.2.0/games/devtest/mods/basenodes/mod.conf minetest-5.3.0/games/devtest/mods/basenodes/mod.conf
--- minetest-5.2.0/games/devtest/mods/basenodes/mod.conf 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/basenodes/mod.conf 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,2 @@
+name = basenodes
+description = Contains basic nodes for mapgen
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/basenodes_dirt_with_grass_bottom.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/basenodes_dirt_with_grass_bottom.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/basenodes_dirt_with_snow_bottom.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/basenodes_dirt_with_snow_bottom.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/basenodes_dirt_with_snow.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/basenodes_dirt_with_snow.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/basenodes_snow_sheet.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/basenodes_snow_sheet.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/default_apple.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/default_apple.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/default_cobble.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/default_cobble.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/default_desert_sand.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/default_desert_sand.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/default_desert_stone.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/default_desert_stone.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/default_dirt.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/default_dirt.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/default_grass.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/default_grass.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/default_grass_side.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/default_grass_side.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/default_gravel.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/default_gravel.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/default_ice.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/default_ice.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/default_junglegrass.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/default_junglegrass.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/default_jungleleaves.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/default_jungleleaves.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/default_jungletree.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/default_jungletree.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/default_jungletree_top.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/default_jungletree_top.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/default_lava_flowing.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/default_lava_flowing.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/default_lava.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/default_lava.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/default_leaves.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/default_leaves.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/default_mossycobble.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/default_mossycobble.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/default_pine_needles.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/default_pine_needles.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/default_pine_tree.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/default_pine_tree.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/default_pine_tree_top.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/default_pine_tree_top.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/default_river_water_flowing.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/default_river_water_flowing.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/default_river_water.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/default_river_water.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/default_sand.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/default_sand.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/default_snow.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/default_snow.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/default_snow_side.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/default_snow_side.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/default_stone.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/default_stone.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/default_tree.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/default_tree.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/default_tree_top.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/default_tree_top.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/default_water_flowing.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/default_water_flowing.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basenodes/textures/default_water.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basenodes/textures/default_water.png differ
diff -Nru minetest-5.2.0/games/devtest/mods/basetools/init.lua minetest-5.3.0/games/devtest/mods/basetools/init.lua
--- minetest-5.2.0/games/devtest/mods/basetools/init.lua 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/basetools/init.lua 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,296 @@
+--
+-- Tool definitions
+--
+
+--[[ TOOLS SUMMARY:
+
+Tool types:
+
+* Hand: basic tool/weapon (just for convenience, not optimized for testing)
+* Pickaxe: dig cracky
+* Axe: dig choppy
+* Shovel: dig crumbly
+* Shears: dig snappy
+* Sword: deal damage
+* Dagger: deal damage, but faster
+
+Tool materials:
+
+* Dirt: dig nodes of rating 3, one use only
+* Wood: dig nodes of rating 3
+* Stone: dig nodes of rating 3 or 2
+* Steel: dig nodes of rating 3, 2 or 1
+* Mese: dig "everything" instantly
+]]
+
+-- The hand
+minetest.register_item(":", {
+ type = "none",
+ wield_image = "wieldhand.png",
+ wield_scale = {x=1,y=1,z=2.5},
+ tool_capabilities = {
+ full_punch_interval = 1.0,
+ max_drop_level = 0,
+ groupcaps = {
+ crumbly = {times={[3]=1.50}, uses=0, maxlevel=0},
+ snappy = {times={[3]=1.50}, uses=0, maxlevel=0},
+ oddly_breakable_by_hand = {times={[1]=7.00,[2]=4.00,[3]=2.00}, uses=0, maxlevel=0},
+ },
+ damage_groups = {fleshy=1},
+ }
+})
+
+-- Mese Pickaxe: special tool that digs "everything" instantly
+minetest.register_tool("basetools:pick_mese", {
+ description = "Mese Pickaxe",
+ inventory_image = "basetools_mesepick.png",
+ tool_capabilities = {
+ full_punch_interval = 1.0,
+ max_drop_level=3,
+ groupcaps={
+ cracky={times={[1]=0.0, [2]=0.0, [3]=0.0}, maxlevel=255},
+ crumbly={times={[1]=0.0, [2]=0.0, [3]=0.0}, maxlevel=255},
+ snappy={times={[1]=0.0, [2]=0.0, [3]=0.0}, maxlevel=255},
+ choppy={times={[1]=0.0, [2]=0.0, [3]=0.0}, maxlevel=255},
+ dig_immediate={times={[1]=0.0, [2]=0.0, [3]=0.0}, maxlevel=255},
+ },
+ damage_groups = {fleshy=100},
+ },
+})
+
+
+--
+-- Pickaxes: Dig cracky
+--
+
+-- This should break after only 1 use
+minetest.register_tool("basetools:pick_dirt", {
+ description = "Dirt Pickaxe",
+ inventory_image = "basetools_dirtpick.png",
+ tool_capabilities = {
+ max_drop_level=0,
+ groupcaps={
+ cracky={times={[3]=2.00}, uses=1, maxlevel=0}
+ },
+ },
+})
+
+minetest.register_tool("basetools:pick_wood", {
+ description = "Wooden Pickaxe",
+ inventory_image = "basetools_woodpick.png",
+ tool_capabilities = {
+ max_drop_level=0,
+ groupcaps={
+ cracky={times={[3]=2.00}, uses=30, maxlevel=0}
+ },
+ },
+})
+minetest.register_tool("basetools:pick_stone", {
+ description = "Stone Pickaxe",
+ inventory_image = "basetools_stonepick.png",
+ tool_capabilities = {
+ max_drop_level=0,
+ groupcaps={
+ cracky={times={[2]=1.20, [3]=0.80}, uses=60, maxlevel=0}
+ },
+ },
+})
+minetest.register_tool("basetools:pick_steel", {
+ description = "Steel Pickaxe",
+ inventory_image = "basetools_steelpick.png",
+ tool_capabilities = {
+ max_drop_level=1,
+ groupcaps={
+ cracky={times={[1]=4.00, [2]=1.60, [3]=1.00}, uses=90, maxlevel=0}
+ },
+ },
+})
+minetest.register_tool("basetools:pick_steel_l1", {
+ description = "Steel Pickaxe Level 1",
+ inventory_image = "basetools_steelpick_l1.png",
+ tool_capabilities = {
+ max_drop_level=1,
+ groupcaps={
+ cracky={times={[1]=4.00, [2]=1.60, [3]=1.00}, uses=90, maxlevel=1}
+ },
+ },
+})
+minetest.register_tool("basetools:pick_steel_l2", {
+ description = "Steel Pickaxe Level 2",
+ inventory_image = "basetools_steelpick_l2.png",
+ tool_capabilities = {
+ max_drop_level=1,
+ groupcaps={
+ cracky={times={[1]=4.00, [2]=1.60, [3]=1.00}, uses=90, maxlevel=2}
+ },
+ },
+})
+
+--
+-- Shovels (dig crumbly)
+--
+
+minetest.register_tool("basetools:shovel_wood", {
+ description = "Wooden Shovel",
+ inventory_image = "basetools_woodshovel.png",
+ tool_capabilities = {
+ max_drop_level=0,
+ groupcaps={
+ crumbly={times={[3]=0.50}, uses=30, maxlevel=0}
+ },
+ },
+})
+minetest.register_tool("basetools:shovel_stone", {
+ description = "Stone Shovel",
+ inventory_image = "basetools_stoneshovel.png",
+ tool_capabilities = {
+ max_drop_level=0,
+ groupcaps={
+ crumbly={times={[2]=0.50, [3]=0.30}, uses=60, maxlevel=0}
+ },
+ },
+})
+minetest.register_tool("basetools:shovel_steel", {
+ description = "Steel Shovel",
+ inventory_image = "basetools_steelshovel.png",
+ tool_capabilities = {
+ max_drop_level=1,
+ groupcaps={
+ crumbly={times={[1]=1.00, [2]=0.70, [3]=0.60}, uses=90, maxlevel=0}
+ },
+ },
+})
+
+--
+-- Axes (dig choppy)
+--
+
+minetest.register_tool("basetools:axe_wood", {
+ description = "Wooden Axe",
+ inventory_image = "basetools_woodaxe.png",
+ tool_capabilities = {
+ max_drop_level=0,
+ groupcaps={
+ choppy={times={[3]=0.80}, uses=30, maxlevel=0},
+ },
+ },
+})
+minetest.register_tool("basetools:axe_stone", {
+ description = "Stone Axe",
+ inventory_image = "basetools_stoneaxe.png",
+ tool_capabilities = {
+ max_drop_level=0,
+ groupcaps={
+ choppy={times={[2]=1.00, [3]=0.60}, uses=60, maxlevel=0},
+ },
+ },
+})
+minetest.register_tool("basetools:axe_steel", {
+ description = "Steel Axe",
+ inventory_image = "basetools_steelaxe.png",
+ tool_capabilities = {
+ max_drop_level=1,
+ groupcaps={
+ choppy={times={[1]=2.00, [2]=0.80, [3]=0.40}, uses=90, maxlevel=0},
+ },
+ },
+})
+
+--
+-- Shears (dig snappy)
+--
+
+minetest.register_tool("basetools:shears_wood", {
+ description = "Wooden Shears",
+ inventory_image = "basetools_woodshears.png",
+ tool_capabilities = {
+ max_drop_level=0,
+ groupcaps={
+ snappy={times={[3]=1.00}, uses=30, maxlevel=0},
+ },
+ },
+})
+minetest.register_tool("basetools:shears_stone", {
+ description = "Stone Shears",
+ inventory_image = "basetools_stoneshears.png",
+ tool_capabilities = {
+ max_drop_level=0,
+ groupcaps={
+ snappy={times={[2]=1.00, [3]=0.50}, uses=60, maxlevel=0},
+ },
+ },
+})
+minetest.register_tool("basetools:shears_steel", {
+ description = "Steel Shears",
+ inventory_image = "basetools_steelshears.png",
+ tool_capabilities = {
+ max_drop_level=1,
+ groupcaps={
+ snappy={times={[1]=1.00, [2]=0.50, [3]=0.25}, uses=90, maxlevel=0},
+ },
+ },
+})
+
+--
+-- Swords (deal damage)
+--
+
+minetest.register_tool("basetools:sword_wood", {
+ description = "Wooden Sword",
+ inventory_image = "basetools_woodsword.png",
+ tool_capabilities = {
+ full_punch_interval = 1.0,
+ damage_groups = {fleshy=2},
+ }
+})
+minetest.register_tool("basetools:sword_stone", {
+ description = "Stone Sword",
+ inventory_image = "basetools_stonesword.png",
+ tool_capabilities = {
+ full_punch_interval = 1.0,
+ max_drop_level=0,
+ damage_groups = {fleshy=4},
+ }
+})
+minetest.register_tool("basetools:sword_steel", {
+ description = "Steel Sword",
+ inventory_image = "basetools_steelsword.png",
+ tool_capabilities = {
+ full_punch_interval = 1.0,
+ max_drop_level=1,
+ damage_groups = {fleshy=6},
+ }
+})
+
+-- Fire/Ice sword: Deal damage to non-fleshy damage groups
+minetest.register_tool("basetools:sword_fire", {
+ description = "Fire Sword",
+ inventory_image = "basetools_firesword.png",
+ tool_capabilities = {
+ full_punch_interval = 1.0,
+ max_drop_level=0,
+ damage_groups = {icy=6},
+ }
+})
+minetest.register_tool("basetools:sword_ice", {
+ description = "Ice Sword",
+ inventory_image = "basetools_icesword.png",
+ tool_capabilities = {
+ full_punch_interval = 1.0,
+ max_drop_level=0,
+ damage_groups = {firy=6},
+ }
+})
+
+--
+-- Dagger: Low damage, fast punch interval
+--
+minetest.register_tool("basetools:dagger_steel", {
+ description = "Steel Dagger",
+ inventory_image = "basetools_steeldagger.png",
+ tool_capabilities = {
+ full_punch_interval = 0.5,
+ max_drop_level=0,
+ damage_groups = {fleshy=2},
+ }
+})
diff -Nru minetest-5.2.0/games/devtest/mods/basetools/mod.conf minetest-5.3.0/games/devtest/mods/basetools/mod.conf
--- minetest-5.2.0/games/devtest/mods/basetools/mod.conf 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/basetools/mod.conf 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,2 @@
+name = basetools
+description = Contains basic digging tools
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basetools/textures/basetools_dirtpick.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basetools/textures/basetools_dirtpick.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basetools/textures/basetools_firesword.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basetools/textures/basetools_firesword.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basetools/textures/basetools_icesword.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basetools/textures/basetools_icesword.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basetools/textures/basetools_mesepick.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basetools/textures/basetools_mesepick.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basetools/textures/basetools_steelaxe.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basetools/textures/basetools_steelaxe.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basetools/textures/basetools_steeldagger.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basetools/textures/basetools_steeldagger.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basetools/textures/basetools_steelpick_l1.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basetools/textures/basetools_steelpick_l1.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basetools/textures/basetools_steelpick_l2.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basetools/textures/basetools_steelpick_l2.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basetools/textures/basetools_steelpick.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basetools/textures/basetools_steelpick.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basetools/textures/basetools_steelshears.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basetools/textures/basetools_steelshears.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basetools/textures/basetools_steelshovel.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basetools/textures/basetools_steelshovel.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basetools/textures/basetools_steelsword.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basetools/textures/basetools_steelsword.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basetools/textures/basetools_stoneaxe.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basetools/textures/basetools_stoneaxe.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basetools/textures/basetools_stonepick.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basetools/textures/basetools_stonepick.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basetools/textures/basetools_stoneshears.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basetools/textures/basetools_stoneshears.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basetools/textures/basetools_stoneshovel.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basetools/textures/basetools_stoneshovel.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basetools/textures/basetools_stonesword.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basetools/textures/basetools_stonesword.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basetools/textures/basetools_woodaxe.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basetools/textures/basetools_woodaxe.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basetools/textures/basetools_woodpick.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basetools/textures/basetools_woodpick.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basetools/textures/basetools_woodshears.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basetools/textures/basetools_woodshears.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basetools/textures/basetools_woodshovel.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basetools/textures/basetools_woodshovel.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/basetools/textures/basetools_woodsword.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/basetools/textures/basetools_woodsword.png differ
diff -Nru minetest-5.2.0/games/devtest/mods/bucket/init.lua minetest-5.3.0/games/devtest/mods/bucket/init.lua
--- minetest-5.2.0/games/devtest/mods/bucket/init.lua 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/bucket/init.lua 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,26 @@
+-- Bucket: Punch liquid source or flowing liquid to collect it
+
+minetest.register_tool("bucket:bucket", {
+ description = "Bucket",
+ inventory_image = "bucket.png",
+ stack_max = 1,
+ liquids_pointable = true,
+ groups = { disable_repair = 1 },
+ on_use = function(itemstack, user, pointed_thing)
+ -- Must be pointing to node
+ if pointed_thing.type ~= "node" then
+ return
+ end
+ -- Check if pointing to a liquid
+ local n = minetest.get_node(pointed_thing.under)
+ local def = minetest.registered_nodes[n.name]
+ if def ~= nil and (def.liquidtype == "source" or def.liquidtype == "flowing") then
+ minetest.add_node(pointed_thing.under, {name="air"})
+ local inv = user:get_inventory()
+ if inv then
+ inv:add_item("main", ItemStack(n.name))
+ end
+ end
+ end,
+})
+
diff -Nru minetest-5.2.0/games/devtest/mods/bucket/mod.conf minetest-5.3.0/games/devtest/mods/bucket/mod.conf
--- minetest-5.2.0/games/devtest/mods/bucket/mod.conf 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/bucket/mod.conf 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,2 @@
+name = bucket
+description = Minimal bucket to pick up liquids
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/bucket/textures/bucket_lava.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/bucket/textures/bucket_lava.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/bucket/textures/bucket.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/bucket/textures/bucket.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/bucket/textures/bucket_water.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/bucket/textures/bucket_water.png differ
diff -Nru minetest-5.2.0/games/devtest/mods/chest/init.lua minetest-5.3.0/games/devtest/mods/chest/init.lua
--- minetest-5.2.0/games/devtest/mods/chest/init.lua 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/chest/init.lua 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,27 @@
+minetest.register_node("chest:chest", {
+ description = "Chest",
+ tiles ={"chest_chest.png^[sheet:2x2:0,0", "chest_chest.png^[sheet:2x2:0,0",
+ "chest_chest.png^[sheet:2x2:1,0", "chest_chest.png^[sheet:2x2:1,0",
+ "chest_chest.png^[sheet:2x2:1,0", "chest_chest.png^[sheet:2x2:0,1"},
+ paramtype2 = "facedir",
+ groups = {dig_immediate=2,choppy=3},
+ is_ground_content = false,
+ on_construct = function(pos)
+ local meta = minetest.get_meta(pos)
+ meta:set_string("formspec",
+ "size[8,9]"..
+ "list[current_name;main;0,0;8,4;]"..
+ "list[current_player;main;0,5;8,4;]" ..
+ "listring[]")
+ meta:set_string("infotext", "Chest")
+ local inv = meta:get_inventory()
+ inv:set_size("main", 8*4)
+ end,
+ can_dig = function(pos,player)
+ local meta = minetest.get_meta(pos);
+ local inv = meta:get_inventory()
+ return inv:is_empty("main")
+ end,
+})
+
+
diff -Nru minetest-5.2.0/games/devtest/mods/chest/mod.conf minetest-5.3.0/games/devtest/mods/chest/mod.conf
--- minetest-5.2.0/games/devtest/mods/chest/mod.conf 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/chest/mod.conf 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,2 @@
+name = chest
+description = A simple chest to store items
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/chest/textures/chest_chest.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/chest/textures/chest_chest.png differ
diff -Nru minetest-5.2.0/games/devtest/mods/chest_of_everything/init.lua minetest-5.3.0/games/devtest/mods/chest_of_everything/init.lua
--- minetest-5.2.0/games/devtest/mods/chest_of_everything/init.lua 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/chest_of_everything/init.lua 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,135 @@
+local F = minetest.formspec_escape
+
+-- Create a detached inventory
+local inv_everything = minetest.create_detached_inventory("everything", {
+ allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
+ return 0
+ end,
+ allow_put = function(inv, listname, index, stack, player)
+ return 0
+ end,
+ allow_take = function(inv, listname, index, stack, player)
+ return -1
+ end,
+})
+local inv_trash = minetest.create_detached_inventory("trash", {
+ allow_take = function(inv, listname, index, stack, player)
+ return 0
+ end,
+ allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
+ return 0
+ end,
+ on_put = function(inv, listname, index, stack, player)
+ inv:set_list("main", {})
+ end,
+})
+inv_trash:set_size("main", 1)
+
+local max_page = 1
+
+local function get_chest_formspec(page)
+ local start = 0 + (page-1)*32
+ return "size[8,9]"..
+ "list[detached:everything;main;0,0;8,4;"..start.."]"..
+ "list[current_player;main;0,5;8,4;]" ..
+ "label[6,4;Trash:]" ..
+ "list[detached:trash;main;7,4;1,1]" ..
+ "button[0,4;1,1;chest_of_everything_prev;"..F("<").."]"..
+ "button[1,4;1,1;chest_of_everything_next;"..F(">").."]"..
+ "label[2,4;"..F("Page: "..page).."]"..
+ "listring[detached:everything;main]"..
+ "listring[current_player;main]"..
+ "listring[detached:trash;main]"
+end
+
+minetest.register_node("chest_of_everything:chest", {
+ description = "Chest of Everything",
+ tiles ={"chest_of_everything_chest.png^[sheet:2x2:0,0", "chest_of_everything_chest.png^[sheet:2x2:0,0",
+ "chest_of_everything_chest.png^[sheet:2x2:1,0", "chest_of_everything_chest.png^[sheet:2x2:1,0",
+ "chest_of_everything_chest.png^[sheet:2x2:1,0", "chest_of_everything_chest.png^[sheet:2x2:0,1"},
+ paramtype2 = "facedir",
+ groups = {dig_immediate=2,choppy=3},
+ is_ground_content = false,
+ on_construct = function(pos)
+ local meta = minetest.get_meta(pos)
+ meta:set_string("infotext", "Chest of Everything")
+ meta:set_int("page", 1)
+ meta:set_string("formspec", get_chest_formspec(1))
+ end,
+ on_receive_fields = function(pos, formname, fields, sender)
+ if formname == "" then
+ local meta = minetest.get_meta(pos)
+ local page = meta:get_int("page")
+ if fields.chest_of_everything_prev then
+ page = page - 1
+ elseif fields.chest_of_everything_next then
+ page = page + 1
+ end
+ if page < 1 then
+ page = 1
+ end
+ if page > max_page then
+ page = max_page
+ end
+ meta:set_int("page", page)
+ meta:set_string("formspec", get_chest_formspec(page))
+ end
+ end,
+})
+
+minetest.register_on_mods_loaded(function()
+ local items = {}
+ for itemstring,_ in pairs(minetest.registered_items) do
+ if itemstring ~= "" and itemstring ~= "unknown" and itemstring ~= "ignore" then
+ table.insert(items, itemstring)
+ end
+ end
+ --[[ Sort items in this order:
+ * Chest of Everything
+ * Test tools
+ * Other tools
+ * Craftitems
+ * Other items
+ * Dummy items ]]
+ local function compare(item1, item2)
+ local def1 = minetest.registered_items[item1]
+ local def2 = minetest.registered_items[item2]
+ local tool1 = def1.type == "tool"
+ local tool2 = def2.type == "tool"
+ local testtool1 = minetest.get_item_group(item1, "testtool") == 1
+ local testtool2 = minetest.get_item_group(item2, "testtool") == 1
+ local dummy1 = minetest.get_item_group(item1, "dummy") == 1
+ local dummy2 = minetest.get_item_group(item2, "dummy") == 1
+ local craftitem1 = def1.type == "craft"
+ local craftitem2 = def2.type == "craft"
+ if item1 == "chest_of_everything:chest" then
+ return true
+ elseif item2 == "chest_of_everything:chest" then
+ return false
+ elseif dummy1 and not dummy2 then
+ return false
+ elseif not dummy1 and dummy2 then
+ return true
+ elseif testtool1 and not testtool2 then
+ return true
+ elseif not testtool1 and testtool2 then
+ return false
+ elseif tool1 and not tool2 then
+ return true
+ elseif not tool1 and tool2 then
+ return false
+ elseif craftitem1 and not craftitem2 then
+ return true
+ elseif not craftitem1 and craftitem2 then
+ return false
+ else
+ return item1 < item2
+ end
+ end
+ table.sort(items, compare)
+ inv_everything:set_size("main", #items)
+ max_page = math.ceil(#items / 32)
+ for i=1, #items do
+ inv_everything:add_item("main", items[i])
+ end
+end)
diff -Nru minetest-5.2.0/games/devtest/mods/chest_of_everything/mod.conf minetest-5.3.0/games/devtest/mods/chest_of_everything/mod.conf
--- minetest-5.2.0/games/devtest/mods/chest_of_everything/mod.conf 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/chest_of_everything/mod.conf 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,2 @@
+name = chest_of_everything
+description = Adds the chest of everything from which you can take all items
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/chest_of_everything/textures/chest_of_everything_chest.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/chest_of_everything/textures/chest_of_everything_chest.png differ
diff -Nru minetest-5.2.0/games/devtest/mods/dignodes/init.lua minetest-5.3.0/games/devtest/mods/dignodes/init.lua
--- minetest-5.2.0/games/devtest/mods/dignodes/init.lua 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/dignodes/init.lua 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,37 @@
+local groups = {
+ "cracky", "dig_immediate"
+}
+
+-- Register dig nodes with 1 digging group, a rating between 1-3 and a level between 0-2
+for g=1, #groups do
+ local gr = groups[g]
+ for r=1, 3 do
+ for l=0, 2 do
+ if not (gr=="dig_immediate" and (l>0 or r==1)) then
+ local d
+ if l > 0 then
+ d = string.format("Dig Test Node: %s=%d, level=%d", gr, r, l)
+ else
+ d = string.format("Dig Test Node: %s=%d", gr, r)
+ end
+ local tile = "dignodes_"..gr..".png^dignodes_rating"..r..".png"
+ if l==1 then
+ tile = tile .. "^[colorize:#FFFF00:127"
+ elseif l==2 then
+ tile = tile .. "^[colorize:#FF0000:127"
+ end
+ minetest.register_node("dignodes:"..gr.."_"..r.."_"..l, {
+ description = d,
+ tiles = { tile },
+ groups = { [gr] = r, level = l },
+ })
+ end
+ end
+ end
+end
+
+-- Node without any digging groups
+minetest.register_node("dignodes:none", {
+ description = "Dig Test Node: groupless",
+ tiles = {"dignodes_none.png"},
+})
diff -Nru minetest-5.2.0/games/devtest/mods/dignodes/mod.conf minetest-5.3.0/games/devtest/mods/dignodes/mod.conf
--- minetest-5.2.0/games/devtest/mods/dignodes/mod.conf 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/dignodes/mod.conf 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,2 @@
+name = dignodes
+description = Nodes with different digging groups
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/dignodes/textures/dignodes_choppy.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/dignodes/textures/dignodes_choppy.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/dignodes/textures/dignodes_cracky.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/dignodes/textures/dignodes_cracky.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/dignodes/textures/dignodes_crumbly.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/dignodes/textures/dignodes_crumbly.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/dignodes/textures/dignodes_dig_immediate.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/dignodes/textures/dignodes_dig_immediate.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/dignodes/textures/dignodes_none.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/dignodes/textures/dignodes_none.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/dignodes/textures/dignodes_rating1.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/dignodes/textures/dignodes_rating1.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/dignodes/textures/dignodes_rating2.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/dignodes/textures/dignodes_rating2.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/dignodes/textures/dignodes_rating3.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/dignodes/textures/dignodes_rating3.png differ
diff -Nru minetest-5.2.0/games/devtest/mods/experimental/commands.lua minetest-5.3.0/games/devtest/mods/experimental/commands.lua
--- minetest-5.2.0/games/devtest/mods/experimental/commands.lua 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/experimental/commands.lua 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,216 @@
+minetest.register_chatcommand("test_inv", {
+ params = "",
+ description = "Test: Modify player's inventory formspec",
+ func = function(name, param)
+ local player = minetest.get_player_by_name(name)
+ if not player then
+ return false, "No player."
+ end
+ player:set_inventory_formspec(
+ "size[13,7.5]"..
+ "image[6,0.6;1,2;player.png]"..
+ "list[current_player;main;5,3.5;8,4;]"..
+ "list[current_player;craft;8,0;3,3;]"..
+ "list[current_player;craftpreview;12,1;1,1;]"..
+ "list[detached:test_inventory;main;0,0;4,6;0]"..
+ "button[0.5,7;2,1;button1;Button 1]"..
+ "button_exit[2.5,7;2,1;button2;Exit Button]")
+ return true, "Done."
+ end,
+})
+
+minetest.register_chatcommand("test_bulk_set_node", {
+ params = "",
+ description = "Test: Bulk-set 9×9×9 stone nodes",
+ func = function(name, param)
+ local player = minetest.get_player_by_name(name)
+ if not player then
+ return false, "No player."
+ end
+ local pos_list = {}
+ local ppos = player:get_pos()
+ local i = 1
+ for x=2,10 do
+ for y=2,10 do
+ for z=2,10 do
+ pos_list[i] = {x=ppos.x + x,y = ppos.y + y,z = ppos.z + z}
+ i = i + 1
+ end
+ end
+ end
+ minetest.bulk_set_node(pos_list, {name = "mapgen_stone"})
+ return true, "Done."
+ end,
+})
+
+minetest.register_chatcommand("bench_bulk_set_node", {
+ params = "",
+ description = "Benchmark: Bulk-set 99×99×99 stone nodes",
+ func = function(name, param)
+ local player = minetest.get_player_by_name(name)
+ if not player then
+ return false, "No player."
+ end
+ local pos_list = {}
+ local ppos = player:get_pos()
+ local i = 1
+ for x=2,100 do
+ for y=2,100 do
+ for z=2,100 do
+ pos_list[i] = {x=ppos.x + x,y = ppos.y + y,z = ppos.z + z}
+ i = i + 1
+ end
+ end
+ end
+
+ minetest.chat_send_player(name, "Benchmarking minetest.bulk_set_node. Warming up ...");
+
+ -- warm up with stone to prevent having different callbacks
+ -- due to different node topology
+ minetest.bulk_set_node(pos_list, {name = "mapgen_stone"})
+
+ minetest.chat_send_player(name, "Warming up finished, now benchmarking ...");
+
+ local start_time = minetest.get_us_time()
+ for i=1,#pos_list do
+ minetest.set_node(pos_list[i], {name = "mapgen_stone"})
+ end
+ local middle_time = minetest.get_us_time()
+ minetest.bulk_set_node(pos_list, {name = "mapgen_stone"})
+ local end_time = minetest.get_us_time()
+ local msg = string.format("Benchmark results: minetest.set_node loop: %.2f ms; minetest.bulk_set_node: %.2f ms",
+ ((middle_time - start_time)) / 1000,
+ ((end_time - middle_time)) / 1000
+ )
+ return true, msg
+ end,
+})
+
+local function advance_pos(pos, start_pos, advance_z)
+ if advance_z then
+ pos.z = pos.z + 2
+ pos.x = start_pos.x
+ else
+ pos.x = pos.x + 2
+ end
+ if pos.x > 30900 or pos.x - start_pos.x > 46 then
+ pos.x = start_pos.x
+ pos.z = pos.z + 2
+ end
+ if pos.z > 30900 then
+ -- We ran out of space! Aborting
+ aborted = true
+ return false
+ end
+ return pos
+end
+
+local function place_nodes(param)
+ local nodes = param.nodes
+ local name = param.name
+ local pos = param.pos
+ local start_pos = param.start_pos
+ table.sort(nodes)
+ minetest.chat_send_player(name, "Placing nodes …")
+ local nodes_placed = 0
+ local aborted = false
+ for n=1, #nodes do
+ local itemstring = nodes[n]
+ local def = minetest.registered_nodes[itemstring]
+ local p2_max = 0
+ if param.param ~= "no_param2" then
+ -- Also test the param2 values of the nodes
+ -- ... but we only use permissible param2 values
+ if def.paramtype2 == "wallmounted" then
+ p2_max = 5
+ elseif def.paramtype2 == "facedir" then
+ p2_max = 23
+ elseif def.paramtype2 == "glasslikeliquidlevel" then
+ p2_max = 63
+ elseif def.paramtype2 == "meshoptions" and def.drawtype == "plantlike" then
+ p2_max = 63
+ elseif def.paramtype2 == "leveled" then
+ p2_max = 127
+ elseif def.paramtype2 == "degrotate" and def.drawtype == "plantlike" then
+ p2_max = 179
+ elseif def.paramtype2 == "colorfacedir" or
+ def.paramtype2 == "colorwallmounted" or
+ def.paramtype2 == "color" then
+ p2_max = 255
+ end
+ end
+ for p2 = 0, p2_max do
+ -- Skip undefined param2 values
+ if not ((def.paramtype2 == "meshoptions" and p2 % 8 > 4) or
+ (def.paramtype2 == "colorwallmounted" and p2 % 8 > 5) or
+ (def.paramtype2 == "colorfacedir" and p2 % 32 > 23)) then
+
+ minetest.set_node(pos, { name = itemstring, param2 = p2 })
+ nodes_placed = nodes_placed + 1
+ pos = advance_pos(pos, start_pos)
+ if not pos then
+ aborted = true
+ break
+ end
+ end
+ end
+ if aborted then
+ break
+ end
+ end
+ if aborted then
+ minetest.chat_send_player(name, "Not all nodes could be placed, please move further away from the world boundary. Nodes placed: "..nodes_placed)
+ end
+ minetest.chat_send_player(name, "Nodes placed: "..nodes_placed..".")
+end
+
+local function after_emerge(blockpos, action, calls_remaining, param)
+ if calls_remaining == 0 then
+ place_nodes(param)
+ end
+end
+
+minetest.register_chatcommand("test_place_nodes", {
+ params = "[ no_param2 ]",
+ description = "Test: Place all non-experimental nodes and optionally their permissible param2 variants",
+ func = function(name, param)
+ local player = minetest.get_player_by_name(name)
+ if not player then
+ return false, "No player."
+ end
+ local pos = vector.floor(player:get_pos())
+ pos.x = math.ceil(pos.x + 3)
+ pos.z = math.ceil(pos.z + 3)
+ pos.y = math.ceil(pos.y + 1)
+ local start_pos = table.copy(pos)
+ if pos.x > 30800 then
+ return false, "Too close to world boundary (+X). Please move to X < 30800."
+ end
+ if pos.z > 30800 then
+ return false, "Too close to world boundary (+Z). Please move to Z < 30800."
+ end
+
+ local aborted = false
+ local nodes = {}
+ local emerge_estimate = 0
+ for itemstring, def in pairs(minetest.registered_nodes) do
+ if itemstring ~= "ignore" and string.sub(itemstring, 1, 13) ~= "experimental:" then
+ table.insert(nodes, itemstring)
+ if def.paramtype2 == 0 then
+ emerge_estimate = emerge_estimate + 1
+ else
+ emerge_estimate = emerge_estimate + 255
+ end
+ end
+ end
+ -- Emerge area to make sure that all nodes are being placed.
+ -- Note we will emerge much more than we need to (overestimation),
+ -- the estimation code could be improved performance-wise …
+ local length = 16 + math.ceil(emerge_estimate / 24) * 2
+ minetest.emerge_area(start_pos,
+ { x = start_pos.x + 46, y = start_pos.y, z = start_pos.z + length },
+ after_emerge, { nodes = nodes, name = name, pos = pos, start_pos = start_pos, param = param })
+ return true, "Emerging area …"
+ end,
+})
+
diff -Nru minetest-5.2.0/games/devtest/mods/experimental/detached.lua minetest-5.3.0/games/devtest/mods/experimental/detached.lua
--- minetest-5.2.0/games/devtest/mods/experimental/detached.lua 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/experimental/detached.lua 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,29 @@
+-- Create a detached inventory
+local inv = minetest.create_detached_inventory("test_inventory", {
+ allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
+ experimental.print_to_everything("allow move asked")
+ return count -- Allow all
+ end,
+ allow_put = function(inv, listname, index, stack, player)
+ experimental.print_to_everything("allow put asked")
+ return 1 -- Allow only 1
+ end,
+ allow_take = function(inv, listname, index, stack, player)
+ experimental.print_to_everything("allow take asked")
+ return 4 -- Allow 4 at max
+ end,
+ on_move = function(inv, from_list, from_index, to_list, to_index, count, player)
+ experimental.print_to_everything(player:get_player_name().." moved items")
+ end,
+ on_put = function(inv, listname, index, stack, player)
+ experimental.print_to_everything(player:get_player_name().." put items")
+ end,
+ on_take = function(inv, listname, index, stack, player)
+ experimental.print_to_everything(player:get_player_name().." took items")
+ end,
+})
+inv:set_size("main", 4*6)
+inv:add_item("main", "experimental:callback_node")
+inv:add_item("main", "experimental:particle_spawner")
+
+
diff -Nru minetest-5.2.0/games/devtest/mods/experimental/init.lua minetest-5.3.0/games/devtest/mods/experimental/init.lua
--- minetest-5.2.0/games/devtest/mods/experimental/init.lua 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/experimental/init.lua 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,23 @@
+--
+-- Experimental things
+--
+
+experimental = {}
+
+dofile(minetest.get_modpath("experimental").."/detached.lua")
+dofile(minetest.get_modpath("experimental").."/items.lua")
+dofile(minetest.get_modpath("experimental").."/commands.lua")
+
+function experimental.print_to_everything(msg)
+ minetest.log("action", msg)
+ minetest.chat_send_all(msg)
+end
+
+minetest.log("info", "[experimental] modname="..dump(minetest.get_current_modname()))
+minetest.log("info", "[experimental] modpath="..dump(minetest.get_modpath("experimental")))
+minetest.log("info", "[experimental] worldpath="..dump(minetest.get_worldpath()))
+
+
+minetest.register_on_mods_loaded(function()
+ minetest.log("action", "[experimental] on_mods_loaded()")
+end)
diff -Nru minetest-5.2.0/games/devtest/mods/experimental/items.lua minetest-5.3.0/games/devtest/mods/experimental/items.lua
--- minetest-5.2.0/games/devtest/mods/experimental/items.lua 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/experimental/items.lua 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,103 @@
+minetest.register_node("experimental:callback_node", {
+ description = "Callback Test Node (construct/destruct/timer)",
+ tiles = {"experimental_callback_node.png"},
+ groups = {dig_immediate=3},
+ -- This was known to cause a bug in minetest.item_place_node() when used
+ -- via minetest.place_node(), causing a placer with no position
+ paramtype2 = "facedir",
+ drop = "",
+
+ on_construct = function(pos)
+ experimental.print_to_everything("experimental:callback_node:on_construct("..minetest.pos_to_string(pos)..")")
+ local meta = minetest.get_meta(pos)
+ meta:set_string("mine", "test")
+ local timer = minetest.get_node_timer(pos)
+ timer:start(4, 3)
+ end,
+
+ after_place_node = function(pos, placer)
+ experimental.print_to_everything("experimental:callback_node:after_place_node("..minetest.pos_to_string(pos)..")")
+ local meta = minetest.get_meta(pos)
+ if meta:get_string("mine") == "test" then
+ experimental.print_to_everything("correct metadata found")
+ else
+ experimental.print_to_everything("incorrect metadata found")
+ end
+ end,
+
+ on_destruct = function(pos)
+ experimental.print_to_everything("experimental:callback_node:on_destruct("..minetest.pos_to_string(pos)..")")
+ end,
+
+ after_destruct = function(pos)
+ experimental.print_to_everything("experimental:callback_node:after_destruct("..minetest.pos_to_string(pos)..")")
+ end,
+
+ after_dig_node = function(pos, oldnode, oldmetadata, digger)
+ experimental.print_to_everything("experimental:callback_node:after_dig_node("..minetest.pos_to_string(pos)..")")
+ end,
+
+ on_timer = function(pos, elapsed)
+ experimental.print_to_everything("on_timer(): elapsed="..dump(elapsed))
+ return true
+ end,
+})
+
+minetest.register_tool("experimental:privatizer", {
+ description = "Node Meta Privatizer",
+ inventory_image = "experimental_tester_tool_1.png",
+ groups = { testtool = 1, disable_repair = 1 },
+ on_use = function(itemstack, user, pointed_thing)
+ if pointed_thing.type == "node" then
+ local node = minetest.get_node(pointed_thing.under)
+ if node.name == "chest:chest" then
+ local p = pointed_thing.under
+ minetest.log("action", "Privatizer used at "..minetest.pos_to_string(p))
+ minetest.get_meta(p):mark_as_private({"infotext", "formspec"})
+ if user and user:is_player() then
+ minetest.chat_send_player(user:get_player_name(), "Chest metadata (infotext, formspec) set private!")
+ end
+ return
+ end
+ end
+ if user and user:is_player() then
+ minetest.chat_send_player(user:get_player_name(), "Privatizer can only be used on chest!")
+ end
+ end,
+})
+
+minetest.register_tool("experimental:particle_spawner", {
+ description = "Particle Spawner",
+ inventory_image = "experimental_tester_tool_1.png^[invert:g",
+ groups = { testtool = 1, disable_repair = 1 },
+ on_use = function(itemstack, user, pointed_thing)
+ local pos = minetest.get_pointed_thing_position(pointed_thing, true)
+ if pos == nil then
+ if user then
+ pos = user:get_pos()
+ end
+ end
+ pos = vector.add(pos, {x=0, y=0.5, z=0})
+ local tex, anim
+ if math.random(0, 1) == 0 then
+ tex = "experimental_particle_sheet.png"
+ anim = {type="sheet_2d", frames_w=3, frames_h=2, frame_length=0.5}
+ else
+ tex = "experimental_particle_vertical.png"
+ anim = {type="vertical_frames", aspect_w=16, aspect_h=16, length=3.3}
+ end
+
+ minetest.add_particle({
+ pos = pos,
+ velocity = {x=0, y=0, z=0},
+ acceleration = {x=0, y=0.04, z=0},
+ expirationtime = 6,
+ collisiondetection = true,
+ texture = tex,
+ animation = anim,
+ size = 4,
+ glow = math.random(0, 5),
+ })
+ end,
+})
+
diff -Nru minetest-5.2.0/games/devtest/mods/experimental/mod.conf minetest-5.3.0/games/devtest/mods/experimental/mod.conf
--- minetest-5.2.0/games/devtest/mods/experimental/mod.conf 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/experimental/mod.conf 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,2 @@
+name = experimental
+description = Chaotic mod containing unstructured tests for testing out engine features. The features in this mod should be moved to other mods.
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/experimental/textures/experimental_callback_node.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/experimental/textures/experimental_callback_node.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/experimental/textures/experimental_particle_sheet.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/experimental/textures/experimental_particle_sheet.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/experimental/textures/experimental_particle_vertical.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/experimental/textures/experimental_particle_vertical.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/experimental/textures/experimental_tester_tool_1.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/experimental/textures/experimental_tester_tool_1.png differ
diff -Nru minetest-5.2.0/games/devtest/mods/give_initial_stuff/init.lua minetest-5.3.0/games/devtest/mods/give_initial_stuff/init.lua
--- minetest-5.2.0/games/devtest/mods/give_initial_stuff/init.lua 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/give_initial_stuff/init.lua 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,37 @@
+local give_if_not_gotten_already = function(inv, list, item)
+ if not inv:contains_item(list, item) then
+ inv:add_item(list, item)
+ end
+end
+
+local give_initial_stuff = function(player)
+ local inv = player:get_inventory()
+ give_if_not_gotten_already(inv, "main", "basetools:pick_mese")
+ give_if_not_gotten_already(inv, "main", "basetools:axe_steel")
+ give_if_not_gotten_already(inv, "main", "basetools:shovel_steel")
+ give_if_not_gotten_already(inv, "main", "bucket:bucket")
+ give_if_not_gotten_already(inv, "main", "testnodes:light14")
+ give_if_not_gotten_already(inv, "main", "chest_of_everything:chest")
+ minetest.log("action", "[give_initial_stuff] Giving initial stuff to "..player:get_player_name())
+end
+
+minetest.register_on_newplayer(function(player)
+ if minetest.settings:get_bool("give_initial_stuff", true) then
+ give_initial_stuff(player)
+ end
+end)
+
+minetest.register_chatcommand("stuff", {
+ params = "",
+ privs = { give = true },
+ description = "Give yourself initial items",
+ func = function(name, param)
+ local player = minetest.get_player_by_name(name)
+ if not player or not player:is_player() then
+ return false, "No player."
+ end
+ give_initial_stuff(player)
+ return true
+ end,
+})
+
diff -Nru minetest-5.2.0/games/devtest/mods/give_initial_stuff/mod.conf minetest-5.3.0/games/devtest/mods/give_initial_stuff/mod.conf
--- minetest-5.2.0/games/devtest/mods/give_initial_stuff/mod.conf 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/give_initial_stuff/mod.conf 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,3 @@
+name = give_initial_stuff
+description = Gives items to players on join
+depends = basetools, bucket, chest_of_everything, testnodes
diff -Nru minetest-5.2.0/games/devtest/mods/initial_message/init.lua minetest-5.3.0/games/devtest/mods/initial_message/init.lua
--- minetest-5.2.0/games/devtest/mods/initial_message/init.lua 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/initial_message/init.lua 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,9 @@
+minetest.register_on_joinplayer(function(player)
+ local cb = function(player)
+ if not player or not player:is_player() then
+ return
+ end
+ minetest.chat_send_player(player:get_player_name(), "This is the \"Development Test\" [devtest], meant only for testing and development. Use Minetest Game for the real thing.")
+ end
+ minetest.after(2.0, cb, player)
+end)
diff -Nru minetest-5.2.0/games/devtest/mods/initial_message/mod.conf minetest-5.3.0/games/devtest/mods/initial_message/mod.conf
--- minetest-5.2.0/games/devtest/mods/initial_message/mod.conf 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/initial_message/mod.conf 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,2 @@
+name = initial_message
+description = Show message to joining players explaining what this testing game is about
diff -Nru minetest-5.2.0/games/devtest/mods/mapgen/init.lua minetest-5.3.0/games/devtest/mods/mapgen/init.lua
--- minetest-5.2.0/games/devtest/mods/mapgen/init.lua 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/mapgen/init.lua 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,104 @@
+--
+-- Aliases for map generator outputs
+--
+
+-- ESSENTIAL node aliases
+-- Basic nodes
+minetest.register_alias("mapgen_stone", "basenodes:stone")
+minetest.register_alias("mapgen_water_source", "basenodes:water_source")
+minetest.register_alias("mapgen_river_water_source", "basenodes:river_water_source")
+
+-- Additional essential aliases for v6
+minetest.register_alias("mapgen_lava_source", "basenodes:lava_source")
+minetest.register_alias("mapgen_dirt", "basenodes:dirt")
+minetest.register_alias("mapgen_dirt_with_grass", "basenodes:dirt_with_grass")
+minetest.register_alias("mapgen_sand", "basenodes:sand")
+minetest.register_alias("mapgen_tree", "basenodes:tree")
+minetest.register_alias("mapgen_leaves", "basenodes:leaves")
+minetest.register_alias("mapgen_apple", "basenodes:apple")
+
+-- Essential alias for dungeons
+minetest.register_alias("mapgen_cobble", "basenodes:cobble")
+
+-- Optional aliases for v6 (they all have fallback values in the engine)
+if minetest.settings:get_bool("devtest_v6_mapgen_aliases", false) then
+ minetest.register_alias("mapgen_gravel", "basenodes:gravel")
+ minetest.register_alias("mapgen_desert_stone", "basenodes:desert_stone")
+ minetest.register_alias("mapgen_desert_sand", "basenodes:desert_sand")
+ minetest.register_alias("mapgen_dirt_with_snow", "basenodes:dirt_with_snow")
+ minetest.register_alias("mapgen_snowblock", "basenodes:snowblock")
+ minetest.register_alias("mapgen_snow", "basenodes:snow")
+ minetest.register_alias("mapgen_ice", "basenodes:ice")
+ minetest.register_alias("mapgen_junglegrass", "basenodes:junglegrass")
+ minetest.register_alias("mapgen_jungletree", "basenodes:jungletree")
+ minetest.register_alias("mapgen_jungleleaves", "basenodes:jungleleaves")
+ minetest.register_alias("mapgen_pine_tree", "basenodes:pine_tree")
+ minetest.register_alias("mapgen_pine_needles", "basenodes:pine_needles")
+end
+-- Optional alias for mossycobble (should fall back to cobble)
+if minetest.settings:get_bool("devtest_dungeon_mossycobble", false) then
+ minetest.register_alias("mapgen_mossycobble", "basenodes:mossycobble")
+end
+-- Optional aliases for dungeon stairs (should fall back to full nodes)
+if minetest.settings:get_bool("devtest_dungeon_stairs", false) then
+ minetest.register_alias("mapgen_stair_cobble", "stairs:stair_cobble")
+ if minetest.settings:get_bool("devtest_v6_mapgen_aliases", false) then
+ minetest.register_alias("mapgen_stair_desert_stone", "stairs:stair_desert_stone")
+ end
+end
+
+--
+-- Register biomes for biome API
+--
+
+minetest.clear_registered_biomes()
+minetest.clear_registered_decorations()
+
+if minetest.settings:get_bool("devtest_register_biomes", true) then
+ minetest.register_biome({
+ name = "mapgen:grassland",
+ node_top = "basenodes:dirt_with_grass",
+ depth_top = 1,
+ node_filler = "basenodes:dirt",
+ depth_filler = 1,
+ node_riverbed = "basenodes:sand",
+ depth_riverbed = 2,
+ node_dungeon = "basenodes:cobble",
+ node_dungeon_alt = "basenodes:mossycobble",
+ node_dungeon_stair = "stairs:stair_cobble",
+ y_max = 31000,
+ y_min = 4,
+ heat_point = 50,
+ humidity_point = 50,
+ })
+
+ minetest.register_biome({
+ name = "mapgen:grassland_ocean",
+ node_top = "basenodes:sand",
+ depth_top = 1,
+ node_filler = "basenodes:sand",
+ depth_filler = 3,
+ node_riverbed = "basenodes:sand",
+ depth_riverbed = 2,
+ node_cave_liquid = "basenodes:water_source",
+ node_dungeon = "basenodes:cobble",
+ node_dungeon_alt = "basenodes:mossycobble",
+ node_dungeon_stair = "stairs:stair_cobble",
+ y_max = 3,
+ y_min = -255,
+ heat_point = 50,
+ humidity_point = 50,
+ })
+
+ minetest.register_biome({
+ name = "mapgen:grassland_under",
+ node_cave_liquid = {"basenodes:water_source", "basenodes:lava_source"},
+ node_dungeon = "basenodes:cobble",
+ node_dungeon_alt = "basenodes:mossycobble",
+ node_dungeon_stair = "stairs:stair_cobble",
+ y_max = -256,
+ y_min = -31000,
+ heat_point = 50,
+ humidity_point = 50,
+ })
+end
diff -Nru minetest-5.2.0/games/devtest/mods/mapgen/mod.conf minetest-5.3.0/games/devtest/mods/mapgen/mod.conf
--- minetest-5.2.0/games/devtest/mods/mapgen/mod.conf 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/mapgen/mod.conf 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,3 @@
+name = mapgen
+description = Minimal map generator
+depends = basenodes
diff -Nru minetest-5.2.0/games/devtest/mods/modchannels/init.lua minetest-5.3.0/games/devtest/mods/modchannels/init.lua
--- minetest-5.2.0/games/devtest/mods/modchannels/init.lua 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/modchannels/init.lua 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,14 @@
+--
+-- Mod channels experimental handlers
+--
+local mod_channel = minetest.mod_channel_join("experimental_preview")
+
+minetest.register_on_modchannel_message(function(channel, sender, message)
+ minetest.log("action", "[modchannels] Server received message `" .. message
+ .. "` on channel `" .. channel .. "` from sender `" .. sender .. "`")
+
+ if mod_channel:is_writeable() then
+ mod_channel:send_all("experimental answers to preview")
+ mod_channel:leave()
+ end
+end)
diff -Nru minetest-5.2.0/games/devtest/mods/modchannels/mod.conf minetest-5.3.0/games/devtest/mods/modchannels/mod.conf
--- minetest-5.2.0/games/devtest/mods/modchannels/mod.conf 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/modchannels/mod.conf 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,2 @@
+name = modchannels
+description = Add experimental mod channel handlers
diff -Nru minetest-5.2.0/games/devtest/mods/soundstuff/init.lua minetest-5.3.0/games/devtest/mods/soundstuff/init.lua
--- minetest-5.2.0/games/devtest/mods/soundstuff/init.lua 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/soundstuff/init.lua 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,170 @@
+local simple_nodes = {
+ footstep = { "Footstep Sound Node", "soundstuff_node_footstep.png" },
+ dig = { "Dig Sound Node", "soundstuff_node_dig.png" },
+ dug = { "Dug Sound Node", "soundstuff_node_dug.png" },
+ place = { "Place Sound Node", "soundstuff_node_place.png" },
+ place_failed = { "Place Failed Sound Node", "soundstuff_node_place_failed.png" },
+}
+
+for k,v in pairs(simple_nodes) do
+ minetest.register_node("soundstuff:"..k, {
+ description = v[1],
+ tiles = {"soundstuff_node_sound.png","soundstuff_node_sound.png",v[2]},
+ groups = {dig_immediate=2},
+ sounds = {
+ [k] = { name = "soundstuff_mono", gain = 1.0 },
+ }
+ })
+end
+
+minetest.register_node("soundstuff:place_failed_attached", {
+ description = "Attached Place Failed Sound Node",
+ tiles = {"soundstuff_node_sound.png", "soundstuff_node_sound.png", "soundstuff_node_place_failed.png"},
+ groups = {dig_immediate=2, attached_node=1},
+ drawtype = "nodebox",
+ paramtype = "light",
+ node_box = { type = "fixed", fixed = {
+ { -7/16, -7/16, -7/16, 7/16, 7/16, 7/16 },
+ { -0.5, -0.5, -0.5, 0.5, -7/16, 0.5 },
+ }},
+ sounds = {
+ place_failed = { name = "soundstuff_mono", gain = 1.0 },
+ },
+})
+
+minetest.register_node("soundstuff:fall", {
+ description = "Fall Sound Node",
+ tiles = {"soundstuff_node_sound.png", "soundstuff_node_sound.png", "soundstuff_node_fall.png"},
+ groups = {dig_immediate=2, falling_node=1},
+ sounds = {
+ fall = { name = "soundstuff_mono", gain = 1.0 },
+ }
+})
+
+minetest.register_node("soundstuff:fall_attached", {
+ description = "Attached Fall Sound Node",
+ tiles = {"soundstuff_node_sound.png", "soundstuff_node_sound.png", "soundstuff_node_fall.png"},
+ groups = {dig_immediate=2, attached_node=1},
+ drawtype = "nodebox",
+ paramtype = "light",
+ node_box = { type = "fixed", fixed = {
+ { -7/16, -7/16, -7/16, 7/16, 7/16, 7/16 },
+ { -0.5, -0.5, -0.5, 0.5, -7/16, 0.5 },
+ }},
+ sounds = {
+ fall = { name = "soundstuff_mono", gain = 1.0 },
+ }
+})
+
+minetest.register_node("soundstuff:footstep_liquid", {
+ description = "Liquid Footstep Sound Node",
+ drawtype = "liquid",
+ tiles = {
+ "soundstuff_node_sound.png^[colorize:#0000FF:127",
+ },
+ special_tiles = {
+ {name = "soundstuff_node_sound.png^[colorize:#0000FF:127", backface_culling = false},
+ {name = "soundstuff_node_sound.png^[colorize:#0000FF:127", backface_culling = true},
+ },
+ liquids_pointable = true,
+ liquidtype = "source",
+ liquid_alternative_flowing = "soundstuff:footstep_liquid",
+ liquid_alternative_source = "soundstuff:footstep_liquid",
+ liquid_renewable = false,
+ liquid_range = 0,
+ liquid_viscosity = 0,
+ alpha = 190,
+ paramtype = "light",
+ walkable = false,
+ pointable = false,
+ diggable = false,
+ buildable_to = true,
+ is_ground_content = false,
+ post_effect_color = {a = 64, r = 0, g = 0, b = 200},
+ sounds = {
+ footstep = { name = "soundstuff_mono", gain = 1.0 },
+ }
+})
+
+minetest.register_node("soundstuff:footstep_climbable", {
+ description = "Climbable Footstep Sound Node",
+ drawtype = "allfaces",
+ tiles = {
+ "soundstuff_node_climbable.png",
+ },
+ alpha = 120,
+ paramtype = "light",
+ sunlight_propagates = true,
+ walkable = false,
+ climbable = true,
+ is_ground_content = false,
+ groups = { dig_immediate = 2 },
+ sounds = {
+ footstep = { name = "soundstuff_mono", gain = 1.0 },
+ }
+})
+
+
+
+minetest.register_craftitem("soundstuff:eat", {
+ description = "Eat Sound Item",
+ inventory_image = "soundstuff_eat.png",
+ on_use = minetest.item_eat(0),
+ sound = {
+ eat = { name = "soundstuff_mono", gain = 1.0 },
+ }
+})
+
+minetest.register_tool("soundstuff:breaks", {
+ description = "Break Sound Tool",
+ inventory_image = "soundstuff_node_dug.png",
+ sound = {
+ breaks = { name = "soundstuff_mono", gain = 1.0 },
+ },
+ tool_capabilities = {
+ max_drop_level=0,
+ groupcaps={
+ cracky={times={[2]=2.00, [3]=1.20}, uses=1, maxlevel=0},
+ choppy={times={[2]=2.00, [3]=1.20}, uses=1, maxlevel=0},
+ snappy={times={[2]=2.00, [3]=1.20}, uses=1, maxlevel=0},
+ crumbly={times={[2]=2.00, [3]=1.20}, uses=1, maxlevel=0},
+ },
+ },
+})
+
+-- Plays sound repeatedly
+minetest.register_node("soundstuff:positional", {
+ description = "Positional Sound Node",
+ on_construct = function(pos)
+ local timer = minetest.get_node_timer(pos)
+ timer:start(0)
+ end,
+ on_timer = function(pos, elapsed)
+ local node = minetest.get_node(pos)
+ local dist = node.param2
+ if dist == 0 then
+ dist = nil
+ end
+ minetest.sound_play("soundstuff_mono", { pos = pos, max_hear_distance = dist })
+ local timer = minetest.get_node_timer(pos)
+ timer:start(0.7)
+ end,
+ on_rightclick = function(pos, node, clicker)
+ node.param2 = (node.param2 + 1) % 64
+ minetest.set_node(pos, node)
+ if clicker and clicker:is_player() then
+ local dist = node.param2
+ local diststr
+ if dist == 0 then
+ diststr = ""
+ else
+ diststr = tostring(dist)
+ end
+ minetest.chat_send_player(clicker:get_player_name(), "max_hear_distance = " .. diststr)
+ end
+ end,
+
+ groups = { dig_immediate = 2 },
+ tiles = { "soundstuff_node_sound.png" },
+})
+
diff -Nru minetest-5.2.0/games/devtest/mods/soundstuff/mod.conf minetest-5.3.0/games/devtest/mods/soundstuff/mod.conf
--- minetest-5.2.0/games/devtest/mods/soundstuff/mod.conf 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/soundstuff/mod.conf 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,2 @@
+name = soundstuff
+description = Example items and nodes for testing sound effects
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/soundstuff/sounds/soundstuff_mono.ogg and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/soundstuff/sounds/soundstuff_mono.ogg differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/soundstuff/textures/soundstuff_eat.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/soundstuff/textures/soundstuff_eat.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/soundstuff/textures/soundstuff_node_blank.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/soundstuff/textures/soundstuff_node_blank.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/soundstuff/textures/soundstuff_node_climbable.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/soundstuff/textures/soundstuff_node_climbable.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/soundstuff/textures/soundstuff_node_dig.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/soundstuff/textures/soundstuff_node_dig.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/soundstuff/textures/soundstuff_node_dug.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/soundstuff/textures/soundstuff_node_dug.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/soundstuff/textures/soundstuff_node_fall.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/soundstuff/textures/soundstuff_node_fall.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/soundstuff/textures/soundstuff_node_footstep.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/soundstuff/textures/soundstuff_node_footstep.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/soundstuff/textures/soundstuff_node_place_failed.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/soundstuff/textures/soundstuff_node_place_failed.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/soundstuff/textures/soundstuff_node_place.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/soundstuff/textures/soundstuff_node_place.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/soundstuff/textures/soundstuff_node_sound.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/soundstuff/textures/soundstuff_node_sound.png differ
diff -Nru minetest-5.2.0/games/devtest/mods/stairs/init.lua minetest-5.3.0/games/devtest/mods/stairs/init.lua
--- minetest-5.2.0/games/devtest/mods/stairs/init.lua 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/stairs/init.lua 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,65 @@
+stairs = {}
+
+-- Node will be called stairs:stair_
+function stairs.register_stair(subname, recipeitem, groups, images, description)
+ minetest.register_node(":stairs:stair_" .. subname, {
+ description = description,
+ drawtype = "nodebox",
+ tiles = images,
+ paramtype = "light",
+ paramtype2 = "facedir",
+ is_ground_content = true,
+ groups = groups,
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
+ {-0.5, 0, 0, 0.5, 0.5, 0.5},
+ },
+ },
+ })
+end
+
+-- Node will be called stairs:slab_
+function stairs.register_slab(subname, recipeitem, groups, images, description)
+ minetest.register_node(":stairs:slab_" .. subname, {
+ description = description,
+ drawtype = "nodebox",
+ tiles = images,
+ paramtype = "light",
+ is_ground_content = true,
+ groups = groups,
+ node_box = {
+ type = "fixed",
+ fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
+ },
+ selection_box = {
+ type = "fixed",
+ fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
+ },
+ })
+end
+
+-- Nodes will be called stairs:{stair,slab}_
+function stairs.register_stair_and_slab(subname, recipeitem, groups, images, desc_stair, desc_slab)
+ stairs.register_stair(subname, recipeitem, groups, images, desc_stair)
+ stairs.register_slab(subname, recipeitem, groups, images, desc_slab)
+end
+
+stairs.register_stair_and_slab("stone", "basenodes:stone",
+ {cracky=3},
+ {"default_stone.png"},
+ "Stone Stair",
+ "Stone Slab")
+
+stairs.register_stair_and_slab("desert_stone", "basenodes:desert_stone",
+ {cracky=3},
+ {"default_desert_stone.png"},
+ "Desert Stone Stair",
+ "Desert Stone Slab")
+
+stairs.register_stair_and_slab("cobble", "basenodes:cobble",
+ {cracky=3},
+ {"default_cobble.png"},
+ "Cobblestone Stair",
+ "Cobblestone Slab")
diff -Nru minetest-5.2.0/games/devtest/mods/stairs/mod.conf minetest-5.3.0/games/devtest/mods/stairs/mod.conf
--- minetest-5.2.0/games/devtest/mods/stairs/mod.conf 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/stairs/mod.conf 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,3 @@
+name = stairs
+description = Adds stairs and slabs
+depends = basenodes
diff -Nru minetest-5.2.0/games/devtest/mods/testentities/armor.lua minetest-5.3.0/games/devtest/mods/testentities/armor.lua
--- minetest-5.2.0/games/devtest/mods/testentities/armor.lua 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/testentities/armor.lua 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,41 @@
+-- Armorball: Test entity for testing armor groups
+-- Rightclick to change armor group
+
+local phasearmor = {
+ [0]={icy=100},
+ [1]={firy=100},
+ [2]={fleshy=100},
+ [3]={immortal=1},
+ [4]={punch_operable=1},
+}
+
+minetest.register_entity("testentities:armorball", {
+ initial_properties = {
+ hp_max = 20,
+ physical = false,
+ collisionbox = {-0.4,-0.4,-0.4, 0.4,0.4,0.4},
+ visual = "sprite",
+ visual_size = {x=1, y=1},
+ textures = {"testentities_armorball.png"},
+ spritediv = {x=1, y=5},
+ initial_sprite_basepos = {x=0, y=0},
+ },
+
+ _phase = 2,
+
+ on_activate = function(self, staticdata)
+ minetest.log("action", "[testentities] armorball.on_activate")
+ self.object:set_armor_groups(phasearmor[self._phase])
+ self.object:set_sprite({x=0, y=self._phase})
+ end,
+
+ on_rightclick = function(self, clicker)
+ -- Change armor group and sprite
+ self._phase = self._phase + 1
+ if self._phase >= 5 then
+ self._phase = 0
+ end
+ self.object:set_sprite({x=0, y=self._phase})
+ self.object:set_armor_groups(phasearmor[self._phase])
+ end,
+})
diff -Nru minetest-5.2.0/games/devtest/mods/testentities/callbacks.lua minetest-5.3.0/games/devtest/mods/testentities/callbacks.lua
--- minetest-5.2.0/games/devtest/mods/testentities/callbacks.lua 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/testentities/callbacks.lua 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,75 @@
+-- Entities that test their callbacks
+
+local message = function(msg)
+ minetest.log("action", msg)
+ minetest.chat_send_all(msg)
+end
+
+local get_object_name = function(obj)
+ local name = ""
+ if obj then
+ if obj:is_player() then
+ name = obj:get_player_name()
+ else
+ name = ""
+ end
+ end
+ return name
+end
+
+local spos = function(self)
+ return minetest.pos_to_string(vector.round(self.object:get_pos()))
+end
+
+-- Callback test entity (all callbacks except on_step)
+minetest.register_entity("testentities:callback", {
+ initial_properties = {
+ visual = "upright_sprite",
+ textures = { "testentities_callback.png" },
+ },
+
+ on_activate = function(self, staticdata, dtime_s)
+ message("Callback entity: on_activate! pos="..spos(self).."; dtime_s="..dtime_s)
+ end,
+ on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage)
+ local name = get_object_name(puncher)
+ message(
+ "Callback entity: on_punch! "..
+ "pos="..spos(self).."; puncher="..name.."; "..
+ "time_from_last_punch="..time_from_last_punch.."; "..
+ "tool_capabilities="..tostring(dump(tool_capabilities)).."; "..
+ "dir="..tostring(dump(dir)).."; damage="..damage)
+ end,
+ on_rightclick = function(self, clicker)
+ local name = get_object_name(clicker)
+ message("Callback entity: on_rightclick! pos="..spos(self).."; clicker="..name)
+ end,
+ on_death = function(self, killer)
+ local name = get_object_name(killer)
+ message("Callback entity: on_death! pos="..spos(self).."; killer="..name)
+ end,
+ on_attach_child = function(self, child)
+ local name = get_object_name(child)
+ message("Callback entity: on_attach_child! pos="..spos(self).."; child="..name)
+ end,
+ on_detach_child = function(self, child)
+ local name = get_object_name(child)
+ message("Callback entity: on_detach_child! pos="..spos(self).."; child="..name)
+ end,
+ on_detach = function(self, parent)
+ local name = get_object_name(parent)
+ message("Callback entity: on_detach! pos="..spos(self).."; parent="..name)
+ end,
+ get_staticdata = function(self)
+ message("Callback entity: get_staticdata! pos="..spos(self))
+ end,
+})
+
+-- Only test on_step callback
+minetest.register_entity("testentities:callback_step", {
+ visual = "upright_sprite",
+ textures = { "testentities_callback_step.png" },
+ on_step = function(self, dtime)
+ message("on_step callback entity: on_step! pos="..spos(self).."; dtime="..dtime)
+ end,
+})
diff -Nru minetest-5.2.0/games/devtest/mods/testentities/init.lua minetest-5.3.0/games/devtest/mods/testentities/init.lua
--- minetest-5.2.0/games/devtest/mods/testentities/init.lua 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/testentities/init.lua 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,3 @@
+dofile(minetest.get_modpath("testentities").."/visuals.lua")
+dofile(minetest.get_modpath("testentities").."/armor.lua")
+dofile(minetest.get_modpath("testentities").."/callbacks.lua")
diff -Nru minetest-5.2.0/games/devtest/mods/testentities/mod.conf minetest-5.3.0/games/devtest/mods/testentities/mod.conf
--- minetest-5.2.0/games/devtest/mods/testentities/mod.conf 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/testentities/mod.conf 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,2 @@
+name = testentities
+description = Example entities for testing
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/testentities/textures/testentities_armorball.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/testentities/textures/testentities_armorball.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/testentities/textures/testentities_callback.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/testentities/textures/testentities_callback.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/testentities/textures/testentities_callback_step.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/testentities/textures/testentities_callback_step.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/testentities/textures/testentities_cube1.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/testentities/textures/testentities_cube1.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/testentities/textures/testentities_cube2.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/testentities/textures/testentities_cube2.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/testentities/textures/testentities_cube3.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/testentities/textures/testentities_cube3.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/testentities/textures/testentities_cube4.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/testentities/textures/testentities_cube4.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/testentities/textures/testentities_cube5.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/testentities/textures/testentities_cube5.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/testentities/textures/testentities_cube6.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/testentities/textures/testentities_cube6.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/testentities/textures/testentities_dungeon_master.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/testentities/textures/testentities_dungeon_master.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/testentities/textures/testentities_sprite.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/testentities/textures/testentities_sprite.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/testentities/textures/testentities_upright_sprite1.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/testentities/textures/testentities_upright_sprite1.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/testentities/textures/testentities_upright_sprite2.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/testentities/textures/testentities_upright_sprite2.png differ
diff -Nru minetest-5.2.0/games/devtest/mods/testentities/visuals.lua minetest-5.3.0/games/devtest/mods/testentities/visuals.lua
--- minetest-5.2.0/games/devtest/mods/testentities/visuals.lua 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/testentities/visuals.lua 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,84 @@
+-- Minimal test entities to test visuals
+
+minetest.register_entity("testentities:sprite", {
+ initial_properties = {
+ visual = "sprite",
+ textures = { "testentities_sprite.png" },
+ },
+})
+
+minetest.register_entity("testentities:upright_sprite", {
+ initial_properties = {
+ visual = "upright_sprite",
+ textures = {
+ "testentities_upright_sprite1.png",
+ "testentities_upright_sprite2.png",
+ },
+ },
+})
+
+minetest.register_entity("testentities:cube", {
+ initial_properties = {
+ visual = "cube",
+ textures = {
+ "testentities_cube1.png",
+ "testentities_cube2.png",
+ "testentities_cube3.png",
+ "testentities_cube4.png",
+ "testentities_cube5.png",
+ "testentities_cube6.png",
+ },
+ },
+})
+
+minetest.register_entity("testentities:item", {
+ initial_properties = {
+ visual = "item",
+ wield_item = "testnodes:normal",
+ },
+})
+
+minetest.register_entity("testentities:wielditem", {
+ initial_properties = {
+ visual = "wielditem",
+ wield_item = "testnodes:normal",
+ },
+})
+
+minetest.register_entity("testentities:mesh", {
+ initial_properties = {
+ visual = "mesh",
+ mesh = "testnodes_pyramid.obj",
+ textures = {
+ "testnodes_mesh_stripes2.png"
+ },
+ },
+})
+
+minetest.register_entity("testentities:mesh_unshaded", {
+ initial_properties = {
+ visual = "mesh",
+ mesh = "testnodes_pyramid.obj",
+ textures = {
+ "testnodes_mesh_stripes2.png"
+ },
+ shaded = false,
+ },
+})
+
+-- Advanced visual tests
+
+-- A test entity for testing animated and yaw-modulated sprites
+minetest.register_entity("testentities:yawsprite", {
+ initial_properties = {
+ selectionbox = {-0.3, -0.5, -0.3, 0.3, 0.3, 0.3},
+ visual = "sprite",
+ visual_size = {x=0.6666, y=1},
+ textures = {"testentities_dungeon_master.png^[makealpha:128,0,0^[makealpha:128,128,0"},
+ spritediv = {x=6, y=5},
+ initial_sprite_basepos = {x=0, y=0},
+ },
+ on_activate = function(self, staticdata)
+ self.object:set_sprite({x=0, y=0}, 1, 0, true)
+ end,
+})
diff -Nru minetest-5.2.0/games/devtest/mods/testfood/init.lua minetest-5.3.0/games/devtest/mods/testfood/init.lua
--- minetest-5.2.0/games/devtest/mods/testfood/init.lua 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/testfood/init.lua 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,24 @@
+local S = minetest.get_translator("testfood")
+
+minetest.register_craftitem("testfood:good1", {
+ description = S("Good Food (+1)"),
+ inventory_image = "testfood_good.png",
+ on_use = minetest.item_eat(1),
+})
+minetest.register_craftitem("testfood:good5", {
+ description = S("Good Food (+5)"),
+ inventory_image = "testfood_good2.png",
+ on_use = minetest.item_eat(5),
+})
+
+minetest.register_craftitem("testfood:bad1", {
+ description = S("Bad Food (-1)"),
+ inventory_image = "testfood_bad.png",
+ on_use = minetest.item_eat(-1),
+})
+minetest.register_craftitem("testfood:bad5", {
+ description = S("Bad Food (-5)"),
+ inventory_image = "testfood_bad2.png",
+ on_use = minetest.item_eat(-5),
+})
+
diff -Nru minetest-5.2.0/games/devtest/mods/testfood/mod.conf minetest-5.3.0/games/devtest/mods/testfood/mod.conf
--- minetest-5.2.0/games/devtest/mods/testfood/mod.conf 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/testfood/mod.conf 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,2 @@
+name = testfood
+description = For testing food items
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/testfood/textures/testfood_bad2.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/testfood/textures/testfood_bad2.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/testfood/textures/testfood_bad.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/testfood/textures/testfood_bad.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/testfood/textures/testfood_good2.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/testfood/textures/testfood_good2.png differ
Binary files /tmp/tmpfN7tCC/heaZZjpnBb/minetest-5.2.0/games/devtest/mods/testfood/textures/testfood_good.png and /tmp/tmpfN7tCC/DlwpBMAfAe/minetest-5.3.0/games/devtest/mods/testfood/textures/testfood_good.png differ
diff -Nru minetest-5.2.0/games/devtest/mods/testformspec/callbacks.lua minetest-5.3.0/games/devtest/mods/testformspec/callbacks.lua
--- minetest-5.2.0/games/devtest/mods/testformspec/callbacks.lua 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/testformspec/callbacks.lua 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,51 @@
+local callback_test = 0
+
+local out = function(player, formname, fields, number)
+ local snum = ""
+ if number then
+ snum = " "..number
+ end
+ local msg = "Formspec callback"..snum..": player="..player:get_player_name()..", formname=\""..tostring(formname).."\", fields="..dump(fields)
+ minetest.chat_send_player(player:get_player_name(), msg)
+ minetest.log("action", msg)
+end
+
+minetest.register_on_player_receive_fields(function(player, formname, fields)
+ if callback_test == 1 then
+ out(player, formname, fields)
+ elseif callback_test == 2 then
+ out(player, formname, fields, 1)
+ end
+end)
+minetest.register_on_player_receive_fields(function(player, formname, fields)
+ if callback_test == 2 then
+ out(player, formname, fields, 2)
+ return true -- Disable the first callback
+ end
+end)
+minetest.register_on_player_receive_fields(function(player, formname, fields)
+ if callback_test == 2 then
+ out(player, formname, fields, 3)
+ end
+end)
+
+minetest.register_chatcommand("test_formspec_callbacks", {
+ params = "[ 0 | 1 | 2 ]",
+ description = "Test: Change formspec callbacks testing mode",
+ func = function(name, param)
+ local mode = tonumber(param)
+ if not mode then
+ callback_test = (callback_test + 1 % 3)
+ else
+ callback_test = mode
+ end
+ if callback_test == 1 then
+ minetest.chat_send_player(name, "Formspec callback test mode 1 enabled: Logging only")
+ elseif callback_test == 2 then
+ minetest.chat_send_player(name, "Formspec callback test mode 2 enabled: Three callbacks, disable pre-registered callbacks")
+ else
+ callback_test = 0
+ minetest.chat_send_player(name, "Formspec callback test disabled!")
+ end
+ end
+})
diff -Nru minetest-5.2.0/games/devtest/mods/testformspec/dummy_items.lua minetest-5.3.0/games/devtest/mods/testformspec/dummy_items.lua
--- minetest-5.2.0/games/devtest/mods/testformspec/dummy_items.lua 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/testformspec/dummy_items.lua 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,14 @@
+-- This code adds dummy items that are supposed to be used in formspecs
+-- for testing item_image formspec elements.
+
+minetest.register_node("testformspec:node", {
+ description = "Formspec Test Node",
+ tiles = { "testformspec_node.png" },
+ groups = { dig_immediate = 3, dummy = 1 },
+})
+
+minetest.register_craftitem("testformspec:item", {
+ description = "Formspec Test Item",
+ inventory_image = "testformspec_item.png",
+ groups = { dummy = 1 },
+})
diff -Nru minetest-5.2.0/games/devtest/mods/testformspec/formspec.lua minetest-5.3.0/games/devtest/mods/testformspec/formspec.lua
--- minetest-5.2.0/games/devtest/mods/testformspec/formspec.lua 1970-01-01 00:00:00.000000000 +0000
+++ minetest-5.3.0/games/devtest/mods/testformspec/formspec.lua 2020-07-09 21:13:20.000000000 +0000
@@ -0,0 +1,381 @@
+local color = minetest.colorize
+
+local clip_fs = [[
+ style_type[label,button,image_button,item_image_button,
+ tabheader,scrollbar,table,animated_image
+ ,field,textarea,checkbox,dropdown;noclip=%c]
+
+ label[0,0;A clipping test]
+ button[0,1;3,0.8;clip_button;A clipping test]
+ image_button[0,2;3,0.8;testformspec_button_image.png;clip_image_button;A clipping test]
+ item_image_button[0,3;3,0.8;testformspec:item;clip_item_image_button;A clipping test]
+ tabheader[0,4.7;3,0.63;clip_tabheader;Clip,Test,Text,Tabs;1;false;false]
+ field[0,5;3,0.8;clip_field;Title;]
+ textarea[0,6;3,1;clip_textarea;Title;]
+ checkbox[0,7.5;clip_checkbox;This is a test;true]
+ dropdown[0,8;3,0.8;clip_dropdown;Select An Item,One,Two,Three,Four,Five;1]
+ scrollbar[0,9;3,0.8;horizontal;clip_scrollbar;3]
+ tablecolumns[text;text]
+ table[0,10;3,1;clip_table;one,two,three,four;1]
+ animated_image[-0.5,11;4.5,1;clip_animated_image;testformspec_animation.png;4;100]
+]]
+
+local tabheaders_fs = [[
+ tabheader[0,0;10,0.63;tabs_opaque;Opaque,Without,Border;1;false;false]
+ tabheader[0,1;10,0.63;tabs_opaque_border;Opaque,With,Border;1;false;true]
+ tabheader[0,2;10,0.63;tabs_transparent;Transparent,Without,Border;1;true;false]
+ tabheader[0,3;10,0.63;tabs_transparent_border;Transparent,With,Border;1;true;true]
+ tabheader[0,4;tabs_default;Default,Tabs;1]
+ tabheader[0,6;10,0.5;tabs_size1;Height=0.5;1;false;false]
+ tabheader[2,6;10,0.75;tabs_size1;Height=0.75;1;false;false]
+ tabheader[4,6;10,1;tabs_size2;Height=1;1;false;false]
+ tabheader[6,6;10,1.25;tabs_size2;Height=1.25;1;false;false]
+ tabheader[8,6;10,1.5;tabs_size2;Height=1.5;1;false;false]
+]]
+
+local hypertext_basic = [[
+Normal test
+This is a normal text.
+
+style test
+
+ .
+
+
+Tag test
+normal
+mono
+bold
+italic
+underlined
+big
+bigger
+left
+center
+right
+justify. Here comes a blind text: Lorem testum dolor sit amet consecutor celeron fiftifahivus e shadoninia e smalus jokus anrus relsocutoti rubenwardus. Erasputinus hara holisti dominus wusi. Grumarinsti erltusmuate ol fortitusti fla flo, blani burki e sfani fahif. Ultae ratii, e megus gigae don anonimus. Grinus dimondus krockus e nore. Endus finalus nowus comus endus o blindus tekstus.
+
+Custom tag test
+
+
+
+
+
+color=green
+Action: color=green
+Action: hovercolor=yellow
+size=24
+font=mono
+color=green font=mono size=24
+
+action test
+action
+
+img test
+Normal:
+
+width=48 height=48:
+
+float=left:
+
+float=right:
+
+
+item test
+Normal:
+-
+width=48 height=48
+
-
+angle=30,0,0:
+
-
+angle=0,30,0:
+
-
+angle=0,0,30:
+
-
+rotate=yes:
+
-
+rotate=100,0,0:
+
-
+rotate=0,100,0:
+
-
+