diff --git a/android/src/io/anuke/mindustry/AndroidLauncher.java b/android/src/io/anuke/mindustry/AndroidLauncher.java index 774e01ae69..d532734999 100644 --- a/android/src/io/anuke/mindustry/AndroidLauncher.java +++ b/android/src/io/anuke/mindustry/AndroidLauncher.java @@ -49,237 +49,237 @@ import java.util.Locale; import static io.anuke.mindustry.Vars.*; public class AndroidLauncher extends AndroidApplication{ - public static final int PERMISSION_REQUEST_CODE = 1; + public static final int PERMISSION_REQUEST_CODE = 1; - boolean doubleScaleTablets = true; - FileChooser chooser; + boolean doubleScaleTablets = true; + FileChooser chooser; - @Override - protected void onCreate(Bundle savedInstanceState){ - super.onCreate(savedInstanceState); + @Override + protected void onCreate(Bundle savedInstanceState){ + super.onCreate(savedInstanceState); - AndroidApplicationConfiguration config = new AndroidApplicationConfiguration(); - config.useImmersiveMode = true; + AndroidApplicationConfiguration config = new AndroidApplicationConfiguration(); + config.useImmersiveMode = true; - Platform.instance = new Platform(){ - DateFormat format = SimpleDateFormat.getDateTimeInstance(); + Platform.instance = new Platform(){ + DateFormat format = SimpleDateFormat.getDateTimeInstance(); - @Override - public boolean hasDiscord() { - return isPackageInstalled("com.discord"); - } + @Override + public boolean hasDiscord(){ + return isPackageInstalled("com.discord"); + } - @Override - public String format(Date date){ - return format.format(date); - } + @Override + public String format(Date date){ + return format.format(date); + } - @Override - public String format(int number){ - return NumberFormat.getIntegerInstance().format(number); - } + @Override + public String format(int number){ + return NumberFormat.getIntegerInstance().format(number); + } - @Override - public void addDialog(TextField field, int length){ - TextFieldDialogListener.add(field, 0, length); - } + @Override + public void addDialog(TextField field, int length){ + TextFieldDialogListener.add(field, 0, length); + } - @Override - public String getLocaleName(Locale locale){ - return locale.getDisplayName(locale); - } + @Override + public String getLocaleName(Locale locale){ + return locale.getDisplayName(locale); + } - @Override - public void openDonations() { - showDonations(); - } + @Override + public void openDonations(){ + showDonations(); + } - @Override - public ThreadProvider getThreadProvider() { - return new DefaultThreadImpl(); - } + @Override + public ThreadProvider getThreadProvider(){ + return new DefaultThreadImpl(); + } - @Override - public boolean isDebug() { - return false; - } + @Override + public boolean isDebug(){ + return false; + } - @Override - public String getUUID() { - try { - String s = Secure.getString(getContext().getContentResolver(), - Secure.ANDROID_ID); + @Override + public String getUUID(){ + try{ + String s = Secure.getString(getContext().getContentResolver(), + Secure.ANDROID_ID); - int len = s.length(); - byte[] data = new byte[len / 2]; - for (int i = 0; i < len; i += 2) { - data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) - + Character.digit(s.charAt(i + 1), 16)); - } + int len = s.length(); + byte[] data = new byte[len / 2]; + for(int i = 0; i < len; i += 2){ + data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + + Character.digit(s.charAt(i + 1), 16)); + } - String result = new String(Base64Coder.encode(data)); + String result = new String(Base64Coder.encode(data)); - if(result.equals("AAAAAAAAAOA=")) throw new RuntimeException("Bad UUID."); + if(result.equals("AAAAAAAAAOA=")) throw new RuntimeException("Bad UUID."); - return result; - }catch (Exception e){ - return super.getUUID(); - } - } + return result; + }catch(Exception e){ + return super.getUUID(); + } + } - @Override - public void shareFile(FileHandle file){ + @Override + public void shareFile(FileHandle file){ - } + } - @Override - public void showFileChooser(String text, String content, Consumer cons, boolean open, String filetype) { - chooser = new FileChooser(text, file -> file.extension().equalsIgnoreCase(filetype), open, cons); + @Override + public void showFileChooser(String text, String content, Consumer cons, boolean open, String filetype){ + chooser = new FileChooser(text, file -> file.extension().equalsIgnoreCase(filetype), open, cons); - if(Build.VERSION.SDK_INT < Build.VERSION_CODES.M || (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED && - checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)){ - chooser.show(); - chooser = null; - }else { - ArrayList perms = new ArrayList<>(); + if(Build.VERSION.SDK_INT < Build.VERSION_CODES.M || (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED && + checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)){ + chooser.show(); + chooser = null; + }else{ + ArrayList perms = new ArrayList<>(); - if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { - perms.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); - } + if(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){ + perms.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); + } - if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { - perms.add(Manifest.permission.READ_EXTERNAL_STORAGE); - } + if(checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){ + perms.add(Manifest.permission.READ_EXTERNAL_STORAGE); + } - requestPermissions(perms.toArray(new String[perms.size()]), PERMISSION_REQUEST_CODE); - } - } + requestPermissions(perms.toArray(new String[perms.size()]), PERMISSION_REQUEST_CODE); + } + } - @Override - public void beginForceLandscape() { - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); - } + @Override + public void beginForceLandscape(){ + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); + } - @Override - public void endForceLandscape() { - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR); - } + @Override + public void endForceLandscape(){ + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR); + } - @Override - public boolean canDonate(){ - return true; - } - }; + @Override + public boolean canDonate(){ + return true; + } + }; - try { - ProviderInstaller.installIfNeeded(this); - } catch (GooglePlayServicesRepairableException e) { - GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance(); - apiAvailability.getErrorDialog(this, e.getConnectionStatusCode(), 0).show(); - } catch (GooglePlayServicesNotAvailableException e) { - Log.e("SecurityException", "Google Play Services not available."); - } + try{ + ProviderInstaller.installIfNeeded(this); + }catch(GooglePlayServicesRepairableException e){ + GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance(); + apiAvailability.getErrorDialog(this, e.getConnectionStatusCode(), 0).show(); + }catch(GooglePlayServicesNotAvailableException e){ + Log.e("SecurityException", "Google Play Services not available."); + } - if(doubleScaleTablets && isTablet(this.getContext())){ - Unit.dp.addition = 0.5f; - } - - config.hideStatusBar = true; + if(doubleScaleTablets && isTablet(this.getContext())){ + Unit.dp.addition = 0.5f; + } + + config.hideStatusBar = true; Net.setClientProvider(new KryoClient()); Net.setServerProvider(new KryoServer()); initialize(new Mindustry(), config); - checkFiles(getIntent()); - } + checkFiles(getIntent()); + } - @Override - public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { - if(requestCode == PERMISSION_REQUEST_CODE){ - for(int i : grantResults){ - if(i != PackageManager.PERMISSION_GRANTED) return; - } + @Override + public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults){ + if(requestCode == PERMISSION_REQUEST_CODE){ + for(int i : grantResults){ + if(i != PackageManager.PERMISSION_GRANTED) return; + } - if(chooser != null){ - chooser.show(); - } - } - } + if(chooser != null){ + chooser.show(); + } + } + } - private void checkFiles(Intent intent){ - try { - Uri uri = intent.getData(); - if (uri != null) { - File myFile = null; - String scheme = uri.getScheme(); - if (scheme.equals("file")) { - String fileName = uri.getEncodedPath(); - myFile = new File(fileName); - } else if (!scheme.equals("content")) { - //error - return; - } + private void checkFiles(Intent intent){ + try{ + Uri uri = intent.getData(); + if(uri != null){ + File myFile = null; + String scheme = uri.getScheme(); + if(scheme.equals("file")){ + String fileName = uri.getEncodedPath(); + myFile = new File(fileName); + }else if(!scheme.equals("content")){ + //error + return; + } - boolean save = uri.getPath().endsWith(saveExtension); - boolean map = uri.getPath().endsWith(mapExtension); + boolean save = uri.getPath().endsWith(saveExtension); + boolean map = uri.getPath().endsWith(mapExtension); - InputStream inStream; - if (myFile != null) inStream = new FileInputStream(myFile); - else inStream = getContentResolver().openInputStream(uri); + InputStream inStream; + if(myFile != null) inStream = new FileInputStream(myFile); + else inStream = getContentResolver().openInputStream(uri); - Gdx.app.postRunnable(() -> { + Gdx.app.postRunnable(() -> { - if(save){ //open save - System.out.println("Opening save."); - FileHandle file = Gdx.files.local("temp-save." + saveExtension); - file.write(inStream, false); + if(save){ //open save + System.out.println("Opening save."); + FileHandle file = Gdx.files.local("temp-save." + saveExtension); + file.write(inStream, false); - if(SaveIO.isSaveValid(file)){ - try{ - SaveSlot slot = control.getSaves().importSave(file); - ui.load.runLoadSave(slot); - }catch (IOException e){ - ui.showError(Bundles.format("text.save.import.fail", Strings.parseException(e, false))); - } - }else{ - ui.showError("$text.save.import.invalid"); - } + if(SaveIO.isSaveValid(file)){ + try{ + SaveSlot slot = control.getSaves().importSave(file); + ui.load.runLoadSave(slot); + }catch(IOException e){ + ui.showError(Bundles.format("text.save.import.fail", Strings.parseException(e, false))); + } + }else{ + ui.showError("$text.save.import.invalid"); + } - }else if(map){ //open map - Gdx.app.postRunnable(() -> { - System.out.println("Opening map."); - if (!ui.editor.isShown()) { - ui.editor.show(); - } + }else if(map){ //open map + Gdx.app.postRunnable(() -> { + System.out.println("Opening map."); + if(!ui.editor.isShown()){ + ui.editor.show(); + } - ui.editor.beginEditMap(inStream); - }); - } - }); - } + ui.editor.beginEditMap(inStream); + }); + } + }); + } - }catch (IOException e){ - e.printStackTrace(); - } - } - - private boolean isPackageInstalled(String packagename) { - try { - getPackageManager().getPackageInfo(packagename, 0); - return true; - } catch (Exception e) { - return false; - } - } - - private boolean isTablet(Context context) { - TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); - return manager.getPhoneType() == TelephonyManager.PHONE_TYPE_NONE; - } - - private void showDonations(){ - Intent intent = new Intent(this, DonationsActivity.class); - startActivity(intent); - } + }catch(IOException e){ + e.printStackTrace(); + } + } + + private boolean isPackageInstalled(String packagename){ + try{ + getPackageManager().getPackageInfo(packagename, 0); + return true; + }catch(Exception e){ + return false; + } + } + + private boolean isTablet(Context context){ + TelephonyManager manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + return manager.getPhoneType() == TelephonyManager.PHONE_TYPE_NONE; + } + + private void showDonations(){ + Intent intent = new Intent(this, DonationsActivity.class); + startActivity(intent); + } } diff --git a/android/src/io/anuke/mindustry/AndroidTextFieldDialog.java b/android/src/io/anuke/mindustry/AndroidTextFieldDialog.java index 7a530e817a..56a1b92c72 100644 --- a/android/src/io/anuke/mindustry/AndroidTextFieldDialog.java +++ b/android/src/io/anuke/mindustry/AndroidTextFieldDialog.java @@ -11,20 +11,20 @@ import android.widget.EditText; import com.badlogic.gdx.Gdx; public class AndroidTextFieldDialog{ - private Activity activity; - private EditText userInput; - private AlertDialog.Builder builder; - private TextPromptListener listener; - private boolean isBuild; + private Activity activity; + private EditText userInput; + private AlertDialog.Builder builder; + private TextPromptListener listener; + private boolean isBuild; - public AndroidTextFieldDialog() { - this.activity = (Activity)Gdx.app; - load(); - } + public AndroidTextFieldDialog(){ + this.activity = (Activity) Gdx.app; + load(); + } - public AndroidTextFieldDialog show() { + public AndroidTextFieldDialog show(){ - activity.runOnUiThread(() -> { + activity.runOnUiThread(() -> { AlertDialog dialog = builder.create(); dialog.getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE); @@ -33,12 +33,12 @@ public class AndroidTextFieldDialog{ }); - return this; - } + return this; + } - private AndroidTextFieldDialog load() { + private AndroidTextFieldDialog load(){ - activity.runOnUiThread(() -> { + activity.runOnUiThread(() -> { AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(activity); LayoutInflater li = LayoutInflater.from(activity); @@ -55,64 +55,65 @@ public class AndroidTextFieldDialog{ isBuild = true; }); - // Wait till TextPrompt is built. - while (!isBuild) { - try { - Thread.sleep(10); - } catch (InterruptedException e) { } - } + // Wait till TextPrompt is built. + while(!isBuild){ + try{ + Thread.sleep(10); + }catch(InterruptedException e){ + } + } - return this; - } + return this; + } - public int getResourceId(String pVariableName, String pVariableType) { - try { - return activity.getResources().getIdentifier(pVariableName, pVariableType, activity.getPackageName()); - } catch (Exception e) { - Gdx.app.error("Android Dialogs", "Cannot find resouce with name: " + pVariableName - + " Did you copy the layouts to /res/layouts and /res/layouts_v14 ?"); - e.printStackTrace(); - return -1; - } - } + public int getResourceId(String pVariableName, String pVariableType){ + try{ + return activity.getResources().getIdentifier(pVariableName, pVariableType, activity.getPackageName()); + }catch(Exception e){ + Gdx.app.error("Android Dialogs", "Cannot find resouce with name: " + pVariableName + + " Did you copy the layouts to /res/layouts and /res/layouts_v14 ?"); + e.printStackTrace(); + return -1; + } + } - public AndroidTextFieldDialog setText(CharSequence value) { - userInput.append(value); - return this; - } + public AndroidTextFieldDialog setText(CharSequence value){ + userInput.append(value); + return this; + } - public AndroidTextFieldDialog setCancelButtonLabel(CharSequence label) { - builder.setNegativeButton(label, (dialog, id) -> dialog.cancel()); - return this; - } + public AndroidTextFieldDialog setCancelButtonLabel(CharSequence label){ + builder.setNegativeButton(label, (dialog, id) -> dialog.cancel()); + return this; + } - public AndroidTextFieldDialog setConfirmButtonLabel(CharSequence label) { - builder.setPositiveButton(label, (dialog, id) -> { - if (listener != null && !userInput.getText().toString().isEmpty()) { + public AndroidTextFieldDialog setConfirmButtonLabel(CharSequence label){ + builder.setPositiveButton(label, (dialog, id) -> { + if(listener != null && !userInput.getText().toString().isEmpty()){ listener.confirm(userInput.getText().toString()); } }); - return this; - } + return this; + } - public AndroidTextFieldDialog setTextPromptListener(TextPromptListener listener) { - this.listener = listener; - return this; - } + public AndroidTextFieldDialog setTextPromptListener(TextPromptListener listener){ + this.listener = listener; + return this; + } - public AndroidTextFieldDialog setInputType(int type) { - userInput.setInputType(type); - return this; - } + public AndroidTextFieldDialog setInputType(int type){ + userInput.setInputType(type); + return this; + } - public AndroidTextFieldDialog setMaxLength(int length) { - userInput.setFilters(new InputFilter[] { new InputFilter.LengthFilter(length) }); - return this; - } - - public interface TextPromptListener{ - void confirm(String text); - } + public AndroidTextFieldDialog setMaxLength(int length){ + userInput.setFilters(new InputFilter[]{new InputFilter.LengthFilter(length)}); + return this; + } + + public interface TextPromptListener{ + void confirm(String text); + } } diff --git a/android/src/io/anuke/mindustry/DonationsActivity.java b/android/src/io/anuke/mindustry/DonationsActivity.java index 690ccc3413..c6e61c61b2 100644 --- a/android/src/io/anuke/mindustry/DonationsActivity.java +++ b/android/src/io/anuke/mindustry/DonationsActivity.java @@ -8,12 +8,9 @@ import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.view.View; import android.widget.Button; - import org.sufficientlysecure.donations.DonationsFragment; -public class DonationsActivity extends FragmentActivity { - DonationsFragment donationsFragment; - +public class DonationsActivity extends FragmentActivity{ /** * Google */ @@ -21,13 +18,14 @@ public class DonationsActivity extends FragmentActivity { private static final String[] GOOGLE_CATALOG = new String[]{ "mindustry.donation.1", "mindustry.donation.2", "mindustry.donation.5", "mindustry.donation.10", "mindustry.donation.15", - "mindustry.donation.25", "mindustry.donation.50" }; + "mindustry.donation.25", "mindustry.donation.50"}; + DonationsFragment donationsFragment; /** * Called when the activity is first created. */ @Override - public void onCreate(Bundle savedInstanceState) { + public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setTheme(R.style.GdxTheme); @@ -35,7 +33,7 @@ public class DonationsActivity extends FragmentActivity { setContentView(R.layout.donations_activity); FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - if (BuildConfig.DONATIONS_GOOGLE) { + if(BuildConfig.DONATIONS_GOOGLE){ donationsFragment = DonationsFragment.newInstance(BuildConfig.DEBUG, true, GOOGLE_PUBKEY, GOOGLE_CATALOG, getResources().getStringArray(R.array.donation_google_catalog_values), false, null, null, null, false, null, null, false, null); @@ -48,9 +46,10 @@ public class DonationsActivity extends FragmentActivity { public void onStart(){ super.onStart(); - Button b = ((Button)findViewById(org.sufficientlysecure.donations.R.id.donations__google_android_market_donate_button)); - b.setOnClickListener(new View.OnClickListener() { - @Override public void onClick(View view) { + Button b = ((Button) findViewById(org.sufficientlysecure.donations.R.id.donations__google_android_market_donate_button)); + b.setOnClickListener(new View.OnClickListener(){ + @Override + public void onClick(View view){ donationsFragment.donateGoogleOnClick(donationsFragment.getView()); b.setEnabled(false); } @@ -58,20 +57,19 @@ public class DonationsActivity extends FragmentActivity { } - /** * Needed for Google Play In-app Billing. It uses startIntentSenderForResult(). The result is not propagated to * the Fragment like in startActivityForResult(). Thus we need to propagate manually to our Fragment. */ @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { + protected void onActivityResult(int requestCode, int resultCode, Intent data){ super.onActivityResult(requestCode, resultCode, data); - Button b = ((Button)findViewById(org.sufficientlysecure.donations.R.id.donations__google_android_market_donate_button)); + Button b = ((Button) findViewById(org.sufficientlysecure.donations.R.id.donations__google_android_market_donate_button)); b.setEnabled(true); FragmentManager fragmentManager = getSupportFragmentManager(); Fragment fragment = fragmentManager.findFragmentByTag("donationsFragment"); - if (fragment != null) { + if(fragment != null){ fragment.onActivityResult(requestCode, resultCode, data); //TODO donation event, set settings? } diff --git a/android/src/io/anuke/mindustry/TextFieldDialogListener.java b/android/src/io/anuke/mindustry/TextFieldDialogListener.java index c6f328d785..be1cc6d924 100644 --- a/android/src/io/anuke/mindustry/TextFieldDialogListener.java +++ b/android/src/io/anuke/mindustry/TextFieldDialogListener.java @@ -11,57 +11,57 @@ import io.anuke.ucore.scene.event.InputListener; import io.anuke.ucore.scene.ui.TextField; public class TextFieldDialogListener extends ClickListener{ - private TextField field; - private int type; - private int max; + private TextField field; + private int type; + private int max; - public static void add(TextField field, int type, int max){ - field.addListener(new TextFieldDialogListener(field, type, max)); - field.addListener(new InputListener(){ - public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) { - Gdx.input.setOnscreenKeyboardVisible(false); - return false; - } - }); - } + //type - 0 is text, 1 is numbers, 2 is decimals + public TextFieldDialogListener(TextField field, int type, int max){ + this.field = field; + this.type = type; + this.max = max; + } - public static void add(TextField field){ - add(field, 0, 16); - } + public static void add(TextField field, int type, int max){ + field.addListener(new TextFieldDialogListener(field, type, max)); + field.addListener(new InputListener(){ + public boolean touchDown(InputEvent event, float x, float y, int pointer, int button){ + Gdx.input.setOnscreenKeyboardVisible(false); + return false; + } + }); + } - //type - 0 is text, 1 is numbers, 2 is decimals - public TextFieldDialogListener(TextField field, int type, int max){ - this.field = field; - this.type = type; - this.max = max; - } + public static void add(TextField field){ + add(field, 0, 16); + } - public void clicked(final InputEvent event, float x, float y){ - - if(Gdx.app.getType() == ApplicationType.Desktop) return; - - AndroidTextFieldDialog dialog = new AndroidTextFieldDialog(); + public void clicked(final InputEvent event, float x, float y){ - dialog.setTextPromptListener(text -> { + if(Gdx.app.getType() == ApplicationType.Desktop) return; + + AndroidTextFieldDialog dialog = new AndroidTextFieldDialog(); + + dialog.setTextPromptListener(text -> { field.clearText(); field.appendText(text); field.fire(new ChangeListener.ChangeEvent()); Gdx.graphics.requestRendering(); }); - if(type == 0){ - dialog.setInputType(InputType.TYPE_CLASS_TEXT); - }else if(type == 1){ - dialog.setInputType(InputType.TYPE_CLASS_NUMBER); - }else if(type == 2){ - dialog.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL); - } + if(type == 0){ + dialog.setInputType(InputType.TYPE_CLASS_TEXT); + }else if(type == 1){ + dialog.setInputType(InputType.TYPE_CLASS_NUMBER); + }else if(type == 2){ + dialog.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL); + } - dialog.setConfirmButtonLabel("OK").setText(field.getText()); - dialog.setCancelButtonLabel("Cancel"); - dialog.setMaxLength(max); - dialog.show(); - event.cancel(); + dialog.setConfirmButtonLabel("OK").setText(field.getText()); + dialog.setCancelButtonLabel("Cancel"); + dialog.setMaxLength(max); + dialog.show(); + event.cancel(); - } + } } diff --git a/annotations/src/io/anuke/annotations/Annotations.java b/annotations/src/io/anuke/annotations/Annotations.java index d685729921..cc60478fee 100644 --- a/annotations/src/io/anuke/annotations/Annotations.java +++ b/annotations/src/io/anuke/annotations/Annotations.java @@ -9,70 +9,31 @@ import java.lang.annotation.Target; * Goal: To create a system to send events to the server from the client and vice versa, without creating a new packet type each time.
* These events may optionally also trigger on the caller client/server as well.
*/ -public class Annotations { +public class Annotations{ - /**Marks a method as invokable remotely across a server/client connection.*/ - @Target(ElementType.METHOD) - @Retention(RetentionPolicy.CLASS) - public @interface Remote { - /**Specifies the locations from which this method can be invoked.*/ - Loc targets() default Loc.server; - /**Specifies which methods are generated. Only affects server-to-client methods.*/ - Variant variants() default Variant.all; - /**The local locations where this method is called locally, when invoked.*/ - Loc called() default Loc.none; - /**Whether to forward this packet to all other clients upon recieval. Client only.*/ - boolean forward() default false; - /**Whether the packet for this method is sent with UDP instead of TCP. - * UDP is faster, but is prone to packet loss and duplication.*/ - boolean unreliable() default false; - /**The simple class name where this method is placed.*/ - String in() default "Call"; - /**Priority of this event.*/ - PacketPriority priority() default PacketPriority.normal; - } - - /**Specifies that this method will be used to write classes of the type returned by {@link #value()}.
- * This method must return void and have two parameters, the first being of type {@link java.nio.ByteBuffer} and the second - * being the type returned by {@link #value()}.*/ - @Target(ElementType.METHOD) - @Retention(RetentionPolicy.CLASS) - public @interface WriteClass { - Class value(); - } - - /**Specifies that this method will be used to read classes of the type returned by {@link #value()}.
- * This method must return the type returned by {@link #value()}, - * and have one parameter, being of type {@link java.nio.ByteBuffer}.*/ - @Target(ElementType.METHOD) - @Retention(RetentionPolicy.CLASS) - public @interface ReadClass { - Class value(); - } - - public enum PacketPriority { - /**Gets put in a queue and processed if not connected.*/ + public enum PacketPriority{ + /** Gets put in a queue and processed if not connected. */ normal, - /**Gets handled immediately, regardless of connection status.*/ + /** Gets handled immediately, regardless of connection status. */ high, - /**Does not get handled unless client is connected.*/ + /** Does not get handled unless client is connected. */ low } - /**A set of two booleans, one specifying server and one specifying client.*/ - public enum Loc { - /**Method can only be invoked on the client from the server.*/ + /** A set of two booleans, one specifying server and one specifying client. */ + public enum Loc{ + /** Method can only be invoked on the client from the server. */ server(true, false), - /**Method can only be invoked on the server from the client.*/ + /** Method can only be invoked on the server from the client. */ client(false, true), - /**Method can be invoked from anywhere*/ + /** Method can be invoked from anywhere */ both(true, true), - /**Neither server nor client.*/ + /** Neither server nor client. */ none(false, false); - /**If true, this method can be invoked ON clients FROM servers.*/ + /** If true, this method can be invoked ON clients FROM servers. */ public final boolean isServer; - /**If true, this method can be invoked ON servers FROM clients.*/ + /** If true, this method can be invoked ON servers FROM clients. */ public final boolean isClient; Loc(boolean server, boolean client){ @@ -81,12 +42,12 @@ public class Annotations { } } - public enum Variant { - /**Method can only be invoked targeting one player.*/ + public enum Variant{ + /** Method can only be invoked targeting one player. */ one(true, false), - /**Method can only be invoked targeting all players.*/ + /** Method can only be invoked targeting all players. */ all(false, true), - /**Method targets both one player and all players.*/ + /** Method targets both one player and all players. */ both(true, true); public final boolean isOne, isAll; @@ -96,4 +57,55 @@ public class Annotations { this.isAll = isAll; } } + + /** Marks a method as invokable remotely across a server/client connection. */ + @Target(ElementType.METHOD) + @Retention(RetentionPolicy.CLASS) + public @interface Remote{ + /** Specifies the locations from which this method can be invoked. */ + Loc targets() default Loc.server; + + /** Specifies which methods are generated. Only affects server-to-client methods. */ + Variant variants() default Variant.all; + + /** The local locations where this method is called locally, when invoked. */ + Loc called() default Loc.none; + + /** Whether to forward this packet to all other clients upon recieval. Client only. */ + boolean forward() default false; + + /** + * Whether the packet for this method is sent with UDP instead of TCP. + * UDP is faster, but is prone to packet loss and duplication. + */ + boolean unreliable() default false; + + /** The simple class name where this method is placed. */ + String in() default "Call"; + + /** Priority of this event. */ + PacketPriority priority() default PacketPriority.normal; + } + + /** + * Specifies that this method will be used to write classes of the type returned by {@link #value()}.
+ * This method must return void and have two parameters, the first being of type {@link java.nio.ByteBuffer} and the second + * being the type returned by {@link #value()}. + */ + @Target(ElementType.METHOD) + @Retention(RetentionPolicy.CLASS) + public @interface WriteClass{ + Class value(); + } + + /** + * Specifies that this method will be used to read classes of the type returned by {@link #value()}.
+ * This method must return the type returned by {@link #value()}, + * and have one parameter, being of type {@link java.nio.ByteBuffer}. + */ + @Target(ElementType.METHOD) + @Retention(RetentionPolicy.CLASS) + public @interface ReadClass{ + Class value(); + } } diff --git a/annotations/src/io/anuke/annotations/ClassEntry.java b/annotations/src/io/anuke/annotations/ClassEntry.java index 3997eb6029..a9be2ec134 100644 --- a/annotations/src/io/anuke/annotations/ClassEntry.java +++ b/annotations/src/io/anuke/annotations/ClassEntry.java @@ -2,14 +2,14 @@ package io.anuke.annotations; import java.util.ArrayList; -/**Represents a class witha list method entries to include in it.*/ -public class ClassEntry { - /**All methods in this generated class.*/ +/** Represents a class witha list method entries to include in it. */ +public class ClassEntry{ + /** All methods in this generated class. */ public final ArrayList methods = new ArrayList<>(); - /**Simple class name.*/ + /** Simple class name. */ public final String name; - public ClassEntry(String name) { + public ClassEntry(String name){ this.name = name; } } diff --git a/annotations/src/io/anuke/annotations/IOFinder.java b/annotations/src/io/anuke/annotations/IOFinder.java index c2dd8e3567..9276b9b887 100644 --- a/annotations/src/io/anuke/annotations/IOFinder.java +++ b/annotations/src/io/anuke/annotations/IOFinder.java @@ -10,12 +10,16 @@ import javax.tools.Diagnostic.Kind; import java.util.HashMap; import java.util.Set; -/**This class finds reader and writer methods annotated by the {@link io.anuke.annotations.Annotations.WriteClass} - * and {@link io.anuke.annotations.Annotations.ReadClass} annotations.*/ -public class IOFinder { +/** + * This class finds reader and writer methods annotated by the {@link io.anuke.annotations.Annotations.WriteClass} + * and {@link io.anuke.annotations.Annotations.ReadClass} annotations. + */ +public class IOFinder{ - /**Finds all class serializers for all types and returns them. Logs errors when necessary. - * Maps fully qualified class names to their serializers.*/ + /** + * Finds all class serializers for all types and returns them. Logs errors when necessary. + * Maps fully qualified class names to their serializers. + */ public HashMap findSerializers(RoundEnvironment env){ HashMap result = new HashMap<>(); @@ -51,33 +55,33 @@ public class IOFinder { } private String getValue(WriteClass write){ - try { + try{ Class type = write.value(); return type.getName(); - }catch (MirroredTypeException e){ + }catch(MirroredTypeException e){ return e.getTypeMirror().toString(); } } private String getValue(ReadClass read){ - try { + try{ Class type = read.value(); return type.getName(); - }catch (MirroredTypeException e){ + }catch(MirroredTypeException e){ return e.getTypeMirror().toString(); } } - /**Information about read/write methods for a specific class type.*/ + /** Information about read/write methods for a specific class type. */ public static class ClassSerializer{ - /**Fully qualified method name of the reader.*/ + /** Fully qualified method name of the reader. */ public final String readMethod; - /**Fully qualified method name of the writer.*/ + /** Fully qualified method name of the writer. */ public final String writeMethod; - /**Fully qualified class type name.*/ + /** Fully qualified class type name. */ public final String classType; - public ClassSerializer(String readMethod, String writeMethod, String classType) { + public ClassSerializer(String readMethod, String writeMethod, String classType){ this.readMethod = readMethod; this.writeMethod = writeMethod; this.classType = classType; diff --git a/annotations/src/io/anuke/annotations/MethodEntry.java b/annotations/src/io/anuke/annotations/MethodEntry.java index ee47fccb4a..3566516372 100644 --- a/annotations/src/io/anuke/annotations/MethodEntry.java +++ b/annotations/src/io/anuke/annotations/MethodEntry.java @@ -6,32 +6,34 @@ import io.anuke.annotations.Annotations.Variant; import javax.lang.model.element.ExecutableElement; -/**Class that repesents a remote method to be constructed and put into a class.*/ -public class MethodEntry { - /**Simple target class name.*/ +/** Class that repesents a remote method to be constructed and put into a class. */ +public class MethodEntry{ + /** Simple target class name. */ public final String className; - /**Fully qualified target method to call.*/ + /** Fully qualified target method to call. */ public final String targetMethod; - /**Whether this method can be called on a client/server.*/ + /** Whether this method can be called on a client/server. */ public final Loc where; - /**Whether an additional 'one' and 'all' method variant is generated. At least one of these must be true. - * Only applicable to client (server-invoked) methods.*/ + /** + * Whether an additional 'one' and 'all' method variant is generated. At least one of these must be true. + * Only applicable to client (server-invoked) methods. + */ public final Variant target; - /**Whether this method is called locally as well as remotely.*/ + /** Whether this method is called locally as well as remotely. */ public final Loc local; - /**Whether this method is unreliable and uses UDP.*/ + /** Whether this method is unreliable and uses UDP. */ public final boolean unreliable; - /**Whether to forward this method call to all other clients when a client invokes it. Server only.*/ + /** Whether to forward this method call to all other clients when a client invokes it. Server only. */ public final boolean forward; - /**Unique method ID.*/ + /** Unique method ID. */ public final int id; - /**The element method associated with this entry.*/ + /** The element method associated with this entry. */ public final ExecutableElement element; - /**The assigned packet priority. Only used in clients.*/ + /** The assigned packet priority. Only used in clients. */ public final PacketPriority priority; public MethodEntry(String className, String targetMethod, Loc where, Variant target, - Loc local, boolean unreliable, boolean forward, int id, ExecutableElement element, PacketPriority priority) { + Loc local, boolean unreliable, boolean forward, int id, ExecutableElement element, PacketPriority priority){ this.className = className; this.forward = forward; this.targetMethod = targetMethod; @@ -45,7 +47,7 @@ public class MethodEntry { } @Override - public int hashCode() { + public int hashCode(){ return targetMethod.hashCode(); } } diff --git a/annotations/src/io/anuke/annotations/RemoteMethodAnnotationProcessor.java b/annotations/src/io/anuke/annotations/RemoteMethodAnnotationProcessor.java index 037ec8129a..b0402b2c55 100644 --- a/annotations/src/io/anuke/annotations/RemoteMethodAnnotationProcessor.java +++ b/annotations/src/io/anuke/annotations/RemoteMethodAnnotationProcessor.java @@ -18,25 +18,25 @@ import java.util.*; import java.util.stream.Collectors; -/**The annotation processor for generating remote method call code.*/ +/** The annotation processor for generating remote method call code. */ @SupportedSourceVersion(SourceVersion.RELEASE_8) @SupportedAnnotationTypes({ - "io.anuke.annotations.Annotations.Remote", - "io.anuke.annotations.Annotations.WriteClass", - "io.anuke.annotations.Annotations.ReadClass", + "io.anuke.annotations.Annotations.Remote", + "io.anuke.annotations.Annotations.WriteClass", + "io.anuke.annotations.Annotations.ReadClass", }) -public class RemoteMethodAnnotationProcessor extends AbstractProcessor { - /**Maximum size of each event packet.*/ +public class RemoteMethodAnnotationProcessor extends AbstractProcessor{ + /** Maximum size of each event packet. */ public static final int maxPacketSize = 4096; - /**Name of the base package to put all the generated classes.*/ + /** Name of the base package to put all the generated classes. */ private static final String packageName = "io.anuke.mindustry.gen"; - /**Name of class that handles reading and invoking packets on the server.*/ + /** Name of class that handles reading and invoking packets on the server. */ private static final String readServerName = "RemoteReadServer"; - /**Name of class that handles reading and invoking packets on the client.*/ + /** Name of class that handles reading and invoking packets on the client. */ private static final String readClientName = "RemoteReadClient"; - /**Processing round number.*/ + /** Processing round number. */ private int round; //class serializers @@ -51,7 +51,7 @@ public class RemoteMethodAnnotationProcessor extends AbstractProcessor { private ArrayList classes; @Override - public synchronized void init(ProcessingEnvironment processingEnv) { + public synchronized void init(ProcessingEnvironment processingEnv){ super.init(processingEnv); //put all relevant utils into utils class Utils.typeUtils = processingEnv.getTypeUtils(); @@ -61,15 +61,15 @@ public class RemoteMethodAnnotationProcessor extends AbstractProcessor { } @Override - public boolean process(Set annotations, RoundEnvironment roundEnv) { + public boolean process(Set annotations, RoundEnvironment roundEnv){ if(round > 1) return false; //only process 2 rounds - round ++; + round++; - try { + try{ //round 1: find all annotations, generate *writers* - if(round == 1) { + if(round == 1){ //get serializers serializers = new IOFinder().findSerializers(roundEnv); @@ -88,21 +88,21 @@ public class RemoteMethodAnnotationProcessor extends AbstractProcessor { orderedElements.sort(Comparator.comparing(Object::toString)); //create methods - for (Element element : orderedElements) { + for(Element element : orderedElements){ Remote annotation = element.getAnnotation(Remote.class); //check for static - if (!element.getModifiers().contains(Modifier.STATIC) || !element.getModifiers().contains(Modifier.PUBLIC)) { + if(!element.getModifiers().contains(Modifier.STATIC) || !element.getModifiers().contains(Modifier.PUBLIC)){ Utils.messager.printMessage(Kind.ERROR, "All @Remote methods must be public and static: ", element); } //can't generate none methods - if (annotation.targets() == Loc.none) { + if(annotation.targets() == Loc.none){ Utils.messager.printMessage(Kind.ERROR, "A @Remote method's targets() cannot be equal to 'none':", element); } //get and create class entry if needed - if (!classMap.containsKey(annotation.in())) { + if(!classMap.containsKey(annotation.in())){ ClassEntry clas = new ClassEntry(annotation.in()); classMap.put(annotation.in(), clas); classes.add(clas); @@ -127,7 +127,7 @@ public class RemoteMethodAnnotationProcessor extends AbstractProcessor { writegen.generateFor(classes, packageName); return true; - }else if(round == 2) { //round 2: generate all *readers* + }else if(round == 2){ //round 2: generate all *readers* RemoteReadGenerator readgen = new RemoteReadGenerator(serializers); //generate server readers @@ -147,7 +147,7 @@ public class RemoteMethodAnnotationProcessor extends AbstractProcessor { return true; } - }catch (Exception e){ + }catch(Exception e){ e.printStackTrace(); throw new RuntimeException(e); } diff --git a/annotations/src/io/anuke/annotations/RemoteReadGenerator.java b/annotations/src/io/anuke/annotations/RemoteReadGenerator.java index ae2ab83de7..5898e369a1 100644 --- a/annotations/src/io/anuke/annotations/RemoteReadGenerator.java +++ b/annotations/src/io/anuke/annotations/RemoteReadGenerator.java @@ -14,22 +14,25 @@ import java.nio.ByteBuffer; import java.util.HashMap; import java.util.List; -/**Generates code for reading remote invoke packets on the client and server.*/ -public class RemoteReadGenerator { +/** Generates code for reading remote invoke packets on the client and server. */ +public class RemoteReadGenerator{ private final HashMap serializers; - /**Creates a read generator that uses the supplied serializer setup.*/ - public RemoteReadGenerator(HashMap serializers) { + /** Creates a read generator that uses the supplied serializer setup. */ + public RemoteReadGenerator(HashMap serializers){ this.serializers = serializers; } - /**Generates a class for reading remote invoke packets. + /** + * Generates a class for reading remote invoke packets. + * * @param entries List of methods to use/ * @param className Simple target class name. * @param packageName Full target package name. - * @param needsPlayer Whether this read method requires a reference to the player sender.*/ + * @param needsPlayer Whether this read method requires a reference to the player sender. + */ public void generateFor(List entries, String className, String packageName, boolean needsPlayer) - throws IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException, IOException { + throws IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException, IOException{ TypeSpec.Builder classBuilder = TypeSpec.classBuilder(className).addModifiers(Modifier.PUBLIC); @@ -69,10 +72,10 @@ public class RemoteReadGenerator { StringBuilder varResult = new StringBuilder(); //go through each parameter - for(int i = 0; i < entry.element.getParameters().size(); i ++){ + for(int i = 0; i < entry.element.getParameters().size(); i++){ VariableElement var = entry.element.getParameters().get(i); - if(!needsPlayer || i != 0) { //if client, skip first parameter since it's always of type player and doesn't need to be read + if(!needsPlayer || i != 0){ //if client, skip first parameter since it's always of type player and doesn't need to be read //full type name of parameter String typeName = var.asType().toString(); //name of parameter @@ -81,17 +84,17 @@ public class RemoteReadGenerator { String capName = typeName.equals("byte") ? "" : Character.toUpperCase(typeName.charAt(0)) + typeName.substring(1); //write primitives automatically - if (Utils.isPrimitive(typeName)) { - if (typeName.equals("boolean")) { + if(Utils.isPrimitive(typeName)){ + if(typeName.equals("boolean")){ readBlock.addStatement("boolean " + varName + " = buffer.get() == 1"); - } else { + }else{ readBlock.addStatement(typeName + " " + varName + " = buffer.get" + capName + "()"); } - } else { + }else{ //else, try and find a serializer ClassSerializer ser = serializers.get(typeName); - if (ser == null) { //make sure a serializer exists! + if(ser == null){ //make sure a serializer exists! Utils.messager.printMessage(Kind.ERROR, "No @ReadClass method to read class type: '" + typeName + "'", var); return; } @@ -121,7 +124,7 @@ public class RemoteReadGenerator { } readBlock.nextControlFlow("catch (java.lang.Exception e)"); - readBlock.addStatement("throw new java.lang.RuntimeException(\"Failed to to read remote method '"+entry.element.getSimpleName() +"'!\", e)"); + readBlock.addStatement("throw new java.lang.RuntimeException(\"Failed to to read remote method '" + entry.element.getSimpleName() + "'!\", e)"); readBlock.endControlFlow(); } diff --git a/annotations/src/io/anuke/annotations/RemoteWriteGenerator.java b/annotations/src/io/anuke/annotations/RemoteWriteGenerator.java index 03be5844ac..86502f96a3 100644 --- a/annotations/src/io/anuke/annotations/RemoteWriteGenerator.java +++ b/annotations/src/io/anuke/annotations/RemoteWriteGenerator.java @@ -14,17 +14,17 @@ import java.nio.ByteBuffer; import java.util.HashMap; import java.util.List; -/**Generates code for writing remote invoke packets on the client and server.*/ -public class RemoteWriteGenerator { +/** Generates code for writing remote invoke packets on the client and server. */ +public class RemoteWriteGenerator{ private final HashMap serializers; - /**Creates a write generator that uses the supplied serializer setup.*/ - public RemoteWriteGenerator(HashMap serializers) { + /** Creates a write generator that uses the supplied serializer setup. */ + public RemoteWriteGenerator(HashMap serializers){ this.serializers = serializers; } - /**Generates all classes in this list.*/ - public void generateFor(List entries, String packageName) throws IOException { + /** Generates all classes in this list. */ + public void generateFor(List entries, String packageName) throws IOException{ for(ClassEntry entry : entries){ //create builder @@ -58,7 +58,7 @@ public class RemoteWriteGenerator { } } - /**Creates a specific variant for a method entry.*/ + /** Creates a specific variant for a method entry. */ private void writeMethodVariant(TypeSpec.Builder classBuilder, MethodEntry methodEntry, boolean toAll, boolean forwarded){ ExecutableElement elem = methodEntry.element; @@ -99,7 +99,7 @@ public class RemoteWriteGenerator { if(!forwarded && methodEntry.local != Loc.none){ //add in local checks if(methodEntry.local != Loc.both){ - method.beginControlFlow("if("+getCheckString(methodEntry.local) + " || !io.anuke.mindustry.net.Net.active())"); + method.beginControlFlow("if(" + getCheckString(methodEntry.local) + " || !io.anuke.mindustry.net.Net.active())"); } //concatenate parameters @@ -109,16 +109,16 @@ public class RemoteWriteGenerator { //special case: calling local-only methods uses the local player if(index == 0 && methodEntry.where == Loc.client){ results.append("io.anuke.mindustry.Vars.players[0]"); - }else { + }else{ results.append(var.getSimpleName()); } if(index != elem.getParameters().size() - 1) results.append(", "); - index ++; + index++; } //add the statement to call it method.addStatement("$N." + elem.getSimpleName() + "(" + results.toString() + ")", - ((TypeElement)elem.getEnclosingElement()).getQualifiedName().toString()); + ((TypeElement) elem.getEnclosingElement()).getQualifiedName().toString()); if(methodEntry.local != Loc.both){ method.endControlFlow(); @@ -126,7 +126,7 @@ public class RemoteWriteGenerator { } //start control flow to check if it's actually client/server so no netcode is called - method.beginControlFlow("if("+getCheckString(methodEntry.where)+")"); + method.beginControlFlow("if(" + getCheckString(methodEntry.where) + ")"); //add statement to create packet from pool method.addStatement("$1N packet = $2N.obtain($1N.class)", "io.anuke.mindustry.net.Packets.InvokePacket", "io.anuke.ucore.util.Pooling"); @@ -139,7 +139,7 @@ public class RemoteWriteGenerator { //rewind buffer method.addStatement("TEMP_BUFFER.position(0)"); - for(int i = 0; i < elem.getParameters().size(); i ++){ + for(int i = 0; i < elem.getParameters().size(); i++){ //first argument is skipped as it is always the player caller if((!methodEntry.where.isServer/* || methodEntry.mode == Loc.both*/) && i == 0){ continue; @@ -164,7 +164,7 @@ public class RemoteWriteGenerator { method.beginControlFlow("if(io.anuke.mindustry.net.Net.server())"); } - if(Utils.isPrimitive(typeName)) { //check if it's a primitive, and if so write it + if(Utils.isPrimitive(typeName)){ //check if it's a primitive, and if so write it if(typeName.equals("boolean")){ //booleans are special method.addStatement("TEMP_BUFFER.put(" + varName + " ? (byte)1 : 0)"); }else{ @@ -181,7 +181,7 @@ public class RemoteWriteGenerator { } //add statement for writing it - method.addStatement(ser.writeMethod + "(TEMP_BUFFER, " + varName +")"); + method.addStatement(ser.writeMethod + "(TEMP_BUFFER, " + varName + ")"); } if(writePlayerSkipCheck){ //write end check @@ -197,7 +197,7 @@ public class RemoteWriteGenerator { if(forwarded){ //forward packet if(!methodEntry.local.isClient){ //if the client doesn't get it called locally, forward it back after validation sendString = "send("; - }else { + }else{ sendString = "sendExcept(exceptSenderID, "; } }else if(toAll){ //send to all players / to server @@ -207,8 +207,8 @@ public class RemoteWriteGenerator { } //send the actual packet - method.addStatement("io.anuke.mindustry.net.Net." + sendString + "packet, "+ - (methodEntry.unreliable ? "io.anuke.mindustry.net.Net.SendMode.udp" : "io.anuke.mindustry.net.Net.SendMode.tcp")+")"); + method.addStatement("io.anuke.mindustry.net.Net." + sendString + "packet, " + + (methodEntry.unreliable ? "io.anuke.mindustry.net.Net.SendMode.udp" : "io.anuke.mindustry.net.Net.SendMode.tcp") + ")"); //end check for server/client @@ -220,7 +220,7 @@ public class RemoteWriteGenerator { private String getCheckString(Loc loc){ return loc.isClient && loc.isServer ? "io.anuke.mindustry.net.Net.server() || io.anuke.mindustry.net.Net.client()" : - loc.isClient ? "io.anuke.mindustry.net.Net.client()" : - loc.isServer ? "io.anuke.mindustry.net.Net.server()" : "false"; + loc.isClient ? "io.anuke.mindustry.net.Net.client()" : + loc.isServer ? "io.anuke.mindustry.net.Net.server()" : "false"; } } diff --git a/annotations/src/io/anuke/annotations/Utils.java b/annotations/src/io/anuke/annotations/Utils.java index d379a2d257..551d953bc4 100644 --- a/annotations/src/io/anuke/annotations/Utils.java +++ b/annotations/src/io/anuke/annotations/Utils.java @@ -7,14 +7,14 @@ import javax.lang.model.element.TypeElement; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; -public class Utils { +public class Utils{ public static Types typeUtils; public static Elements elementUtils; public static Filer filer; public static Messager messager; public static String getMethodName(Element element){ - return ((TypeElement)element.getEnclosingElement()).getQualifiedName().toString() + "." + element.getSimpleName(); + return ((TypeElement) element.getEnclosingElement()).getQualifiedName().toString() + "." + element.getSimpleName(); } public static boolean isPrimitive(String type){ diff --git a/core/src/Mindustry.gwt.xml b/core/src/Mindustry.gwt.xml index 9f3caa7c8c..95e2e371aa 100644 --- a/core/src/Mindustry.gwt.xml +++ b/core/src/Mindustry.gwt.xml @@ -1,22 +1,22 @@ - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/core/src/io/anuke/mindustry/Mindustry.java b/core/src/io/anuke/mindustry/Mindustry.java index 86cc421e96..804baca4e4 100644 --- a/core/src/io/anuke/mindustry/Mindustry.java +++ b/core/src/io/anuke/mindustry/Mindustry.java @@ -8,35 +8,35 @@ import io.anuke.ucore.util.Log; import static io.anuke.mindustry.Vars.*; -public class Mindustry extends ModuleCore { +public class Mindustry extends ModuleCore{ - @Override - public void init(){ - Timers.mark(); + @Override + public void init(){ + Timers.mark(); - Vars.init(); + Vars.init(); - debug = Platform.instance.isDebug(); + debug = Platform.instance.isDebug(); - Log.setUseColors(false); - BundleLoader.load(); - ContentLoader.load(); + Log.setUseColors(false); + BundleLoader.load(); + ContentLoader.load(); - module(logic = new Logic()); - module(world = new World()); - module(control = new Control()); - module(renderer = new Renderer()); - module(ui = new UI()); - module(netServer = new NetServer()); - module(netClient = new NetClient()); + module(logic = new Logic()); + module(world = new World()); + module(control = new Control()); + module(renderer = new Renderer()); + module(ui = new UI()); + module(netServer = new NetServer()); + module(netClient = new NetClient()); Log.info("Time to load [total]: {0}", Timers.elapsed()); - } + } - @Override - public void render(){ - super.render(); - threads.handleRender(); - } + @Override + public void render(){ + super.render(); + threads.handleRender(); + } } diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java index d98a9c7d50..ba03f4c21f 100644 --- a/core/src/io/anuke/mindustry/Vars.java +++ b/core/src/io/anuke/mindustry/Vars.java @@ -19,173 +19,156 @@ import io.anuke.mindustry.io.Version; import io.anuke.mindustry.net.Net; import io.anuke.ucore.entities.Entities; import io.anuke.ucore.entities.EntityGroup; -import io.anuke.ucore.entities.trait.DrawTrait; import io.anuke.ucore.entities.impl.EffectEntity; +import io.anuke.ucore.entities.trait.DrawTrait; import io.anuke.ucore.scene.ui.layout.Unit; import io.anuke.ucore.util.OS; import java.util.Locale; public class Vars{ - public static boolean testMobile; - //shorthand for whether or not this is running on android or ios - public static boolean mobile; - public static boolean ios; - public static boolean android; - //shorthand for whether or not this is running on GWT - public static boolean gwt; - - //respawn time in frames - public static final float respawnduration = 60*4; - //time between waves in frames (on normal mode) - public static final float wavespace = 60*60*2f; - //waves can last no longer than 3 minutes, otherwise the next one spawns - public static final float maxwavespace = 60*60*4f; - - //set ridiculously high for now - public static final float coreBuildRange = 800999f; - //discord group URL - public static final String discordURL = "https://discord.gg/BKADYds"; - - public static final String releasesURL = "https://api.github.com/repos/Anuken/Mindustry/releases"; - - //directory for user-created map data - public static FileHandle customMapDirectory; - //save file directory - public static FileHandle saveDirectory; - public static String mapExtension = "mmap"; - public static String saveExtension = "msav"; - //scale of the font - public static float fontScale; - //camera zoom displayed on startup - public static int baseCameraScale; - //if true, player speed will be increased, massive amounts of resources will be given on start, and other debug options will be available - public static boolean debug = false; - public static boolean console = false; - //whether the player can clip through walls - public static boolean noclip = false; - //whether turrets have infinite ammo (only with debug) - public static boolean infiniteAmmo = true; - //whether to show paths of enemies - public static boolean showPaths = false; - //if false, player is always hidden - public static boolean showPlayer = true; - //whether to hide ui, only on debug - public static boolean showUI = true; - //whether to show block debug - public static boolean showBlockDebug = false; - - public static boolean showFog = true; - + //respawn time in frames + public static final float respawnduration = 60 * 4; + //time between waves in frames (on normal mode) + public static final float wavespace = 60 * 60 * 2f; + //waves can last no longer than 3 minutes, otherwise the next one spawns + public static final float maxwavespace = 60 * 60 * 4f; + //set ridiculously high for now + public static final float coreBuildRange = 800999f; + //discord group URL + public static final String discordURL = "https://discord.gg/BKADYds"; + public static final String releasesURL = "https://api.github.com/repos/Anuken/Mindustry/releases"; public static final int maxTextLength = 150; public static final int maxNameLength = 40; public static final int maxCharNameLength = 20; + public static final int saveSlots = 64; + public static final float itemSize = 5f; + public static final int tilesize = 8; + public static final Locale[] locales = {new Locale("en"), new Locale("fr"), new Locale("ru"), new Locale("uk", "UA"), new Locale("pl"), + new Locale("de"), new Locale("pt", "BR"), new Locale("ko"), new Locale("in", "ID"), new Locale("ita"), new Locale("es")}; + public static final Color[] playerColors = { + Color.valueOf("82759a"), + Color.valueOf("c0c1c5"), + Color.valueOf("fff0e7"), + Color.valueOf("7d2953"), + Color.valueOf("ff074e"), + Color.valueOf("ff072a"), + Color.valueOf("ff76a6"), + Color.valueOf("a95238"), + Color.valueOf("ffa108"), + Color.valueOf("feeb2c"), + Color.valueOf("ffcaa8"), + Color.valueOf("008551"), + Color.valueOf("00e339"), + Color.valueOf("423c7b"), + Color.valueOf("4b5ef1"), + Color.valueOf("2cabfe"), + }; + //server port + public static final int port = 6567; + public static final int webPort = 6568; + public static boolean testMobile; + //shorthand for whether or not this is running on android or ios + public static boolean mobile; + public static boolean ios; + public static boolean android; + //shorthand for whether or not this is running on GWT + public static boolean gwt; + //directory for user-created map data + public static FileHandle customMapDirectory; + //save file directory + public static FileHandle saveDirectory; + public static String mapExtension = "mmap"; + public static String saveExtension = "msav"; + //scale of the font + public static float fontScale; + //camera zoom displayed on startup + public static int baseCameraScale; + //if true, player speed will be increased, massive amounts of resources will be given on start, and other debug options will be available + public static boolean debug = false; + public static boolean console = false; + //whether the player can clip through walls + public static boolean noclip = false; + //whether turrets have infinite ammo (only with debug) + public static boolean infiniteAmmo = true; + //whether to show paths of enemies + public static boolean showPaths = false; + //if false, player is always hidden + public static boolean showPlayer = true; + //whether to hide ui, only on debug + public static boolean showUI = true; + //whether to show block debug + public static boolean showBlockDebug = false; + public static boolean showFog = true; + public static boolean headless = false; + public static float controllerMin = 0.25f; + public static float baseControllerSpeed = 11f; + //only if smoothCamera + public static boolean snapCamera = true; + public static GameState state; + public static ThreadHandler threads; - public static boolean headless = false; + public static Control control; + public static Logic logic; + public static Renderer renderer; + public static UI ui; + public static World world; + public static NetServer netServer; + public static NetClient netClient; - public static float controllerMin = 0.25f; + public static Player[] players = {}; - public static float baseControllerSpeed = 11f; + public static EntityGroup playerGroup; + public static EntityGroup tileGroup; + public static EntityGroup bulletGroup; + public static EntityGroup shieldGroup; + public static EntityGroup effectGroup; + public static EntityGroup groundEffectGroup; + public static EntityGroup itemGroup; - public static final int saveSlots = 64; + public static EntityGroup puddleGroup; + public static EntityGroup fireGroup; + public static EntityGroup[] unitGroups; - public static final float itemSize = 5f; + public static void init(){ + Version.init(); - //only if smoothCamera - public static boolean snapCamera = true; - - public static final int tilesize = 8; + playerGroup = Entities.addGroup(Player.class).enableMapping(); + tileGroup = Entities.addGroup(TileEntity.class, false); + bulletGroup = Entities.addGroup(Bullet.class).enableMapping(); + shieldGroup = Entities.addGroup(Shield.class, false); + effectGroup = Entities.addGroup(EffectEntity.class, false); + groundEffectGroup = Entities.addGroup(DrawTrait.class, false); + puddleGroup = Entities.addGroup(Puddle.class, false).enableMapping(); + itemGroup = Entities.addGroup(ItemDrop.class).enableMapping(); + fireGroup = Entities.addGroup(Fire.class, false).enableMapping(); + unitGroups = new EntityGroup[Team.all.length]; - public static final Locale[] locales = {new Locale("en"), new Locale("fr"), new Locale("ru"), new Locale("uk", "UA"), new Locale("pl"), - new Locale("de"), new Locale("pt", "BR"), new Locale("ko"), new Locale("in", "ID"), new Locale("ita"), new Locale("es")}; + for(Team team : Team.all){ + unitGroups[team.ordinal()] = Entities.addGroup(BaseUnit.class).enableMapping(); + } - public static final Color[] playerColors = { - Color.valueOf("82759a"), - Color.valueOf("c0c1c5"), - Color.valueOf("fff0e7"), - Color.valueOf("7d2953"), - Color.valueOf("ff074e"), - Color.valueOf("ff072a"), - Color.valueOf("ff76a6"), - Color.valueOf("a95238"), - Color.valueOf("ffa108"), - Color.valueOf("feeb2c"), - Color.valueOf("ffcaa8"), - Color.valueOf("008551"), - Color.valueOf("00e339"), - Color.valueOf("423c7b"), - Color.valueOf("4b5ef1"), - Color.valueOf("2cabfe"), - }; + for(EntityGroup group : Entities.getAllGroups()){ + group.setRemoveListener(entity -> { + if(entity instanceof SyncTrait && Net.client()){ + netClient.addRemovedEntity((entity).getID()); + } + }); + } - //server port - public static final int port = 6567; - public static final int webPort = 6568; + threads = new ThreadHandler(Platform.instance.getThreadProvider()); - public static GameState state; - public static ThreadHandler threads; + mobile = Gdx.app.getType() == ApplicationType.Android || Gdx.app.getType() == ApplicationType.iOS || testMobile; + ios = Gdx.app.getType() == ApplicationType.iOS; + android = Gdx.app.getType() == ApplicationType.Android; + gwt = Gdx.app.getType() == ApplicationType.WebGL; - public static Control control; - public static Logic logic; - public static Renderer renderer; - public static UI ui; - public static World world; - public static NetServer netServer; - public static NetClient netClient; - - public static Player[] players = {}; + if(!gwt){ + customMapDirectory = OS.getAppDataDirectory("Mindustry").child("maps/"); + saveDirectory = OS.getAppDataDirectory("Mindustry").child("saves/"); + } - public static EntityGroup playerGroup; - public static EntityGroup tileGroup; - public static EntityGroup bulletGroup; - public static EntityGroup shieldGroup; - public static EntityGroup effectGroup; - public static EntityGroup groundEffectGroup; - public static EntityGroup itemGroup; - - public static EntityGroup puddleGroup; - public static EntityGroup fireGroup; - public static EntityGroup[] unitGroups; - - public static void init(){ - Version.init(); - - playerGroup = Entities.addGroup(Player.class).enableMapping(); - tileGroup = Entities.addGroup(TileEntity.class, false); - bulletGroup = Entities.addGroup(Bullet.class).enableMapping(); - shieldGroup = Entities.addGroup(Shield.class, false); - effectGroup = Entities.addGroup(EffectEntity.class, false); - groundEffectGroup = Entities.addGroup(DrawTrait.class, false); - puddleGroup = Entities.addGroup(Puddle.class, false).enableMapping(); - itemGroup = Entities.addGroup(ItemDrop.class).enableMapping(); - fireGroup = Entities.addGroup(Fire.class, false).enableMapping(); - unitGroups = new EntityGroup[Team.all.length]; - - for(Team team : Team.all){ - unitGroups[team.ordinal()] = Entities.addGroup(BaseUnit.class).enableMapping(); - } - - for(EntityGroup group : Entities.getAllGroups()){ - group.setRemoveListener(entity -> { - if(entity instanceof SyncTrait && Net.client()){ - netClient.addRemovedEntity((entity).getID()); - } - }); - } - - threads = new ThreadHandler(Platform.instance.getThreadProvider()); - - mobile = Gdx.app.getType() == ApplicationType.Android || Gdx.app.getType() == ApplicationType.iOS || testMobile; - ios = Gdx.app.getType() == ApplicationType.iOS; - android = Gdx.app.getType() == ApplicationType.Android; - gwt = Gdx.app.getType() == ApplicationType.WebGL; - - if(!gwt) { - customMapDirectory = OS.getAppDataDirectory("Mindustry").child("maps/"); - saveDirectory = OS.getAppDataDirectory("Mindustry").child("saves/"); - } - - fontScale = Math.max(Unit.dp.scl(1f)/2f, 0.5f); - baseCameraScale = Math.round(Unit.dp.scl(4)); - } + fontScale = Math.max(Unit.dp.scl(1f) / 2f, 0.5f); + baseCameraScale = Math.round(Unit.dp.scl(4)); + } } diff --git a/core/src/io/anuke/mindustry/ai/BlockIndexer.java b/core/src/io/anuke/mindustry/ai/BlockIndexer.java index 38a3f8309f..ae21cd4e13 100644 --- a/core/src/io/anuke/mindustry/ai/BlockIndexer.java +++ b/core/src/io/anuke/mindustry/ai/BlockIndexer.java @@ -26,32 +26,53 @@ import static io.anuke.mindustry.Vars.*; //TODO consider using quadtrees for finding specific types of blocks within an area //TODO maybe use Arrays instead of ObjectSets? -/**Class used for indexing special target blocks for AI.*/ -public class BlockIndexer { - /**Size of one ore quadrant.*/ + +/** + * Class used for indexing special target blocks for AI. + */ +public class BlockIndexer{ + /** + * Size of one ore quadrant. + */ private final static int oreQuadrantSize = 20; - /**Size of one structure quadrant.*/ + /** + * Size of one structure quadrant. + */ private final static int structQuadrantSize = 12; - /**Set of all ores that are being scanned.*/ + /** + * Set of all ores that are being scanned. + */ private final ObjectSet scanOres = ObjectSet.with(Items.tungsten, Items.coal, Items.lead, Items.thorium, Items.titanium); - /**Stores all ore quadtrants on the map.*/ - private ObjectMap> ores; - private final ObjectSet itemSet = new ObjectSet<>(); - - /**Tags all quadrants.*/ + /** + * Stores all ore quadtrants on the map. + */ + private ObjectMap> ores; + /** + * Tags all quadrants. + */ private Bits[] structQuadrants; - /**Maps teams to a map of flagged tiles by type.*/ + /** + * Maps teams to a map of flagged tiles by type. + */ private ObjectMap> enemyMap = new ObjectMap<>(); - /**Maps teams to a map of flagged tiles by type.*/ + /** + * Maps teams to a map of flagged tiles by type. + */ private ObjectMap> allyMap = new ObjectMap<>(); - /**Empty map for invalid teams.*/ + /** + * Empty map for invalid teams. + */ private ObjectMap> emptyMap = new ObjectMap<>(); - /**Maps tile positions to their last known tile index data.*/ + /** + * Maps tile positions to their last known tile index data. + */ private IntMap typeMap = new IntMap<>(); - /**Empty array used for returning.*/ + /** + * Empty array used for returning. + */ private ObjectSet emptyArray = new ObjectSet<>(); public BlockIndexer(){ @@ -74,18 +95,18 @@ public class BlockIndexer { //create bitset for each team type that contains each quadrant structQuadrants = new Bits[Team.all.length]; - for(int i = 0; i < Team.all.length; i ++){ - structQuadrants[i] = new Bits(Mathf.ceil(world.width() / (float)structQuadrantSize) * Mathf.ceil(world.height() / (float)structQuadrantSize)); + for(int i = 0; i < Team.all.length; i++){ + structQuadrants[i] = new Bits(Mathf.ceil(world.width() / (float) structQuadrantSize) * Mathf.ceil(world.height() / (float) structQuadrantSize)); } - for(int x = 0; x < world.width(); x ++){ - for (int y = 0; y < world.height(); y++) { + for(int x = 0; x < world.width(); x++){ + for(int y = 0; y < world.height(); y++){ process(world.tile(x, y)); } } - for (int x = 0; x < quadWidth(); x++) { - for (int y = 0; y < quadHeight(); y++) { + for(int x = 0; x < quadWidth(); x++){ + for(int y = 0; y < quadHeight(); y++){ updateQuadrant(world.tile(x * structQuadrantSize, y * structQuadrantSize)); } } @@ -94,12 +115,16 @@ public class BlockIndexer { }); } - /**Get all allied blocks with a flag.*/ + /** + * Get all allied blocks with a flag. + */ public ObjectSet getAllied(Team team, BlockFlag type){ return (state.teams.get(team).ally ? allyMap : enemyMap).get(type, emptyArray); } - /**Get all enemy blocks with a flag.*/ + /** + * Get all enemy blocks with a flag. + */ public ObjectSet getEnemy(Team team, BlockFlag type){ return (!state.teams.get(team).ally ? allyMap : enemyMap).get(type, emptyArray); } @@ -108,13 +133,13 @@ public class BlockIndexer { Entity closest = null; float dst = 0; - for(int rx = Math.max((int)((x-range)/tilesize/structQuadrantSize), 0); rx <= (int)((x+range)/tilesize/structQuadrantSize) && rx < quadWidth(); rx ++){ - for(int ry = Math.max((int)((y-range)/tilesize/structQuadrantSize), 0); ry <= (int)((y+range)/tilesize/structQuadrantSize) && ry < quadHeight(); ry ++){ + for(int rx = Math.max((int) ((x - range) / tilesize / structQuadrantSize), 0); rx <= (int) ((x + range) / tilesize / structQuadrantSize) && rx < quadWidth(); rx++){ + for(int ry = Math.max((int) ((y - range) / tilesize / structQuadrantSize), 0); ry <= (int) ((y + range) / tilesize / structQuadrantSize) && ry < quadHeight(); ry++){ if(!getQuad(team, rx, ry)) continue; - for(int tx = rx * structQuadrantSize; tx < (rx + 1) * structQuadrantSize && tx < world.width(); tx ++){ - for(int ty = ry * structQuadrantSize; ty < (ry + 1) * structQuadrantSize && ty < world.height(); ty ++ ){ + for(int tx = rx * structQuadrantSize; tx < (rx + 1) * structQuadrantSize && tx < world.width(); tx++){ + for(int ty = ry * structQuadrantSize; ty < (ry + 1) * structQuadrantSize && ty < world.height(); ty++){ Tile other = world.tile(tx, ty); if(other == null || other.entity == null || !pred.test(other)) continue; @@ -134,22 +159,26 @@ public class BlockIndexer { return (TileEntity) closest; } - /**Returns a set of tiles that have ores of the specified type nearby. + /** + * Returns a set of tiles that have ores of the specified type nearby. * While each tile in the set is not guaranteed to have an ore directly on it, * each tile will at least have an ore within {@link #oreQuadrantSize} / 2 blocks of it. - * Only specific ore types are scanned. See {@link #scanOres}.*/ + * Only specific ore types are scanned. See {@link #scanOres}. + */ public ObjectSet getOrePositions(Item item){ return ores.get(item, emptyArray); } - /**Find the closest ore block relative to a position.*/ + /** + * Find the closest ore block relative to a position. + */ public Tile findClosestOre(float xp, float yp, Item item){ - Tile tile = Geometry.findClosest(xp, yp, world.indexer().getOrePositions(item)); + Tile tile = Geometry.findClosest(xp, yp, world.indexer().getOrePositions(item)); if(tile == null) return null; - for (int x = Math.max(0, tile.x - oreQuadrantSize/2); x < tile.x + oreQuadrantSize/2 && x < world.width(); x++) { - for (int y = Math.max(0, tile.y - oreQuadrantSize/2); y < tile.y + oreQuadrantSize/2 && y < world.height(); y++) { + for(int x = Math.max(0, tile.x - oreQuadrantSize / 2); x < tile.x + oreQuadrantSize / 2 && x < world.width(); x++){ + for(int y = Math.max(0, tile.y - oreQuadrantSize / 2); y < tile.y + oreQuadrantSize / 2 && y < world.height(); y++){ Tile res = world.tile(x, y); if(res.block() == Blocks.air && res.floor().drops != null && res.floor().drops.item == item){ return res; @@ -186,12 +215,12 @@ public class BlockIndexer { int quadrantY = tile.y / oreQuadrantSize; itemSet.clear(); - Tile rounded = world.tile(Mathf.clamp(quadrantX * oreQuadrantSize + oreQuadrantSize /2, 0, world.width() - 1), - Mathf.clamp(quadrantY * oreQuadrantSize + oreQuadrantSize /2, 0, world.height() - 1)); + Tile rounded = world.tile(Mathf.clamp(quadrantX * oreQuadrantSize + oreQuadrantSize / 2, 0, world.width() - 1), + Mathf.clamp(quadrantY * oreQuadrantSize + oreQuadrantSize / 2, 0, world.height() - 1)); //find all items that this quadrant contains - for (int x = quadrantX * structQuadrantSize; x < world.width() && x < (quadrantX + 1) * structQuadrantSize; x++) { - for (int y = quadrantY * structQuadrantSize; y < world.height() && y < (quadrantY + 1) * structQuadrantSize; y++) { + for(int x = quadrantX * structQuadrantSize; x < world.width() && x < (quadrantX + 1) * structQuadrantSize; x++){ + for(int y = quadrantY * structQuadrantSize; y < world.height() && y < (quadrantY + 1) * structQuadrantSize; y++){ Tile result = world.tile(x, y); if(result.block().drops == null || !scanOres.contains(result.block().drops.item)) continue; @@ -200,7 +229,7 @@ public class BlockIndexer { } //update quadrant at this position - for (Item item : scanOres){ + for(Item item : scanOres){ ObjectSet set = ores.get(item); //update quadrant status depending on whether the item is in it @@ -219,7 +248,7 @@ public class BlockIndexer { int index = quadrantX + quadrantY * quadWidth(); //Log.info("Updating quadrant: {0} {1}", quadrantX, quadrantY); - for(TeamData data : state.teams.getTeams()) { + for(TeamData data : state.teams.getTeams()){ //fast-set this quadrant to 'occupied' if the tile just placed is already of this team if(tile.getTeam() == data.team && tile.entity != null){ @@ -230,8 +259,8 @@ public class BlockIndexer { structQuadrants[data.team.ordinal()].clear(index); outer: - for (int x = quadrantX * structQuadrantSize; x < world.width() && x < (quadrantX + 1) * structQuadrantSize; x++) { - for (int y = quadrantY * structQuadrantSize; y < world.height() && y < (quadrantY + 1) * structQuadrantSize; y++) { + for(int x = quadrantX * structQuadrantSize; x < world.width() && x < (quadrantX + 1) * structQuadrantSize; x++){ + for(int y = quadrantY * structQuadrantSize; y < world.height() && y < (quadrantY + 1) * structQuadrantSize; y++){ Tile result = world.tile(x, y); //when a targetable block is found, mark this quadrant as occupied and stop searching if(result.entity != null && result.getTeam() == data.team){ @@ -244,16 +273,16 @@ public class BlockIndexer { } private boolean getQuad(Team team, int quadrantX, int quadrantY){ - int index = quadrantX + quadrantY * Mathf.ceil(world.width() / (float)structQuadrantSize); + int index = quadrantX + quadrantY * Mathf.ceil(world.width() / (float) structQuadrantSize); return structQuadrants[team.ordinal()].get(index); } private int quadWidth(){ - return Mathf.ceil(world.width() / (float)structQuadrantSize); + return Mathf.ceil(world.width() / (float) structQuadrantSize); } private int quadHeight(){ - return Mathf.ceil(world.height() / (float)structQuadrantSize); + return Mathf.ceil(world.height() / (float) structQuadrantSize); } private ObjectMap> getMap(Team team){ @@ -269,10 +298,10 @@ public class BlockIndexer { ores.put(item, new ObjectSet<>()); } - for(int x = 0; x < world.width(); x ++){ - for (int y = 0; y < world.height(); y++) { - int qx = (x/ oreQuadrantSize); - int qy = (y/ oreQuadrantSize); + for(int x = 0; x < world.width(); x++){ + for(int y = 0; y < world.height(); y++){ + int qx = (x / oreQuadrantSize); + int qy = (y / oreQuadrantSize); Tile tile = world.tile(x, y); @@ -280,8 +309,8 @@ public class BlockIndexer { if(tile.floor().drops != null && scanOres.contains(tile.floor().drops.item) && tile.block() == Blocks.air){ ores.get(tile.floor().drops.item).add(world.tile( //make sure to clamp quadrant middle position, since it might go off bounds - Mathf.clamp(qx * oreQuadrantSize + oreQuadrantSize /2, 0, world.width() - 1), - Mathf.clamp(qy * oreQuadrantSize + oreQuadrantSize /2, 0, world.height() - 1))); + Mathf.clamp(qx * oreQuadrantSize + oreQuadrantSize / 2, 0, world.width() - 1), + Mathf.clamp(qy * oreQuadrantSize + oreQuadrantSize / 2, 0, world.height() - 1))); } } } @@ -291,7 +320,7 @@ public class BlockIndexer { public final EnumSet flags; public final Team team; - public TileIndex(EnumSet flags, Team team) { + public TileIndex(EnumSet flags, Team team){ this.flags = flags; this.team = team; } diff --git a/core/src/io/anuke/mindustry/ai/Pathfinder.java b/core/src/io/anuke/mindustry/ai/Pathfinder.java index 81c6cf01c9..f3290674be 100644 --- a/core/src/io/anuke/mindustry/ai/Pathfinder.java +++ b/core/src/io/anuke/mindustry/ai/Pathfinder.java @@ -20,7 +20,7 @@ import io.anuke.ucore.util.Log; import static io.anuke.mindustry.Vars.state; import static io.anuke.mindustry.Vars.world; -public class Pathfinder { +public class Pathfinder{ private long maxUpdate = TimeUtils.millisToNanos(4); private PathData[] paths; private IntArray blocked = new IntArray(); @@ -56,7 +56,7 @@ public class Pathfinder { Tile target = null; float tl = 0f; - for(GridPoint2 point : Geometry.d8) { + for(GridPoint2 point : Geometry.d8){ int dx = tile.x + point.x, dy = tile.y + point.y; Tile other = world.tile(dx, dy); @@ -89,16 +89,16 @@ public class Pathfinder { } private void update(Tile tile, Team team){ - if(paths[team.ordinal()] != null) { + if(paths[team.ordinal()] != null){ PathData path = paths[team.ordinal()]; if(!passable(tile, team)){ path.weights[tile.x][tile.y] = Float.MAX_VALUE; } - path.search ++; + path.search++; - if(path.lastSearchTime + 1000/60*3 > TimeUtils.millis()){ + if(path.lastSearchTime + 1000 / 60 * 3 > TimeUtils.millis()){ path.frontier.clear(); } @@ -115,17 +115,17 @@ public class Pathfinder { private void createFor(Team team){ PathData path = new PathData(); - path.search ++; + path.search++; path.frontier.ensureCapacity((world.width() + world.height()) * 3); paths[team.ordinal()] = path; - for (int x = 0; x < world.width(); x++) { - for (int y = 0; y < world.height(); y++) { + for(int x = 0; x < world.width(); x++){ + for(int y = 0; y < world.height(); y++){ Tile tile = world.tile(x, y); - if (tile.block().flags != null && state.teams.areEnemies(tile.getTeam(), team) - && tile.block().flags.contains(BlockFlag.target)) { + if(tile.block().flags != null && state.teams.areEnemies(tile.getTeam(), team) + && tile.block().flags.contains(BlockFlag.target)){ path.frontier.addFirst(tile); path.weights[x][y] = 0; path.searches[x][y] = path.search; @@ -143,20 +143,20 @@ public class Pathfinder { long start = TimeUtils.nanoTime(); - while (path.frontier.size > 0 && (nsToRun < 0 || TimeUtils.timeSinceNanos(start) <= nsToRun)) { + while(path.frontier.size > 0 && (nsToRun < 0 || TimeUtils.timeSinceNanos(start) <= nsToRun)){ Tile tile = path.frontier.removeLast(); float cost = path.weights[tile.x][tile.y]; - if (cost < Float.MAX_VALUE) { - for (GridPoint2 point : Geometry.d4) { + if(cost < Float.MAX_VALUE){ + for(GridPoint2 point : Geometry.d4){ int dx = tile.x + point.x, dy = tile.y + point.y; Tile other = world.tile(dx, dy); - if (other != null && (path.weights[dx][dy] > cost + 1 || path.searches[dx][dy] < path.search) + if(other != null && (path.weights[dx][dy] > cost + 1 || path.searches[dx][dy] < path.search) && passable(other, team)){ path.frontier.addFirst(world.tile(dx, dy)); - path.weights[dx][dy] = cost + other.cost/2f; + path.weights[dx][dy] = cost + other.cost / 2f; path.searches[dx][dy] = path.search; } } diff --git a/core/src/io/anuke/mindustry/ai/WaveSpawner.java b/core/src/io/anuke/mindustry/ai/WaveSpawner.java index ed9b8dd60d..96635c2576 100644 --- a/core/src/io/anuke/mindustry/ai/WaveSpawner.java +++ b/core/src/io/anuke/mindustry/ai/WaveSpawner.java @@ -18,7 +18,7 @@ import java.io.IOException; import static io.anuke.mindustry.Vars.*; -public class WaveSpawner { +public class WaveSpawner{ private static final int quadsize = 4; private Bits quadrants; @@ -34,28 +34,28 @@ public class WaveSpawner { public void write(DataOutput output) throws IOException{ output.writeShort(flySpawns.size); - for (FlyerSpawn spawn : flySpawns){ + for(FlyerSpawn spawn : flySpawns){ output.writeFloat(spawn.angle); } output.writeShort(groundSpawns.size); - for (GroundSpawn spawn : groundSpawns){ - output.writeShort((short)spawn.x); - output.writeShort((short)spawn.y); + for(GroundSpawn spawn : groundSpawns){ + output.writeShort((short) spawn.x); + output.writeShort((short) spawn.y); } } public void read(DataInput input) throws IOException{ short flya = input.readShort(); - - for (int i = 0; i < flya; i++) { + + for(int i = 0; i < flya; i++){ FlyerSpawn spawn = new FlyerSpawn(); spawn.angle = input.readFloat(); flySpawns.add(spawn); } - + short grounda = input.readShort(); - for (int i = 0; i < grounda; i++) { + for(int i = 0; i < grounda; i++){ GroundSpawn spawn = new GroundSpawn(); spawn.x = input.readShort(); spawn.y = input.readShort(); @@ -80,13 +80,13 @@ public class WaveSpawner { int addGround = groundGroups - groundSpawns.size, addFly = flyGroups - flySpawns.size; //add extra groups if the total exceeds it - for (int i = 0; i < addGround; i++) { + for(int i = 0; i < addGround; i++){ GroundSpawn spawn = new GroundSpawn(); findLocation(spawn); groundSpawns.add(spawn); } - for (int i = 0; i < addFly; i++) { + for(int i = 0; i < addFly; i++){ FlyerSpawn spawn = new FlyerSpawn(); findLocation(spawn); flySpawns.add(spawn); @@ -99,7 +99,7 @@ public class WaveSpawner { int groups = group.getGroupsSpawned(state.wave); int spawned = group.getUnitsSpawned(state.wave); - for (int i = 0; i < groups; i++) { + for(int i = 0; i < groups; i++){ Squad squad = new Squad(); float spawnX, spawnY; float spread; @@ -109,11 +109,11 @@ public class WaveSpawner { //TODO verify flyer spawn float margin = 40f; //how far away from the edge flying units spawn - spawnX = world.width() *tilesize/2f + Mathf.sqrwavex(spawn.angle) * (world.width()/2f*tilesize + margin); - spawnY = world.height() * tilesize/2f + Mathf.sqrwavey(spawn.angle) * (world.height()/2f*tilesize + margin); + spawnX = world.width() * tilesize / 2f + Mathf.sqrwavex(spawn.angle) * (world.width() / 2f * tilesize + margin); + spawnY = world.height() * tilesize / 2f + Mathf.sqrwavey(spawn.angle) * (world.height() / 2f * tilesize + margin); spread = margin / 1.5f; - flyCount ++; + flyCount++; }else{ GroundSpawn spawn = groundSpawns.get(groundCount); checkQuadrant(spawn.x, spawn.y); @@ -121,14 +121,14 @@ public class WaveSpawner { findLocation(spawn); } - spawnX = spawn.x * quadsize * tilesize + quadsize * tilesize/2f; - spawnY = spawn.y * quadsize * tilesize + quadsize * tilesize/2f; - spread = quadsize*tilesize/3f; + spawnX = spawn.x * quadsize * tilesize + quadsize * tilesize / 2f; + spawnY = spawn.y * quadsize * tilesize + quadsize * tilesize / 2f; + spread = quadsize * tilesize / 3f; - groundCount ++; + groundCount++; } - for (int j = 0; j < spawned; j++) { + for(int j = 0; j < spawned; j++){ BaseUnit unit = group.createUnit(Team.red); unit.setWave(); unit.setSquad(squad); @@ -140,19 +140,19 @@ public class WaveSpawner { } public void checkAllQuadrants(){ - for(int x = 0; x < quadWidth(); x ++){ - for(int y = 0; y < quadHeight(); y ++){ + for(int x = 0; x < quadWidth(); x++){ + for(int y = 0; y < quadHeight(); y++){ checkQuadrant(x, y); } } } - + private void checkQuadrant(int quadx, int quady){ setQuad(quadx, quady, true); outer: - for (int x = quadx * quadsize; x < world.width() && x < (quadx + 1)*quadsize; x++) { - for (int y = quady * quadsize; y < world.height() && y < (quady + 1)*quadsize; y++) { + for(int x = quadx * quadsize; x < world.width() && x < (quadx + 1) * quadsize; x++){ + for(int y = quady * quadsize; y < world.height() && y < (quady + 1) * quadsize; y++){ Tile tile = world.tile(x, y); if(tile == null || tile.solid() || world.pathfinder().getValueforTeam(Team.red, x, y) == Float.MAX_VALUE){ @@ -190,7 +190,7 @@ public class WaveSpawner { spawn.x = -1; spawn.y = -1; - int shellWidth = quadWidth()*2 + quadHeight() * 2 * 6; + int shellWidth = quadWidth() * 2 + quadHeight() * 2 * 6; shellWidth = Math.min(quadWidth() * quadHeight() / 4, shellWidth); Mathf.traverseSpiral(quadWidth(), quadHeight(), Mathf.random(shellWidth), (x, y) -> { @@ -210,11 +210,11 @@ public class WaveSpawner { } private int quadWidth(){ - return Mathf.ceil(world.width() / (float)quadsize); + return Mathf.ceil(world.width() / (float) quadsize); } private int quadHeight(){ - return Mathf.ceil(world.height() / (float)quadsize); + return Mathf.ceil(world.height() / (float) quadsize); } private class FlyerSpawn{ diff --git a/core/src/io/anuke/mindustry/content/AmmoTypes.java b/core/src/io/anuke/mindustry/content/AmmoTypes.java index eb8fefb1a0..1c784a4736 100644 --- a/core/src/io/anuke/mindustry/content/AmmoTypes.java +++ b/core/src/io/anuke/mindustry/content/AmmoTypes.java @@ -9,7 +9,7 @@ import io.anuke.mindustry.game.Content; import io.anuke.mindustry.type.AmmoType; import io.anuke.mindustry.type.ContentList; -public class AmmoTypes implements ContentList { +public class AmmoTypes implements ContentList{ public static AmmoType bulletTungsten, bulletLead, bulletCarbide, bulletThorium, bulletSilicon, bulletPyratite, shotgunTungsten, bombExplosive, bombIncendiary, bombOil, shellCarbide, flamerThermite, weaponMissile, flakLead, flakExplosive, flakPlastic, flakSurge, missileExplosive, missileIncindiary, missileSurge, @@ -17,41 +17,41 @@ public class AmmoTypes implements ContentList { basicFlame, lancerLaser, lightning, spectreLaser, meltdownLaser, fuseShotgun, oil, water, lava, cryofluid; @Override - public void load() { + public void load(){ //weapon specific - shotgunTungsten = new AmmoType(Items.tungsten, WeaponBullets.tungstenShotgun, 2) {{ + shotgunTungsten = new AmmoType(Items.tungsten, WeaponBullets.tungstenShotgun, 2){{ shootEffect = ShootFx.shootBig; smokeEffect = ShootFx.shootBigSmoke; recoil = 1f; }}; - shellCarbide = new AmmoType(Items.carbide, WeaponBullets.shellCarbide, 2) {{ + shellCarbide = new AmmoType(Items.carbide, WeaponBullets.shellCarbide, 2){{ shootEffect = ShootFx.shootBig; smokeEffect = ShootFx.shootBigSmoke; }}; - bombExplosive = new AmmoType(Items.blastCompound, WeaponBullets.bombExplosive, 3) {{ + bombExplosive = new AmmoType(Items.blastCompound, WeaponBullets.bombExplosive, 3){{ shootEffect = Fx.none; smokeEffect = Fx.none; }}; - bombIncendiary = new AmmoType(Items.pyratite, WeaponBullets.bombIncendiary, 3) {{ + bombIncendiary = new AmmoType(Items.pyratite, WeaponBullets.bombIncendiary, 3){{ shootEffect = Fx.none; smokeEffect = Fx.none; }}; - bombOil = new AmmoType(Items.coal, WeaponBullets.bombOil, 3) {{ + bombOil = new AmmoType(Items.coal, WeaponBullets.bombOil, 3){{ shootEffect = Fx.none; smokeEffect = Fx.none; }}; - flamerThermite = new AmmoType(Items.pyratite, TurretBullets.basicFlame, 3) {{ + flamerThermite = new AmmoType(Items.pyratite, TurretBullets.basicFlame, 3){{ shootEffect = ShootFx.shootSmallFlame; }}; - weaponMissile = new AmmoType(Items.carbide, MissileBullets.javelin, 2) {{ + weaponMissile = new AmmoType(Items.carbide, MissileBullets.javelin, 2){{ shootEffect = BulletFx.hitBulletSmall; smokeEffect = Fx.none; reloadMultiplier = 1.2f; @@ -59,37 +59,37 @@ public class AmmoTypes implements ContentList { //bullets - bulletLead = new AmmoType(Items.lead, StandardBullets.lead, 5) {{ + bulletLead = new AmmoType(Items.lead, StandardBullets.lead, 5){{ shootEffect = ShootFx.shootSmall; smokeEffect = ShootFx.shootSmallSmoke; reloadMultiplier = 1.6f; inaccuracy = 5f; }}; - bulletTungsten = new AmmoType(Items.tungsten, StandardBullets.tungsten, 2) {{ + bulletTungsten = new AmmoType(Items.tungsten, StandardBullets.tungsten, 2){{ shootEffect = ShootFx.shootSmall; smokeEffect = ShootFx.shootSmallSmoke; reloadMultiplier = 0.8f; }}; - bulletCarbide = new AmmoType(Items.carbide, StandardBullets.carbide, 2) {{ + bulletCarbide = new AmmoType(Items.carbide, StandardBullets.carbide, 2){{ shootEffect = ShootFx.shootSmall; smokeEffect = ShootFx.shootSmallSmoke; reloadMultiplier = 0.6f; }}; - bulletThorium = new AmmoType(Items.thorium, StandardBullets.thorium, 2) {{ + bulletThorium = new AmmoType(Items.thorium, StandardBullets.thorium, 2){{ shootEffect = ShootFx.shootBig; smokeEffect = ShootFx.shootBigSmoke; }}; - bulletSilicon = new AmmoType(Items.silicon, StandardBullets.homing, 5) {{ + bulletSilicon = new AmmoType(Items.silicon, StandardBullets.homing, 5){{ shootEffect = ShootFx.shootSmall; smokeEffect = ShootFx.shootSmallSmoke; reloadMultiplier = 1.4f; }}; - bulletPyratite = new AmmoType(Items.pyratite, StandardBullets.tracer, 3) {{ + bulletPyratite = new AmmoType(Items.pyratite, StandardBullets.tracer, 3){{ shootEffect = ShootFx.shootSmall; smokeEffect = ShootFx.shootSmallSmoke; inaccuracy = 3f; @@ -97,71 +97,71 @@ public class AmmoTypes implements ContentList { //flak - flakLead = new AmmoType(Items.lead, FlakBullets.lead, 5) {{ + flakLead = new AmmoType(Items.lead, FlakBullets.lead, 5){{ shootEffect = ShootFx.shootSmall; smokeEffect = ShootFx.shootSmallSmoke; }}; - flakExplosive = new AmmoType(Items.blastCompound, FlakBullets.explosive, 5) {{ + flakExplosive = new AmmoType(Items.blastCompound, FlakBullets.explosive, 5){{ shootEffect = ShootFx.shootSmall; smokeEffect = ShootFx.shootSmallSmoke; }}; - flakPlastic = new AmmoType(Items.plastanium, FlakBullets.plastic, 5) {{ + flakPlastic = new AmmoType(Items.plastanium, FlakBullets.plastic, 5){{ shootEffect = ShootFx.shootSmall; smokeEffect = ShootFx.shootSmallSmoke; }}; - flakSurge = new AmmoType(Items.surgealloy, FlakBullets.surge, 5) {{ + flakSurge = new AmmoType(Items.surgealloy, FlakBullets.surge, 5){{ shootEffect = ShootFx.shootSmall; smokeEffect = ShootFx.shootSmallSmoke; }}; //missiles - missileExplosive = new AmmoType(Items.blastCompound, MissileBullets.explosive, 1) {{ + missileExplosive = new AmmoType(Items.blastCompound, MissileBullets.explosive, 1){{ shootEffect = ShootFx.shootBig2; smokeEffect = ShootFx.shootBigSmoke2; reloadMultiplier = 1.2f; }}; - missileIncindiary = new AmmoType(Items.pyratite, MissileBullets.incindiary, 1) {{ + missileIncindiary = new AmmoType(Items.pyratite, MissileBullets.incindiary, 1){{ shootEffect = ShootFx.shootBig2; smokeEffect = ShootFx.shootBigSmoke2; reloadMultiplier = 1.0f; }}; - missileSurge = new AmmoType(Items.surgealloy, MissileBullets.surge, 1) {{ + missileSurge = new AmmoType(Items.surgealloy, MissileBullets.surge, 1){{ shootEffect = ShootFx.shootBig2; smokeEffect = ShootFx.shootBigSmoke2; }}; //artillery - artilleryCarbide = new AmmoType(Items.carbide, ArtilleryBullets.carbide, 2) {{ + artilleryCarbide = new AmmoType(Items.carbide, ArtilleryBullets.carbide, 2){{ shootEffect = ShootFx.shootBig2; smokeEffect = ShootFx.shootBigSmoke2; }}; - artilleryPlastic = new AmmoType(Items.plastanium, ArtilleryBullets.plastic, 2) {{ + artilleryPlastic = new AmmoType(Items.plastanium, ArtilleryBullets.plastic, 2){{ shootEffect = ShootFx.shootBig2; smokeEffect = ShootFx.shootBigSmoke2; reloadMultiplier = 1.4f; }}; - artilleryHoming = new AmmoType(Items.silicon, ArtilleryBullets.homing, 1) {{ + artilleryHoming = new AmmoType(Items.silicon, ArtilleryBullets.homing, 1){{ shootEffect = ShootFx.shootBig2; smokeEffect = ShootFx.shootBigSmoke2; reloadMultiplier = 0.9f; }}; - artilleryIncindiary = new AmmoType(Items.pyratite, ArtilleryBullets.incindiary, 2) {{ + artilleryIncindiary = new AmmoType(Items.pyratite, ArtilleryBullets.incindiary, 2){{ shootEffect = ShootFx.shootBig2; smokeEffect = ShootFx.shootBigSmoke2; reloadMultiplier = 1.2f; }}; - artilleryExplosive = new AmmoType(Items.blastCompound, ArtilleryBullets.explosive, 1) {{ + artilleryExplosive = new AmmoType(Items.blastCompound, ArtilleryBullets.explosive, 1){{ shootEffect = ShootFx.shootBig2; smokeEffect = ShootFx.shootBigSmoke2; reloadMultiplier = 1.6f; @@ -169,7 +169,7 @@ public class AmmoTypes implements ContentList { //flame - basicFlame = new AmmoType(Liquids.oil, TurretBullets.basicFlame, 0.3f) {{ + basicFlame = new AmmoType(Liquids.oil, TurretBullets.basicFlame, 0.3f){{ shootEffect = ShootFx.shootSmallFlame; }}; @@ -198,7 +198,7 @@ public class AmmoTypes implements ContentList { } @Override - public Array getAll() { + public Array getAll(){ return AmmoType.all(); } } diff --git a/core/src/io/anuke/mindustry/content/Items.java b/core/src/io/anuke/mindustry/content/Items.java index eabd520782..d9de2c5513 100644 --- a/core/src/io/anuke/mindustry/content/Items.java +++ b/core/src/io/anuke/mindustry/content/Items.java @@ -12,41 +12,41 @@ public class Items implements ContentList{ biomatter, sand, blastCompound, pyratite; @Override - public void load() { + public void load(){ - stone = new Item("stone", Color.valueOf("777777")) {{ + stone = new Item("stone", Color.valueOf("777777")){{ hardness = 3; }}; - tungsten = new Item("tungsten", Color.valueOf("a0b0c8")) {{ + tungsten = new Item("tungsten", Color.valueOf("a0b0c8")){{ type = ItemType.material; hardness = 1; cost = 0.75f; }}; - lead = new Item("lead", Color.valueOf("8e85a2")) {{ + lead = new Item("lead", Color.valueOf("8e85a2")){{ type = ItemType.material; hardness = 1; cost = 0.6f; }}; - coal = new Item("coal", Color.valueOf("272727")) {{ + coal = new Item("coal", Color.valueOf("272727")){{ explosiveness = 0.2f; flammability = 0.5f; hardness = 2; }}; - carbide = new Item("carbide", Color.valueOf("e2e2e2")) {{ + carbide = new Item("carbide", Color.valueOf("e2e2e2")){{ type = ItemType.material; }}; - titanium = new Item("titanium", Color.valueOf("8da1e3")) {{ + titanium = new Item("titanium", Color.valueOf("8da1e3")){{ type = ItemType.material; hardness = 3; cost = 1.1f; }}; - thorium = new Item("thorium", Color.valueOf("f9a3c7")) {{ + thorium = new Item("thorium", Color.valueOf("f9a3c7")){{ type = ItemType.material; explosiveness = 0.1f; hardness = 4; @@ -54,49 +54,49 @@ public class Items implements ContentList{ cost = 1.2f; }}; - silicon = new Item("silicon", Color.valueOf("53565c")) {{ + silicon = new Item("silicon", Color.valueOf("53565c")){{ type = ItemType.material; cost = 0.9f; }}; - plastanium = new Item("plastanium", Color.valueOf("e9ead3")) {{ + plastanium = new Item("plastanium", Color.valueOf("e9ead3")){{ type = ItemType.material; flammability = 0.1f; explosiveness = 0.1f; cost = 1.5f; }}; - phasematter = new Item("phase-matter", Color.valueOf("f4ba6e")) {{ + phasematter = new Item("phase-matter", Color.valueOf("f4ba6e")){{ type = ItemType.material; cost = 1.5f; }}; - surgealloy = new Item("surge-alloy", Color.valueOf("b4d5c7")) {{ + surgealloy = new Item("surge-alloy", Color.valueOf("b4d5c7")){{ type = ItemType.material; }}; - biomatter = new Item("biomatter", Color.valueOf("648b55")) {{ + biomatter = new Item("biomatter", Color.valueOf("648b55")){{ flammability = 0.4f; fluxiness = 0.2f; }}; - sand = new Item("sand", Color.valueOf("e3d39e")) {{ + sand = new Item("sand", Color.valueOf("e3d39e")){{ fluxiness = 0.5f; }}; - blastCompound = new Item("blast-compound", Color.valueOf("ff795e")) {{ + blastCompound = new Item("blast-compound", Color.valueOf("ff795e")){{ flammability = 0.2f; explosiveness = 0.6f; }}; - pyratite = new Item("pyratite", Color.valueOf("ffaa5f")) {{ + pyratite = new Item("pyratite", Color.valueOf("ffaa5f")){{ flammability = 0.7f; explosiveness = 0.2f; }}; } @Override - public Array getAll() { + public Array getAll(){ return Item.all(); } } diff --git a/core/src/io/anuke/mindustry/content/Liquids.java b/core/src/io/anuke/mindustry/content/Liquids.java index b29705bb32..e1311d4a78 100644 --- a/core/src/io/anuke/mindustry/content/Liquids.java +++ b/core/src/io/anuke/mindustry/content/Liquids.java @@ -6,13 +6,13 @@ import io.anuke.mindustry.game.Content; import io.anuke.mindustry.type.ContentList; import io.anuke.mindustry.type.Liquid; -public class Liquids implements ContentList { +public class Liquids implements ContentList{ public static Liquid water, lava, oil, cryofluid; @Override - public void load() { + public void load(){ - water = new Liquid("water", Color.valueOf("486acd")) { + water = new Liquid("water", Color.valueOf("486acd")){ { heatCapacity = 0.4f; tier = 0; @@ -20,7 +20,7 @@ public class Liquids implements ContentList { } }; - lava = new Liquid("lava", Color.valueOf("e37341")) { + lava = new Liquid("lava", Color.valueOf("e37341")){ { temperature = 0.8f; viscosity = 0.8f; @@ -29,7 +29,7 @@ public class Liquids implements ContentList { } }; - oil = new Liquid("oil", Color.valueOf("313131")) { + oil = new Liquid("oil", Color.valueOf("313131")){ { viscosity = 0.7f; flammability = 0.6f; @@ -39,7 +39,7 @@ public class Liquids implements ContentList { } }; - cryofluid = new Liquid("cryofluid", Color.SKY) { + cryofluid = new Liquid("cryofluid", Color.SKY){ { heatCapacity = 0.9f; temperature = 0.25f; @@ -50,7 +50,7 @@ public class Liquids implements ContentList { } @Override - public Array getAll() { + public Array getAll(){ return Liquid.all(); } } diff --git a/core/src/io/anuke/mindustry/content/Mechs.java b/core/src/io/anuke/mindustry/content/Mechs.java index b141eabd9b..c946060560 100644 --- a/core/src/io/anuke/mindustry/content/Mechs.java +++ b/core/src/io/anuke/mindustry/content/Mechs.java @@ -8,14 +8,16 @@ import io.anuke.mindustry.type.ContentList; import io.anuke.mindustry.type.Mech; import io.anuke.mindustry.type.Upgrade; -public class Mechs implements ContentList { +public class Mechs implements ContentList{ public static Mech alpha, delta, tau, omega, dart, javelin, trident, halberd; - /**These are not new mechs, just re-assignments for convenience.*/ + /** + * These are not new mechs, just re-assignments for convenience. + */ public static Mech starterDesktop, starterMobile; @Override - public void load() { + public void load(){ alpha = new Mech("alpha-mech", false){{ drillPower = 1; @@ -85,7 +87,7 @@ public class Mechs implements ContentList { } @Override - public Array getAll() { + public Array getAll(){ return Upgrade.all(); } } diff --git a/core/src/io/anuke/mindustry/content/Recipes.java b/core/src/io/anuke/mindustry/content/Recipes.java index 43aa5e602b..9bdae7e9ef 100644 --- a/core/src/io/anuke/mindustry/content/Recipes.java +++ b/core/src/io/anuke/mindustry/content/Recipes.java @@ -12,19 +12,19 @@ import static io.anuke.mindustry.type.Category.*; public class Recipes implements ContentList{ @Override - public void load (){ + public void load(){ //WALLS new Recipe(defense, DefenseBlocks.tungstenWall, new ItemStack(Items.tungsten, 12)); - new Recipe(defense, DefenseBlocks.tungstenWallLarge, new ItemStack(Items.tungsten, 12*4)); + new Recipe(defense, DefenseBlocks.tungstenWallLarge, new ItemStack(Items.tungsten, 12 * 4)); new Recipe(defense, DefenseBlocks.carbideWall, new ItemStack(Items.carbide, 12)); - new Recipe(defense, DefenseBlocks.carbideWallLarge, new ItemStack(Items.carbide, 12*4)); + new Recipe(defense, DefenseBlocks.carbideWallLarge, new ItemStack(Items.carbide, 12 * 4)); new Recipe(defense, DefenseBlocks.thoriumWall, new ItemStack(Items.thorium, 12)); - new Recipe(defense, DefenseBlocks.thoriumWallLarge, new ItemStack(Items.thorium, 12*4)); + new Recipe(defense, DefenseBlocks.thoriumWallLarge, new ItemStack(Items.thorium, 12 * 4)); new Recipe(defense, DefenseBlocks.door, new ItemStack(Items.carbide, 12), new ItemStack(Items.silicon, 8)); - new Recipe(defense, DefenseBlocks.doorLarge, new ItemStack(Items.carbide, 12*4), new ItemStack(Items.silicon, 8*4)); + new Recipe(defense, DefenseBlocks.doorLarge, new ItemStack(Items.carbide, 12 * 4), new ItemStack(Items.silicon, 8 * 4)); //TURRETS new Recipe(weapon, TurretBlocks.duo, new ItemStack(Items.tungsten, 40)); @@ -171,7 +171,6 @@ public class Recipes implements ContentList{ new Recipe(production, ProductionBlocks.oilextractor, new ItemStack(Items.titanium, 40), new ItemStack(Items.surgealloy, 40));*/ - //new Recipe(distribution, DistributionBlocks.massDriver, new ItemStack(Items.carbide, 1)); @@ -282,7 +281,7 @@ public class Recipes implements ContentList{ } @Override - public Array getAll() { + public Array getAll(){ return Recipe.all(); } } diff --git a/core/src/io/anuke/mindustry/content/StatusEffects.java b/core/src/io/anuke/mindustry/content/StatusEffects.java index 91e46ce74e..f17656c2e3 100644 --- a/core/src/io/anuke/mindustry/content/StatusEffects.java +++ b/core/src/io/anuke/mindustry/content/StatusEffects.java @@ -3,30 +3,30 @@ package io.anuke.mindustry.content; import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.content.fx.EnvironmentFx; import io.anuke.mindustry.entities.StatusController.StatusEntry; -import io.anuke.mindustry.game.Content; -import io.anuke.mindustry.type.StatusEffect; import io.anuke.mindustry.entities.Unit; +import io.anuke.mindustry.game.Content; import io.anuke.mindustry.type.ContentList; +import io.anuke.mindustry.type.StatusEffect; import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Timers; import io.anuke.ucore.util.Mathf; -public class StatusEffects implements ContentList { +public class StatusEffects implements ContentList{ public static StatusEffect none, burning, freezing, wet, melting, tarred, overdrive, shielded; @Override - public void load() { + public void load(){ none = new StatusEffect(0); - burning = new StatusEffect(4 * 60f) { + burning = new StatusEffect(4 * 60f){ { oppositeScale = 0.5f; } @Override - public StatusEntry getTransition(Unit unit, StatusEffect to, float time, float newTime, StatusEntry result) { - if (to == tarred) { + public StatusEntry getTransition(Unit unit, StatusEffect to, float time, float newTime, StatusEntry result){ + if(to == tarred){ unit.damage(1f); Effects.effect(EnvironmentFx.burning, unit.x + Mathf.range(unit.getSize() / 2f), unit.y + Mathf.range(unit.getSize() / 2f)); return result.set(this, Math.min(time + newTime, baseDuration + tarred.baseDuration)); @@ -36,45 +36,45 @@ public class StatusEffects implements ContentList { } @Override - public void update(Unit unit, float time) { + public void update(Unit unit, float time){ unit.damagePeriodic(0.04f); - if (Mathf.chance(Timers.delta() * 0.2f)) { + if(Mathf.chance(Timers.delta() * 0.2f)){ Effects.effect(EnvironmentFx.burning, unit.x + Mathf.range(unit.getSize() / 2f), unit.y + Mathf.range(unit.getSize() / 2f)); } } }; - freezing = new StatusEffect(5 * 60f) { + freezing = new StatusEffect(5 * 60f){ { oppositeScale = 0.4f; speedMultiplier = 0.7f; } @Override - public void update(Unit unit, float time) { + public void update(Unit unit, float time){ - if (Mathf.chance(Timers.delta() * 0.15f)) { + if(Mathf.chance(Timers.delta() * 0.15f)){ Effects.effect(EnvironmentFx.freezing, unit.x + Mathf.range(unit.getSize() / 2f), unit.y + Mathf.range(unit.getSize() / 2f)); } } }; - wet = new StatusEffect(3 * 60f) { + wet = new StatusEffect(3 * 60f){ { oppositeScale = 0.5f; speedMultiplier = 0.999f; } @Override - public void update(Unit unit, float time) { - if (Mathf.chance(Timers.delta() * 0.15f)) { + public void update(Unit unit, float time){ + if(Mathf.chance(Timers.delta() * 0.15f)){ Effects.effect(EnvironmentFx.wet, unit.x + Mathf.range(unit.getSize() / 2f), unit.y + Mathf.range(unit.getSize() / 2f)); } } }; - melting = new StatusEffect(5 * 60f) { + melting = new StatusEffect(5 * 60f){ { oppositeScale = 0.2f; speedMultiplier = 0.8f; @@ -82,8 +82,8 @@ public class StatusEffects implements ContentList { } @Override - public StatusEntry getTransition(Unit unit, StatusEffect to, float time, float newTime, StatusEntry result) { - if (to == tarred) { + public StatusEntry getTransition(Unit unit, StatusEffect to, float time, float newTime, StatusEntry result){ + if(to == tarred){ return result.set(this, Math.min(time + newTime / 2f, baseDuration)); } @@ -91,30 +91,30 @@ public class StatusEffects implements ContentList { } @Override - public void update(Unit unit, float time) { + public void update(Unit unit, float time){ unit.damagePeriodic(0.3f); - if (Mathf.chance(Timers.delta() * 0.2f)) { + if(Mathf.chance(Timers.delta() * 0.2f)){ Effects.effect(EnvironmentFx.melting, unit.x + Mathf.range(unit.getSize() / 2f), unit.y + Mathf.range(unit.getSize() / 2f)); } } }; - tarred = new StatusEffect(4 * 60f) { + tarred = new StatusEffect(4 * 60f){ { speedMultiplier = 0.6f; } @Override - public void update(Unit unit, float time) { - if (Mathf.chance(Timers.delta() * 0.15f)) { + public void update(Unit unit, float time){ + if(Mathf.chance(Timers.delta() * 0.15f)){ Effects.effect(EnvironmentFx.oily, unit.x + Mathf.range(unit.getSize() / 2f), unit.y + Mathf.range(unit.getSize() / 2f)); } } @Override - public StatusEntry getTransition(Unit unit, StatusEffect to, float time, float newTime, StatusEntry result) { - if (to == melting || to == burning) { + public StatusEntry getTransition(Unit unit, StatusEffect to, float time, float newTime, StatusEntry result){ + if(to == melting || to == burning){ return result.set(to, newTime + time); } @@ -122,7 +122,7 @@ public class StatusEffects implements ContentList { } }; - overdrive = new StatusEffect(6f) { + overdrive = new StatusEffect(6f){ { armorMultiplier = 0.95f; speedMultiplier = 1.05f; @@ -130,13 +130,13 @@ public class StatusEffects implements ContentList { } @Override - public void update(Unit unit, float time) { + public void update(Unit unit, float time){ //idle regen boosted unit.health += 0.01f * Timers.delta(); } }; - shielded = new StatusEffect(6f) { + shielded = new StatusEffect(6f){ { armorMultiplier = 3f; } @@ -149,7 +149,7 @@ public class StatusEffects implements ContentList { } @Override - public Array getAll() { + public Array getAll(){ return StatusEffect.all(); } } diff --git a/core/src/io/anuke/mindustry/content/UnitTypes.java b/core/src/io/anuke/mindustry/content/UnitTypes.java index 8f95a7c3c4..e17da55df6 100644 --- a/core/src/io/anuke/mindustry/content/UnitTypes.java +++ b/core/src/io/anuke/mindustry/content/UnitTypes.java @@ -6,11 +6,11 @@ import io.anuke.mindustry.entities.units.types.*; import io.anuke.mindustry.game.Content; import io.anuke.mindustry.type.ContentList; -public class UnitTypes implements ContentList { +public class UnitTypes implements ContentList{ public static UnitType drone, scout, vtol, monsoon, titan, fabricator; @Override - public void load() { + public void load(){ drone = new UnitType("drone", Drone.class, Drone::new){{ isFlying = true; drag = 0.01f; @@ -73,7 +73,7 @@ public class UnitTypes implements ContentList { } @Override - public Array getAll() { + public Array getAll(){ return UnitType.all(); } } diff --git a/core/src/io/anuke/mindustry/content/Weapons.java b/core/src/io/anuke/mindustry/content/Weapons.java index e3b2321dfa..5ccc7456fc 100644 --- a/core/src/io/anuke/mindustry/content/Weapons.java +++ b/core/src/io/anuke/mindustry/content/Weapons.java @@ -8,13 +8,13 @@ import io.anuke.mindustry.type.ContentList; import io.anuke.mindustry.type.Upgrade; import io.anuke.mindustry.type.Weapon; -public class Weapons implements ContentList { +public class Weapons implements ContentList{ public static Weapon blaster, chainBlaster, shockgun, sapper, swarmer, bomber, flakgun, flamethrower, missiles; @Override - public void load() { + public void load(){ - blaster = new Weapon("blaster") {{ + blaster = new Weapon("blaster"){{ length = 1.5f; reload = 15f; roundrobin = true; @@ -22,7 +22,7 @@ public class Weapons implements ContentList { setAmmo(AmmoTypes.bulletLead); }}; - missiles = new Weapon("missiles") {{ + missiles = new Weapon("missiles"){{ length = 1.5f; reload = 40f; shots = 2; @@ -33,7 +33,7 @@ public class Weapons implements ContentList { setAmmo(AmmoTypes.weaponMissile); }}; - chainBlaster = new Weapon("chain-blaster") {{ + chainBlaster = new Weapon("chain-blaster"){{ length = 1.5f; reload = 30f; roundrobin = true; @@ -41,7 +41,7 @@ public class Weapons implements ContentList { setAmmo(AmmoTypes.bulletLead, AmmoTypes.bulletCarbide, AmmoTypes.bulletTungsten, AmmoTypes.bulletSilicon, AmmoTypes.bulletThorium); }}; - shockgun = new Weapon("shockgun") {{ + shockgun = new Weapon("shockgun"){{ length = 1f; reload = 50f; roundrobin = true; @@ -53,7 +53,7 @@ public class Weapons implements ContentList { setAmmo(AmmoTypes.shotgunTungsten); }}; - flakgun = new Weapon("flakgun") {{ + flakgun = new Weapon("flakgun"){{ length = 1f; reload = 70f; roundrobin = true; @@ -65,7 +65,7 @@ public class Weapons implements ContentList { setAmmo(AmmoTypes.shellCarbide); }}; - flamethrower = new Weapon("flamethrower") {{ + flamethrower = new Weapon("flamethrower"){{ length = 1f; reload = 14f; roundrobin = true; @@ -74,7 +74,7 @@ public class Weapons implements ContentList { setAmmo(AmmoTypes.flamerThermite); }}; - sapper = new Weapon("sapper") {{ + sapper = new Weapon("sapper"){{ length = 1.5f; reload = 12f; roundrobin = true; @@ -82,7 +82,7 @@ public class Weapons implements ContentList { setAmmo(AmmoTypes.bulletCarbide); }}; - swarmer = new Weapon("swarmer") {{ + swarmer = new Weapon("swarmer"){{ length = 1.5f; reload = 10f; roundrobin = true; @@ -90,7 +90,7 @@ public class Weapons implements ContentList { setAmmo(AmmoTypes.bulletPyratite); }}; - bomber = new Weapon("bomber") {{ + bomber = new Weapon("bomber"){{ length = 0f; width = 2f; reload = 5f; @@ -103,7 +103,7 @@ public class Weapons implements ContentList { } @Override - public Array getAll() { + public Array getAll(){ return Upgrade.all(); } } diff --git a/core/src/io/anuke/mindustry/content/blocks/BlockList.java b/core/src/io/anuke/mindustry/content/blocks/BlockList.java index 9bf7eb92ee..e1b7819220 100644 --- a/core/src/io/anuke/mindustry/content/blocks/BlockList.java +++ b/core/src/io/anuke/mindustry/content/blocks/BlockList.java @@ -5,10 +5,10 @@ import io.anuke.mindustry.game.Content; import io.anuke.mindustry.type.ContentList; import io.anuke.mindustry.world.Block; -public abstract class BlockList implements ContentList { +public abstract class BlockList implements ContentList{ @Override - public Array getAll() { + public Array getAll(){ return Block.all(); } } diff --git a/core/src/io/anuke/mindustry/content/blocks/Blocks.java b/core/src/io/anuke/mindustry/content/blocks/Blocks.java index 86a239c042..1268255a74 100644 --- a/core/src/io/anuke/mindustry/content/blocks/Blocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/Blocks.java @@ -15,26 +15,31 @@ public class Blocks extends BlockList implements ContentList{ public static Block air, spawn, blockpart, space, metalfloor, deepwater, water, lava, oil, stone, blackstone, dirt, sand, ice, snow, grass, shrub, rock, icerock, blackrock; - @Override - public void load() { - air = new Floor("air") { + public void load(){ + air = new Floor("air"){ { blend = false; } + //don't draw - public void draw(Tile tile) {} - public void load() {} - public void init() {} + public void draw(Tile tile){ + } + + public void load(){ + } + + public void init(){ + } }; blockpart = new BlockPart(); - for(int i = 1; i <= 6; i ++){ + for(int i = 1; i <= 6; i++){ new BuildBlock("build" + i); } - space = new Floor("space") {{ + space = new Floor("space"){{ placeableOn = false; variants = 0; cacheLayer = CacheLayer.space; @@ -43,11 +48,11 @@ public class Blocks extends BlockList implements ContentList{ minimapColor = Color.valueOf("000001"); }}; - metalfloor = new Floor("metalfloor") {{ + metalfloor = new Floor("metalfloor"){{ variants = 6; }}; - deepwater = new Floor("deepwater") {{ + deepwater = new Floor("deepwater"){{ liquidColor = Color.valueOf("546bb3"); speedMultiplier = 0.2f; variants = 0; @@ -60,7 +65,7 @@ public class Blocks extends BlockList implements ContentList{ minimapColor = Color.valueOf("465a96"); }}; - water = new Floor("water") {{ + water = new Floor("water"){{ liquidColor = Color.valueOf("546bb3"); speedMultiplier = 0.5f; variants = 0; @@ -72,7 +77,7 @@ public class Blocks extends BlockList implements ContentList{ minimapColor = Color.valueOf("506eb4"); }}; - lava = new Floor("lava") {{ + lava = new Floor("lava"){{ liquidColor = Color.valueOf("ed5334"); speedMultiplier = 0.2f; damageTaken = 0.5f; @@ -85,7 +90,7 @@ public class Blocks extends BlockList implements ContentList{ minimapColor = Color.valueOf("ed5334"); }}; - oil = new Floor("oil") {{ + oil = new Floor("oil"){{ liquidColor = Color.valueOf("292929"); status = StatusEffects.tarred; statusIntensity = 1f; @@ -97,7 +102,7 @@ public class Blocks extends BlockList implements ContentList{ minimapColor = Color.valueOf("292929"); }}; - stone = new Floor("stone") {{ + stone = new Floor("stone"){{ hasOres = true; drops = new ItemStack(Items.stone, 1); blends = block -> block != this && !(block instanceof Ore); @@ -105,7 +110,7 @@ public class Blocks extends BlockList implements ContentList{ playerUnmineable = true; }}; - blackstone = new Floor("blackstone") {{ + blackstone = new Floor("blackstone"){{ drops = new ItemStack(Items.stone, 1); minimapColor = Color.valueOf("252525"); playerUnmineable = true; @@ -115,14 +120,14 @@ public class Blocks extends BlockList implements ContentList{ minimapColor = Color.valueOf("6e501e"); }}; - sand = new Floor("sand") {{ + sand = new Floor("sand"){{ drops = new ItemStack(Items.sand, 1); minimapColor = Color.valueOf("988a67"); hasOres = true; playerUnmineable = true; }}; - ice = new Floor("ice") {{ + ice = new Floor("ice"){{ dragMultiplier = 0.3f; speedMultiplier = 0.4f; minimapColor = Color.valueOf("c4e3e7"); @@ -143,15 +148,15 @@ public class Blocks extends BlockList implements ContentList{ shadow = "shrubshadow"; }}; - rock = new Rock("rock") {{ + rock = new Rock("rock"){{ variants = 2; }}; - icerock = new Rock("icerock") {{ + icerock = new Rock("icerock"){{ variants = 2; }}; - blackrock = new Rock("blackrock") {{ + blackrock = new Rock("blackrock"){{ variants = 1; }}; } diff --git a/core/src/io/anuke/mindustry/content/blocks/CraftingBlocks.java b/core/src/io/anuke/mindustry/content/blocks/CraftingBlocks.java index dd97e4a8b9..67ab558fdd 100644 --- a/core/src/io/anuke/mindustry/content/blocks/CraftingBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/CraftingBlocks.java @@ -10,14 +10,14 @@ import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.blocks.production.*; -public class CraftingBlocks extends BlockList implements ContentList { +public class CraftingBlocks extends BlockList implements ContentList{ public static Block smelter, arcsmelter, siliconsmelter, plastaniumCompressor, phaseWeaver, alloysmelter, alloyfuser, pyratiteMixer, blastMixer, cryofluidmixer, melter, separator, centrifuge, biomatterCompressor, pulverizer, solidifier, incinerator; @Override - public void load() { - smelter = new Smelter("smelter") {{ + public void load(){ + smelter = new Smelter("smelter"){{ health = 70; result = Items.carbide; craftTime = 45f; @@ -28,7 +28,7 @@ public class CraftingBlocks extends BlockList implements ContentList { consumes.item(Items.coal); }}; - arcsmelter = new PowerSmelter("arc-smelter") {{ + arcsmelter = new PowerSmelter("arc-smelter"){{ health = 90; craftEffect = BlockFx.smeltsmoke; result = Items.carbide; @@ -42,7 +42,7 @@ public class CraftingBlocks extends BlockList implements ContentList { consumes.power(0.1f); }}; - siliconsmelter = new PowerSmelter("silicon-smelter") {{ + siliconsmelter = new PowerSmelter("silicon-smelter"){{ health = 90; craftEffect = BlockFx.smeltsmoke; result = Items.silicon; @@ -55,7 +55,7 @@ public class CraftingBlocks extends BlockList implements ContentList { consumes.power(0.05f); }}; - plastaniumCompressor = new PlastaniumCompressor("plastanium-compressor") {{ + plastaniumCompressor = new PlastaniumCompressor("plastanium-compressor"){{ hasItems = true; liquidCapacity = 60f; craftTime = 80f; @@ -72,7 +72,7 @@ public class CraftingBlocks extends BlockList implements ContentList { consumes.item(Items.titanium, 2); }}; - phaseWeaver = new PhaseWeaver("phase-weaver") {{ + phaseWeaver = new PhaseWeaver("phase-weaver"){{ health = 90; craftEffect = BlockFx.smeltsmoke; result = Items.phasematter; @@ -83,7 +83,7 @@ public class CraftingBlocks extends BlockList implements ContentList { consumes.power(0.5f); }}; - alloysmelter = new PowerSmelter("alloy-smelter") {{ + alloysmelter = new PowerSmelter("alloy-smelter"){{ health = 90; craftEffect = BlockFx.smeltsmoke; result = Items.surgealloy; @@ -97,7 +97,7 @@ public class CraftingBlocks extends BlockList implements ContentList { consumes.items(new ItemStack[]{new ItemStack(Items.titanium, 2), new ItemStack(Items.lead, 4), new ItemStack(Items.silicon, 3), new ItemStack(Items.plastanium, 2)}); }}; - alloyfuser = new PowerSmelter("alloy-fuser") {{ + alloyfuser = new PowerSmelter("alloy-fuser"){{ health = 90; craftEffect = BlockFx.smeltsmoke; result = Items.surgealloy; @@ -111,7 +111,7 @@ public class CraftingBlocks extends BlockList implements ContentList { consumes.power(0.4f); }}; - cryofluidmixer = new LiquidMixer("cryofluidmixer") {{ + cryofluidmixer = new LiquidMixer("cryofluidmixer"){{ health = 200; outputLiquid = Liquids.cryofluid; liquidPerItem = 50f; @@ -124,7 +124,7 @@ public class CraftingBlocks extends BlockList implements ContentList { consumes.liquid(Liquids.water, 0.3f); }}; - blastMixer = new GenericCrafter("blast-mixer") {{ + blastMixer = new GenericCrafter("blast-mixer"){{ itemCapacity = 20; hasItems = true; hasPower = true; @@ -137,7 +137,7 @@ public class CraftingBlocks extends BlockList implements ContentList { consumes.power(0.04f); }}; - pyratiteMixer = new PowerSmelter("pyratite-mixer") {{ + pyratiteMixer = new PowerSmelter("pyratite-mixer"){{ flameColor = Color.CLEAR; itemCapacity = 20; hasItems = true; @@ -150,7 +150,7 @@ public class CraftingBlocks extends BlockList implements ContentList { consumes.items(new ItemStack[]{new ItemStack(Items.coal, 1), new ItemStack(Items.lead, 2), new ItemStack(Items.sand, 2)}); }}; - melter = new PowerCrafter("melter") {{ + melter = new PowerCrafter("melter"){{ health = 200; outputLiquid = Liquids.lava; outputLiquidAmount = 0.75f; @@ -162,7 +162,7 @@ public class CraftingBlocks extends BlockList implements ContentList { consumes.item(Items.stone, 2); }}; - separator = new Separator("separator") {{ + separator = new Separator("separator"){{ results = new Item[]{ null, null, null, null, null, null, null, null, null, null, Items.sand, Items.sand, Items.sand, Items.sand, Items.sand, Items.sand, Items.sand, Items.sand, Items.sand, Items.sand, @@ -180,7 +180,7 @@ public class CraftingBlocks extends BlockList implements ContentList { consumes.liquid(Liquids.water, 0.3f); }}; - centrifuge = new Separator("centrifuge") {{ + centrifuge = new Separator("centrifuge"){{ results = new Item[]{ null, null, null, null, null, null, null, null, null, null, null, null, null, Items.sand, Items.sand, Items.sand, Items.sand, Items.sand, Items.sand, Items.sand, Items.sand, Items.sand, Items.sand, Items.sand, Items.sand, @@ -207,7 +207,7 @@ public class CraftingBlocks extends BlockList implements ContentList { consumes.liquid(Liquids.water, 0.5f); }}; - biomatterCompressor = new Compressor("biomattercompressor") {{ + biomatterCompressor = new Compressor("biomattercompressor"){{ liquidCapacity = 60f; itemCapacity = 50; craftTime = 25f; @@ -221,7 +221,7 @@ public class CraftingBlocks extends BlockList implements ContentList { consumes.power(0.06f); }}; - pulverizer = new Pulverizer("pulverizer") {{ + pulverizer = new Pulverizer("pulverizer"){{ itemCapacity = 40; output = Items.sand; health = 80; @@ -234,7 +234,7 @@ public class CraftingBlocks extends BlockList implements ContentList { consumes.power(0.2f); }}; - solidifier = new GenericCrafter("solidifer") {{ + solidifier = new GenericCrafter("solidifer"){{ liquidCapacity = 21f; craftTime = 14; output = Items.stone; @@ -246,7 +246,7 @@ public class CraftingBlocks extends BlockList implements ContentList { consumes.liquid(Liquids.lava, 1f); }}; - incinerator = new Incinerator("incinerator") {{ + incinerator = new Incinerator("incinerator"){{ health = 90; }}; } diff --git a/core/src/io/anuke/mindustry/content/blocks/DebugBlocks.java b/core/src/io/anuke/mindustry/content/blocks/DebugBlocks.java index ff875423f9..b23a545823 100644 --- a/core/src/io/anuke/mindustry/content/blocks/DebugBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/DebugBlocks.java @@ -28,45 +28,52 @@ import java.io.IOException; public class DebugBlocks extends BlockList implements ContentList{ public static Block powerVoid, powerInfinite, itemSource, liquidSource, itemVoid; + @Remote(targets = Loc.both, called = Loc.both, in = In.blocks, forward = true) + public static void setLiquidSourceLiquid(Player player, Tile tile, Liquid liquid){ + LiquidSourceEntity entity = tile.entity(); + entity.source = liquid; + } + @Override - public void load() { - powerVoid = new PowerBlock("powervoid") { + public void load(){ + powerVoid = new PowerBlock("powervoid"){ { powerCapacity = Float.MAX_VALUE; } }; - powerInfinite = new PowerNode("powerinfinite") { + powerInfinite = new PowerNode("powerinfinite"){ { powerCapacity = 10000f; powerSpeed = 100f; } @Override - public void update(Tile tile) { + public void update(Tile tile){ super.update(tile); tile.entity.power.amount = powerCapacity; } }; - itemSource = new Sorter("itemsource") { + itemSource = new Sorter("itemsource"){ { hasItems = true; } + @Override - public void update(Tile tile) { + public void update(Tile tile){ SorterEntity entity = tile.entity(); entity.items.set(entity.sortItem, 1); tryDump(tile, entity.sortItem); } @Override - public boolean acceptItem(Item item, Tile tile, Tile source) { + public boolean acceptItem(Item item, Tile tile, Tile source){ return false; } }; - liquidSource = new Block("liquidsource") { + liquidSource = new Block("liquidsource"){ { update = true; solid = true; @@ -76,7 +83,7 @@ public class DebugBlocks extends BlockList implements ContentList{ } @Override - public void update(Tile tile) { + public void update(Tile tile){ LiquidSourceEntity entity = tile.entity(); tile.entity.liquids.add(entity.source, liquidCapacity); @@ -84,7 +91,7 @@ public class DebugBlocks extends BlockList implements ContentList{ } @Override - public void draw(Tile tile) { + public void draw(Tile tile){ super.draw(tile); LiquidSourceEntity entity = tile.entity(); @@ -95,7 +102,7 @@ public class DebugBlocks extends BlockList implements ContentList{ } @Override - public void buildTable(Tile tile, Table table) { + public void buildTable(Tile tile, Table table){ LiquidSourceEntity entity = tile.entity(); Array items = Liquid.all(); @@ -103,8 +110,8 @@ public class DebugBlocks extends BlockList implements ContentList{ ButtonGroup group = new ButtonGroup<>(); Table cont = new Table(); - for (int i = 0; i < items.size; i++) { - if (i == 0) continue; + for(int i = 0; i < items.size; i++){ + if(i == 0) continue; final int f = i; ImageButton button = cont.addImageButton("white", "toggle", 24, () -> { CallBlocks.setLiquidSourceLiquid(null, tile, items.get(f)); @@ -112,7 +119,7 @@ public class DebugBlocks extends BlockList implements ContentList{ button.getStyle().imageUpColor = items.get(i).color; button.setChecked(entity.source.id == f); - if (i % 4 == 3) { + if(i % 4 == 3){ cont.row(); } } @@ -121,43 +128,37 @@ public class DebugBlocks extends BlockList implements ContentList{ } @Override - public TileEntity getEntity() { + public TileEntity getEntity(){ return new LiquidSourceEntity(); } }; - itemVoid = new Block("itemvoid") { + itemVoid = new Block("itemvoid"){ { update = solid = true; } @Override - public void handleItem(Item item, Tile tile, Tile source) { + public void handleItem(Item item, Tile tile, Tile source){ } @Override - public boolean acceptItem(Item item, Tile tile, Tile source) { + public boolean acceptItem(Item item, Tile tile, Tile source){ return true; } }; } - @Remote(targets = Loc.both, called = Loc.both, in = In.blocks, forward = true) - public static void setLiquidSourceLiquid(Player player, Tile tile, Liquid liquid){ - LiquidSourceEntity entity = tile.entity(); - entity.source = liquid; - } - - class LiquidSourceEntity extends TileEntity { + class LiquidSourceEntity extends TileEntity{ public Liquid source = Liquids.water; @Override - public void write(DataOutputStream stream) throws IOException { + public void write(DataOutputStream stream) throws IOException{ stream.writeByte(source.id); } @Override - public void read(DataInputStream stream) throws IOException { + public void read(DataInputStream stream) throws IOException{ source = Liquid.getByID(stream.readByte()); } } diff --git a/core/src/io/anuke/mindustry/content/blocks/DefenseBlocks.java b/core/src/io/anuke/mindustry/content/blocks/DefenseBlocks.java index 761f05b7b8..ca40928d80 100644 --- a/core/src/io/anuke/mindustry/content/blocks/DefenseBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/DefenseBlocks.java @@ -8,65 +8,65 @@ import io.anuke.mindustry.world.blocks.defense.DeflectorWall; import io.anuke.mindustry.world.blocks.defense.Door; import io.anuke.mindustry.world.blocks.defense.PhaseWall; -public class DefenseBlocks extends BlockList implements ContentList { +public class DefenseBlocks extends BlockList implements ContentList{ public static Block tungstenWall, tungstenWallLarge, carbideWall, carbideWallLarge, thoriumWall, thoriumWallLarge, door, doorLarge, deflectorwall, deflectorwalllarge, - phasewall, phasewalllarge; + phasewall, phasewalllarge; @Override - public void load() { + public void load(){ int wallHealthMultiplier = 4; - tungstenWall = new Wall("tungsten-wall") {{ + tungstenWall = new Wall("tungsten-wall"){{ health = 80 * wallHealthMultiplier; }}; - tungstenWallLarge = new Wall("tungsten-wall-large") {{ + tungstenWallLarge = new Wall("tungsten-wall-large"){{ health = 80 * 4 * wallHealthMultiplier; size = 2; }}; - carbideWall = new Wall("carbide-wall") {{ + carbideWall = new Wall("carbide-wall"){{ health = 110 * wallHealthMultiplier; }}; - carbideWallLarge = new Wall("carbide-wall-large") {{ - health = 110 * wallHealthMultiplier*4; + carbideWallLarge = new Wall("carbide-wall-large"){{ + health = 110 * wallHealthMultiplier * 4; size = 2; }}; - thoriumWall = new Wall("thorium-wall") {{ + thoriumWall = new Wall("thorium-wall"){{ health = 200 * wallHealthMultiplier; }}; - thoriumWallLarge = new Wall("thorium-wall-large") {{ - health = 200 * wallHealthMultiplier*4; + thoriumWallLarge = new Wall("thorium-wall-large"){{ + health = 200 * wallHealthMultiplier * 4; size = 2; }}; - deflectorwall = new DeflectorWall("deflector-wall") {{ + deflectorwall = new DeflectorWall("deflector-wall"){{ health = 150 * wallHealthMultiplier; }}; - deflectorwalllarge = new DeflectorWall("deflector-wall-large") {{ + deflectorwalllarge = new DeflectorWall("deflector-wall-large"){{ health = 150 * 4 * wallHealthMultiplier; size = 2; }}; - phasewall = new PhaseWall("phase-wall") {{ + phasewall = new PhaseWall("phase-wall"){{ health = 150 * wallHealthMultiplier; }}; - phasewalllarge = new PhaseWall("phase-wall-large") {{ + phasewalllarge = new PhaseWall("phase-wall-large"){{ health = 150 * 4 * wallHealthMultiplier; size = 2; regenSpeed = 0.5f; }}; - door = new Door("door") {{ + door = new Door("door"){{ health = 100 * wallHealthMultiplier; }}; - doorLarge = new Door("door-large") {{ + doorLarge = new Door("door-large"){{ openfx = BlockFx.dooropenlarge; closefx = BlockFx.doorcloselarge; health = 100 * 4 * wallHealthMultiplier; diff --git a/core/src/io/anuke/mindustry/content/blocks/DistributionBlocks.java b/core/src/io/anuke/mindustry/content/blocks/DistributionBlocks.java index cda352e0f6..f045133968 100644 --- a/core/src/io/anuke/mindustry/content/blocks/DistributionBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/DistributionBlocks.java @@ -5,50 +5,50 @@ import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.blocks.distribution.*; public class DistributionBlocks extends BlockList implements ContentList{ - public static Block conveyor, titaniumconveyor, distributor, junction, - bridgeConveyor, phaseConveyor, sorter, splitter, overflowGate, massDriver; + public static Block conveyor, titaniumconveyor, distributor, junction, + bridgeConveyor, phaseConveyor, sorter, splitter, overflowGate, massDriver; - @Override - public void load() { + @Override + public void load(){ - conveyor = new Conveyor("conveyor") {{ - health = 45; - speed = 0.03f; - }}; + conveyor = new Conveyor("conveyor"){{ + health = 45; + speed = 0.03f; + }}; - titaniumconveyor = new Conveyor("titanium-conveyor") {{ - health = 65; - speed = 0.07f; - }}; + titaniumconveyor = new Conveyor("titanium-conveyor"){{ + health = 65; + speed = 0.07f; + }}; - junction = new Junction("junction") {{ - speed = 26; - capacity = 32; - }}; + junction = new Junction("junction"){{ + speed = 26; + capacity = 32; + }}; - bridgeConveyor = new BufferedItemBridge("bridge-conveyor") {{ - range = 3; - hasPower = false; - }}; + bridgeConveyor = new BufferedItemBridge("bridge-conveyor"){{ + range = 3; + hasPower = false; + }}; - phaseConveyor = new ItemBridge("phase-conveyor") {{ - range = 7; - }}; + phaseConveyor = new ItemBridge("phase-conveyor"){{ + range = 7; + }}; - sorter = new Sorter("sorter"); + sorter = new Sorter("sorter"); - splitter = new Splitter("splitter"); + splitter = new Splitter("splitter"); - distributor = new Splitter("distributor") {{ - size = 2; - }}; + distributor = new Splitter("distributor"){{ + size = 2; + }}; - overflowGate = new OverflowGate("overflow-gate"); + overflowGate = new OverflowGate("overflow-gate"); - massDriver = new MassDriver("mass-driver"){{ - size = 3; - itemCapacity = 80; - range = 300f; - }}; - } + massDriver = new MassDriver("mass-driver"){{ + size = 3; + itemCapacity = 80; + range = 300f; + }}; + } } diff --git a/core/src/io/anuke/mindustry/content/blocks/LiquidBlocks.java b/core/src/io/anuke/mindustry/content/blocks/LiquidBlocks.java index 621fca803a..30205142f4 100644 --- a/core/src/io/anuke/mindustry/content/blocks/LiquidBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/LiquidBlocks.java @@ -9,15 +9,15 @@ public class LiquidBlocks extends BlockList implements ContentList{ public static Block mechanicalPump, rotaryPump, thermalPump, conduit, pulseConduit, liquidRouter, liquidtank, liquidJunction, bridgeConduit, phaseConduit; @Override - public void load() { + public void load(){ - mechanicalPump = new Pump("mechanical-pump") {{ + mechanicalPump = new Pump("mechanical-pump"){{ shadow = "shadow-round-1"; pumpAmount = 0.1f; tier = 0; }}; - rotaryPump = new Pump("rotary-pump") {{ + rotaryPump = new Pump("rotary-pump"){{ shadow = "shadow-rounded-2"; pumpAmount = 0.25f; consumes.power(0.015f); @@ -27,7 +27,7 @@ public class LiquidBlocks extends BlockList implements ContentList{ tier = 1; }}; - thermalPump = new Pump("thermal-pump") {{ + thermalPump = new Pump("thermal-pump"){{ pumpAmount = 0.3f; consumes.power(0.05f); liquidCapacity = 40f; @@ -35,21 +35,21 @@ public class LiquidBlocks extends BlockList implements ContentList{ tier = 2; }}; - conduit = new Conduit("conduit") {{ + conduit = new Conduit("conduit"){{ health = 45; }}; - pulseConduit = new Conduit("pulse-conduit") {{ + pulseConduit = new Conduit("pulse-conduit"){{ liquidCapacity = 16f; liquidFlowFactor = 4.9f; health = 90; }}; - liquidRouter = new LiquidRouter("liquid-router") {{ + liquidRouter = new LiquidRouter("liquid-router"){{ liquidCapacity = 40f; }}; - liquidtank = new LiquidRouter("liquid-tank") {{ + liquidtank = new LiquidRouter("liquid-tank"){{ size = 3; liquidCapacity = 1500f; health = 500; @@ -57,12 +57,12 @@ public class LiquidBlocks extends BlockList implements ContentList{ liquidJunction = new LiquidJunction("liquid-junction"); - bridgeConduit = new LiquidExtendingBridge("bridge-conduit") {{ + bridgeConduit = new LiquidExtendingBridge("bridge-conduit"){{ range = 3; hasPower = false; }}; - phaseConduit = new LiquidBridge("phase-conduit") {{ + phaseConduit = new LiquidBridge("phase-conduit"){{ range = 7; }}; } diff --git a/core/src/io/anuke/mindustry/content/blocks/OreBlocks.java b/core/src/io/anuke/mindustry/content/blocks/OreBlocks.java index cd1764586b..4cb86032f8 100644 --- a/core/src/io/anuke/mindustry/content/blocks/OreBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/OreBlocks.java @@ -7,11 +7,18 @@ import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.blocks.Floor; import io.anuke.mindustry.world.blocks.OreBlock; -public class OreBlocks extends BlockList { +public class OreBlocks extends BlockList{ private static final ObjectMap> oreBlockMap = new ObjectMap<>(); + public static Block get(Block floor, Item item){ + if(!oreBlockMap.containsKey(item)) throw new IllegalArgumentException("Item '" + item + "' is not an ore!"); + if(!oreBlockMap.get(item).containsKey(floor)) + throw new IllegalArgumentException("Block '" + floor.name + "' does not support ores!"); + return oreBlockMap.get(item).get(floor); + } + @Override - public void load() { + public void load(){ Item[] ores = {Items.tungsten, Items.lead, Items.coal, Items.titanium, Items.thorium}; for(Item item : ores){ @@ -25,10 +32,4 @@ public class OreBlocks extends BlockList { } } } - - public static Block get(Block floor, Item item){ - if(!oreBlockMap.containsKey(item)) throw new IllegalArgumentException("Item '" + item + "' is not an ore!"); - if(!oreBlockMap.get(item).containsKey(floor)) throw new IllegalArgumentException("Block '" + floor.name + "' does not support ores!"); - return oreBlockMap.get(item).get(floor); - } } diff --git a/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java b/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java index 223a88efdb..df8ead1a55 100644 --- a/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java @@ -7,19 +7,19 @@ import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.blocks.distribution.WarpGate; import io.anuke.mindustry.world.blocks.power.*; -public class PowerBlocks extends BlockList implements ContentList { +public class PowerBlocks extends BlockList implements ContentList{ public static Block combustionGenerator, thermalGenerator, turbineGenerator, rtgGenerator, solarPanel, largeSolarPanel, nuclearReactor, fusionReactor, battery, batteryLarge, powerNode, powerNodeLarge, warpGate; @Override - public void load() { - combustionGenerator = new BurnerGenerator("combustion-generator") {{ + public void load(){ + combustionGenerator = new BurnerGenerator("combustion-generator"){{ powerOutput = 0.09f; powerCapacity = 40f; itemDuration = 40f; }}; - thermalGenerator = new LiquidHeatGenerator("thermal-generator") {{ + thermalGenerator = new LiquidHeatGenerator("thermal-generator"){{ maxLiquidGenerate = 0.5f; powerPerLiquid = 0.08f; powerCapacity = 40f; @@ -28,7 +28,7 @@ public class PowerBlocks extends BlockList implements ContentList { size = 2; }}; - turbineGenerator = new TurbineGenerator("turbine-generator") {{ + turbineGenerator = new TurbineGenerator("turbine-generator"){{ powerOutput = 0.28f; powerCapacity = 40f; itemDuration = 30f; @@ -37,46 +37,46 @@ public class PowerBlocks extends BlockList implements ContentList { size = 2; }}; - rtgGenerator = new DecayGenerator("rtg-generator") {{ + rtgGenerator = new DecayGenerator("rtg-generator"){{ powerCapacity = 40f; powerOutput = 0.02f; itemDuration = 500f; }}; - solarPanel = new SolarGenerator("solar-panel") {{ + solarPanel = new SolarGenerator("solar-panel"){{ generation = 0.0045f; }}; - largeSolarPanel = new SolarGenerator("solar-panel-large") {{ + largeSolarPanel = new SolarGenerator("solar-panel-large"){{ size = 3; generation = 0.055f; }}; - nuclearReactor = new NuclearReactor("nuclear-reactor") {{ + nuclearReactor = new NuclearReactor("nuclear-reactor"){{ size = 3; health = 700; powerMultiplier = 0.8f; }}; - fusionReactor = new FusionReactor("fusion-reactor") {{ + fusionReactor = new FusionReactor("fusion-reactor"){{ size = 4; health = 600; }}; - battery = new PowerDistributor("battery") {{ + battery = new PowerDistributor("battery"){{ powerCapacity = 320f; }}; - batteryLarge = new PowerDistributor("battery-large") {{ + batteryLarge = new PowerDistributor("battery-large"){{ size = 3; powerCapacity = 2000f; }}; - powerNode = new PowerNode("power-node") {{ + powerNode = new PowerNode("power-node"){{ shadow = "shadow-round-1"; }}; - powerNodeLarge = new PowerNode("power-node-large") {{ + powerNodeLarge = new PowerNode("power-node-large"){{ size = 2; powerSpeed = 1f; maxNodes = 5; diff --git a/core/src/io/anuke/mindustry/content/blocks/ProductionBlocks.java b/core/src/io/anuke/mindustry/content/blocks/ProductionBlocks.java index 0e3ae62edd..c07dc66303 100644 --- a/core/src/io/anuke/mindustry/content/blocks/ProductionBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/ProductionBlocks.java @@ -11,22 +11,22 @@ import io.anuke.mindustry.world.blocks.production.Drill; import io.anuke.mindustry.world.blocks.production.Fracker; import io.anuke.mindustry.world.blocks.production.SolidPump; -public class ProductionBlocks extends BlockList implements ContentList { +public class ProductionBlocks extends BlockList implements ContentList{ public static Block tungstenDrill, carbideDrill, laserdrill, blastdrill, plasmadrill, waterextractor, oilextractor, cultivator; @Override - public void load() { - tungstenDrill = new Drill("tungsten-drill") {{ + public void load(){ + tungstenDrill = new Drill("tungsten-drill"){{ tier = 2; drillTime = 340; }}; - carbideDrill = new Drill("carbide-drill") {{ + carbideDrill = new Drill("carbide-drill"){{ tier = 3; drillTime = 280; }}; - laserdrill = new Drill("laser-drill") {{ + laserdrill = new Drill("laser-drill"){{ drillTime = 180; size = 2; hasPower = true; @@ -37,7 +37,7 @@ public class ProductionBlocks extends BlockList implements ContentList { consumes.power(0.2f); }}; - blastdrill = new Drill("blast-drill") {{ + blastdrill = new Drill("blast-drill"){{ drillTime = 120; size = 3; drawRim = true; @@ -52,7 +52,7 @@ public class ProductionBlocks extends BlockList implements ContentList { consumes.power(0.5f); }}; - plasmadrill = new Drill("plasma-drill") {{ + plasmadrill = new Drill("plasma-drill"){{ heatColor = Color.valueOf("ff461b"); drillTime = 90; size = 4; @@ -69,7 +69,7 @@ public class ProductionBlocks extends BlockList implements ContentList { consumes.power(0.7f); }}; - waterextractor = new SolidPump("water-extractor") {{ + waterextractor = new SolidPump("water-extractor"){{ result = Liquids.water; pumpAmount = 0.1f; size = 2; @@ -79,7 +79,7 @@ public class ProductionBlocks extends BlockList implements ContentList { consumes.power(0.2f); }}; - oilextractor = new Fracker("oil-extractor") {{ + oilextractor = new Fracker("oil-extractor"){{ result = Liquids.oil; updateEffect = BlockFx.pulverize; liquidCapacity = 50f; @@ -93,7 +93,7 @@ public class ProductionBlocks extends BlockList implements ContentList { consumes.liquid(Liquids.water, 0.3f); }}; - cultivator = new Cultivator("cultivator") {{ + cultivator = new Cultivator("cultivator"){{ result = Items.biomatter; drillTime = 260; size = 2; diff --git a/core/src/io/anuke/mindustry/content/blocks/StorageBlocks.java b/core/src/io/anuke/mindustry/content/blocks/StorageBlocks.java index 0d736832cb..d3946f8339 100644 --- a/core/src/io/anuke/mindustry/content/blocks/StorageBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/StorageBlocks.java @@ -7,26 +7,26 @@ import io.anuke.mindustry.world.blocks.storage.SortedUnloader; import io.anuke.mindustry.world.blocks.storage.Unloader; import io.anuke.mindustry.world.blocks.storage.Vault; -public class StorageBlocks extends BlockList implements ContentList { +public class StorageBlocks extends BlockList implements ContentList{ public static Block core, vault, unloader, sortedunloader; @Override - public void load() { - core = new CoreBlock("core") {{ + public void load(){ + core = new CoreBlock("core"){{ health = 800; }}; - vault = new Vault("vault") {{ + vault = new Vault("vault"){{ size = 3; health = 600; itemCapacity = 2000; }}; - unloader = new Unloader("unloader") {{ + unloader = new Unloader("unloader"){{ speed = 5; }}; - sortedunloader = new SortedUnloader("sortedunloader") {{ + sortedunloader = new SortedUnloader("sortedunloader"){{ speed = 5; }}; } diff --git a/core/src/io/anuke/mindustry/content/blocks/TurretBlocks.java b/core/src/io/anuke/mindustry/content/blocks/TurretBlocks.java index c993ec8fbc..e408d82719 100644 --- a/core/src/io/anuke/mindustry/content/blocks/TurretBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/TurretBlocks.java @@ -12,22 +12,23 @@ import io.anuke.ucore.util.Angles; import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Strings; -public class TurretBlocks extends BlockList implements ContentList { - public static Block duo, /*scatter,*/ scorch, hail, wave, lancer, arc, swarmer, salvo, fuse, ripple, cyclone, spectre, meltdown; +public class TurretBlocks extends BlockList implements ContentList{ + public static Block duo, /*scatter,*/ + scorch, hail, wave, lancer, arc, swarmer, salvo, fuse, ripple, cyclone, spectre, meltdown; - @Override - public void load() { - duo = new DoubleTurret("duo") {{ - ammoTypes = new AmmoType[]{AmmoTypes.bulletTungsten, AmmoTypes.bulletLead, AmmoTypes.bulletCarbide, AmmoTypes.bulletPyratite, AmmoTypes.bulletSilicon}; - reload = 25f; - restitution = 0.03f; - range = 90f; - shootCone = 15f; - ammoUseEffect = ShootFx.shellEjectSmall; - health = 80; - inaccuracy = 2f; - rotatespeed = 10f; - }}; + @Override + public void load(){ + duo = new DoubleTurret("duo"){{ + ammoTypes = new AmmoType[]{AmmoTypes.bulletTungsten, AmmoTypes.bulletLead, AmmoTypes.bulletCarbide, AmmoTypes.bulletPyratite, AmmoTypes.bulletSilicon}; + reload = 25f; + restitution = 0.03f; + range = 90f; + shootCone = 15f; + ammoUseEffect = ShootFx.shellEjectSmall; + health = 80; + inaccuracy = 2f; + rotatespeed = 10f; + }}; /* scatter = new BurstTurret("scatter") {{ ammoTypes = new AmmoType[]{AmmoTypes.flakLead, AmmoTypes.flakExplosive, AmmoTypes.flakPlastic}; @@ -41,165 +42,165 @@ public class TurretBlocks extends BlockList implements ContentList { ammoUseEffect = ShootFx.shellEjectSmall; }};*/ - hail = new ArtilleryTurret("hail") {{ - ammoTypes = new AmmoType[]{AmmoTypes.artilleryCarbide, AmmoTypes.artilleryHoming, AmmoTypes.artilleryIncindiary}; - reload = 100f; - recoil = 2f; - range = 200f; - inaccuracy = 5f; - health = 120; - }}; + hail = new ArtilleryTurret("hail"){{ + ammoTypes = new AmmoType[]{AmmoTypes.artilleryCarbide, AmmoTypes.artilleryHoming, AmmoTypes.artilleryIncindiary}; + reload = 100f; + recoil = 2f; + range = 200f; + inaccuracy = 5f; + health = 120; + }}; - scorch = new LiquidTurret("scorch") {{ + scorch = new LiquidTurret("scorch"){{ ammoTypes = new AmmoType[]{AmmoTypes.basicFlame}; recoil = 0f; reload = 4f; shootCone = 50f; ammoUseEffect = ShootFx.shellEjectSmall; - health = 160; + health = 160; drawer = (tile, entity) -> Draw.rect(entity.target != null ? name + "-shoot" : name, tile.drawx() + tr2.x, tile.drawy() + tr2.y, entity.rotation - 90); }}; - wave = new LiquidTurret("wave") {{ - ammoTypes = new AmmoType[]{AmmoTypes.water, AmmoTypes.lava, AmmoTypes.cryofluid, AmmoTypes.oil}; - size = 2; - recoil = 0f; - reload = 4f; - inaccuracy = 5f; - shootCone = 50f; - shootEffect = ShootFx.shootLiquid; - range = 70f; - health = 360; + wave = new LiquidTurret("wave"){{ + ammoTypes = new AmmoType[]{AmmoTypes.water, AmmoTypes.lava, AmmoTypes.cryofluid, AmmoTypes.oil}; + size = 2; + recoil = 0f; + reload = 4f; + inaccuracy = 5f; + shootCone = 50f; + shootEffect = ShootFx.shootLiquid; + range = 70f; + health = 360; - drawer = (tile, entity) -> { - Draw.rect(region, tile.drawx() + tr2.x, tile.drawy() + tr2.y, entity.rotation - 90); + drawer = (tile, entity) -> { + Draw.rect(region, tile.drawx() + tr2.x, tile.drawy() + tr2.y, entity.rotation - 90); - Draw.color(entity.liquids.current().color); - Draw.alpha(entity.liquids.total() / liquidCapacity); - Draw.rect(name + "-liquid", tile.drawx() + tr2.x, tile.drawy() + tr2.y, entity.rotation - 90); - Draw.color(); - }; - }}; + Draw.color(entity.liquids.current().color); + Draw.alpha(entity.liquids.total() / liquidCapacity); + Draw.rect(name + "-liquid", tile.drawx() + tr2.x, tile.drawy() + tr2.y, entity.rotation - 90); + Draw.color(); + }; + }}; - lancer = new LaserTurret("lancer") {{ - range = 90f; - chargeTime = 60f; - chargeMaxDelay = 30f; - chargeEffects = 7; - shootType = AmmoTypes.lancerLaser; - recoil = 2f; - reload = 100f; - cooldown = 0.03f; - powerUsed = 20f; - powerCapacity = 60f; - shootShake = 2f; - shootEffect = ShootFx.lancerLaserShoot; - smokeEffect = ShootFx.lancerLaserShootSmoke; - chargeEffect = ShootFx.lancerLaserCharge; - chargeBeginEffect = ShootFx.lancerLaserChargeBegin; - heatColor = Color.RED; - size = 2; - health = 320; - }}; + lancer = new LaserTurret("lancer"){{ + range = 90f; + chargeTime = 60f; + chargeMaxDelay = 30f; + chargeEffects = 7; + shootType = AmmoTypes.lancerLaser; + recoil = 2f; + reload = 100f; + cooldown = 0.03f; + powerUsed = 20f; + powerCapacity = 60f; + shootShake = 2f; + shootEffect = ShootFx.lancerLaserShoot; + smokeEffect = ShootFx.lancerLaserShootSmoke; + chargeEffect = ShootFx.lancerLaserCharge; + chargeBeginEffect = ShootFx.lancerLaserChargeBegin; + heatColor = Color.RED; + size = 2; + health = 320; + }}; - arc = new LaserTurret("arc") {{ - shootType = AmmoTypes.lightning; - reload = 100f; - chargeTime = 70f; - shootShake = 1f; - chargeMaxDelay = 30f; - chargeEffects = 7; - shootEffect = ShootFx.lightningShoot; - chargeEffect = ShootFx.lightningCharge; - chargeBeginEffect = ShootFx.lancerLaserChargeBegin; - heatColor = Color.RED; - recoil = 3f; - size = 2; - }}; + arc = new LaserTurret("arc"){{ + shootType = AmmoTypes.lightning; + reload = 100f; + chargeTime = 70f; + shootShake = 1f; + chargeMaxDelay = 30f; + chargeEffects = 7; + shootEffect = ShootFx.lightningShoot; + chargeEffect = ShootFx.lightningCharge; + chargeBeginEffect = ShootFx.lancerLaserChargeBegin; + heatColor = Color.RED; + recoil = 3f; + size = 2; + }}; - swarmer = new BurstTurret("swarmer") {{ - ammoTypes = new AmmoType[]{AmmoTypes.missileExplosive, AmmoTypes.missileIncindiary/*, AmmoTypes.missileSurge*/}; - reload = 60f; - shots = 4; - burstSpacing = 5; - inaccuracy = 10f; - range = 140f; - xRand = 6f; - size = 2; - health = 380; - }}; + swarmer = new BurstTurret("swarmer"){{ + ammoTypes = new AmmoType[]{AmmoTypes.missileExplosive, AmmoTypes.missileIncindiary/*, AmmoTypes.missileSurge*/}; + reload = 60f; + shots = 4; + burstSpacing = 5; + inaccuracy = 10f; + range = 140f; + xRand = 6f; + size = 2; + health = 380; + }}; - salvo = new BurstTurret("salvo") {{ - size = 2; - range = 120f; - ammoTypes = new AmmoType[]{AmmoTypes.bulletTungsten, AmmoTypes.bulletCarbide, AmmoTypes.bulletPyratite, AmmoTypes.bulletThorium, AmmoTypes.bulletSilicon}; - reload = 40f; - restitution = 0.03f; - ammoEjectBack = 3f; - cooldown = 0.03f; - recoil = 3f; - shootShake = 2f; - burstSpacing = 4; - shots = 3; - ammoUseEffect = ShootFx.shellEjectBig; + salvo = new BurstTurret("salvo"){{ + size = 2; + range = 120f; + ammoTypes = new AmmoType[]{AmmoTypes.bulletTungsten, AmmoTypes.bulletCarbide, AmmoTypes.bulletPyratite, AmmoTypes.bulletThorium, AmmoTypes.bulletSilicon}; + reload = 40f; + restitution = 0.03f; + ammoEjectBack = 3f; + cooldown = 0.03f; + recoil = 3f; + shootShake = 2f; + burstSpacing = 4; + shots = 3; + ammoUseEffect = ShootFx.shellEjectBig; - drawer = (tile, entity) -> { - Draw.rect(region, tile.drawx() + tr2.x, tile.drawy() + tr2.y, entity.rotation - 90); - float offsetx = (int) (Mathf.abscurve(Mathf.curve(entity.reload / reload, 0.3f, 0.2f)) * 3f); - float offsety = -(int) (Mathf.abscurve(Mathf.curve(entity.reload / reload, 0.3f, 0.2f)) * 2f); + drawer = (tile, entity) -> { + Draw.rect(region, tile.drawx() + tr2.x, tile.drawy() + tr2.y, entity.rotation - 90); + float offsetx = (int) (Mathf.abscurve(Mathf.curve(entity.reload / reload, 0.3f, 0.2f)) * 3f); + float offsety = -(int) (Mathf.abscurve(Mathf.curve(entity.reload / reload, 0.3f, 0.2f)) * 2f); - for (int i : Mathf.signs) { - float rot = entity.rotation + 90 * i; - Draw.rect(name + "-panel-" + Strings.dir(i), - tile.drawx() + tr2.x + Angles.trnsx(rot, offsetx, offsety), - tile.drawy() + tr2.y + Angles.trnsy(rot, -offsetx, offsety), entity.rotation - 90); - } - }; + for(int i : Mathf.signs){ + float rot = entity.rotation + 90 * i; + Draw.rect(name + "-panel-" + Strings.dir(i), + tile.drawx() + tr2.x + Angles.trnsx(rot, offsetx, offsety), + tile.drawy() + tr2.y + Angles.trnsy(rot, -offsetx, offsety), entity.rotation - 90); + } + }; - health = 360; - }}; + health = 360; + }}; - ripple = new ArtilleryTurret("ripple") {{ - ammoTypes = new AmmoType[]{AmmoTypes.artilleryCarbide, AmmoTypes.artilleryHoming, AmmoTypes.artilleryIncindiary, AmmoTypes.artilleryExplosive, AmmoTypes.artilleryPlastic}; - size = 3; - shots = 4; - inaccuracy = 12f; - reload = 60f; - ammoEjectBack = 5f; + ripple = new ArtilleryTurret("ripple"){{ + ammoTypes = new AmmoType[]{AmmoTypes.artilleryCarbide, AmmoTypes.artilleryHoming, AmmoTypes.artilleryIncindiary, AmmoTypes.artilleryExplosive, AmmoTypes.artilleryPlastic}; + size = 3; + shots = 4; + inaccuracy = 12f; + reload = 60f; + ammoEjectBack = 5f; ammoUseEffect = ShootFx.shellEjectBig; cooldown = 0.03f; - velocityInaccuracy = 0.2f; + velocityInaccuracy = 0.2f; restitution = 0.02f; recoil = 6f; shootShake = 2f; range = 300f; - health = 550; - }}; + health = 550; + }}; - cyclone = new ItemTurret("cyclone") {{ - ammoTypes = new AmmoType[]{AmmoTypes.flakLead, AmmoTypes.flakExplosive, AmmoTypes.flakPlastic, AmmoTypes.flakSurge}; - size = 3; - }}; + cyclone = new ItemTurret("cyclone"){{ + ammoTypes = new AmmoType[]{AmmoTypes.flakLead, AmmoTypes.flakExplosive, AmmoTypes.flakPlastic, AmmoTypes.flakSurge}; + size = 3; + }}; - fuse = new ItemTurret("fuse") {{ - //TODO make it use power - ammoTypes = new AmmoType[]{AmmoTypes.fuseShotgun}; - size = 3; - }}; + fuse = new ItemTurret("fuse"){{ + //TODO make it use power + ammoTypes = new AmmoType[]{AmmoTypes.fuseShotgun}; + size = 3; + }}; - spectre = new ItemTurret("spectre") {{ - ammoTypes = new AmmoType[]{AmmoTypes.bulletTungsten, AmmoTypes.bulletLead, AmmoTypes.bulletCarbide, AmmoTypes.bulletPyratite, AmmoTypes.bulletThorium, AmmoTypes.bulletSilicon}; - reload = 25f; - restitution = 0.03f; - ammoUseEffect = ShootFx.shellEjectSmall; - size = 4; - }}; + spectre = new ItemTurret("spectre"){{ + ammoTypes = new AmmoType[]{AmmoTypes.bulletTungsten, AmmoTypes.bulletLead, AmmoTypes.bulletCarbide, AmmoTypes.bulletPyratite, AmmoTypes.bulletThorium, AmmoTypes.bulletSilicon}; + reload = 25f; + restitution = 0.03f; + ammoUseEffect = ShootFx.shellEjectSmall; + size = 4; + }}; - meltdown = new PowerTurret("meltdown") {{ - shootType = AmmoTypes.meltdownLaser; - size = 4; - }}; - } + meltdown = new PowerTurret("meltdown"){{ + shootType = AmmoTypes.meltdownLaser; + size = 4; + }}; + } } diff --git a/core/src/io/anuke/mindustry/content/blocks/UnitBlocks.java b/core/src/io/anuke/mindustry/content/blocks/UnitBlocks.java index 5abf5ceb51..dc98341364 100644 --- a/core/src/io/anuke/mindustry/content/blocks/UnitBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/UnitBlocks.java @@ -7,12 +7,12 @@ import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.blocks.units.*; -public class UnitBlocks extends BlockList implements ContentList { +public class UnitBlocks extends BlockList implements ContentList{ public static Block resupplyPoint, repairPoint, droneFactory, fabricatorFactory, dropPoint, reconstructor, overdriveProjector, shieldProjector; @Override - public void load() { - droneFactory = new UnitFactory("drone-factory") {{ + public void load(){ + droneFactory = new UnitFactory("drone-factory"){{ type = UnitTypes.drone; produceTime = 800; size = 2; @@ -20,7 +20,7 @@ public class UnitBlocks extends BlockList implements ContentList { consumes.items(new ItemStack[]{new ItemStack(Items.silicon, 30), new ItemStack(Items.lead, 30)}); }}; - fabricatorFactory = new UnitFactory("fabricator-factory") {{ + fabricatorFactory = new UnitFactory("fabricator-factory"){{ type = UnitTypes.fabricator; produceTime = 1600; size = 2; @@ -28,30 +28,30 @@ public class UnitBlocks extends BlockList implements ContentList { consumes.items(new ItemStack[]{new ItemStack(Items.silicon, 70), new ItemStack(Items.lead, 80), new ItemStack(Items.titanium, 80)}); }}; - resupplyPoint = new ResupplyPoint("resupply-point") {{ + resupplyPoint = new ResupplyPoint("resupply-point"){{ shadow = "shadow-round-1"; itemCapacity = 30; }}; - dropPoint = new DropPoint("drop-point") {{ + dropPoint = new DropPoint("drop-point"){{ shadow = "shadow-round-1"; itemCapacity = 40; }}; - repairPoint = new RepairPoint("repair-point") {{ + repairPoint = new RepairPoint("repair-point"){{ shadow = "shadow-round-1"; repairSpeed = 0.1f; }}; - reconstructor = new Reconstructor("reconstructor") {{ + reconstructor = new Reconstructor("reconstructor"){{ size = 2; }}; - overdriveProjector = new OverdriveProjector("overdrive-projector") {{ + overdriveProjector = new OverdriveProjector("overdrive-projector"){{ size = 2; }}; - shieldProjector = new ShieldProjector("shieldprojector") {{ + shieldProjector = new ShieldProjector("shieldprojector"){{ size = 2; }}; } diff --git a/core/src/io/anuke/mindustry/content/blocks/UpgradeBlocks.java b/core/src/io/anuke/mindustry/content/blocks/UpgradeBlocks.java index 7382e726fe..c66cfba208 100644 --- a/core/src/io/anuke/mindustry/content/blocks/UpgradeBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/UpgradeBlocks.java @@ -4,11 +4,11 @@ import io.anuke.mindustry.content.Mechs; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.blocks.units.MechFactory; -public class UpgradeBlocks extends BlockList { +public class UpgradeBlocks extends BlockList{ public static Block deltaFactory, tauFactory, omegaFactory, dartFactory, javelinFactory, tridentFactory, halberdFactory; @Override - public void load() { + public void load(){ deltaFactory = new MechFactory("delta-mech-factory"){{ mech = Mechs.delta; size = 2; diff --git a/core/src/io/anuke/mindustry/content/bullets/ArtilleryBullets.java b/core/src/io/anuke/mindustry/content/bullets/ArtilleryBullets.java index 0747fecae7..5898a70070 100644 --- a/core/src/io/anuke/mindustry/content/bullets/ArtilleryBullets.java +++ b/core/src/io/anuke/mindustry/content/bullets/ArtilleryBullets.java @@ -11,9 +11,9 @@ public class ArtilleryBullets extends BulletList implements ContentList{ public static BulletType carbide, plastic, plasticFrag, homing, incindiary, explosive, surge; @Override - public void load() { + public void load(){ - carbide = new ArtilleryBulletType(3f, 0, "shell") { + carbide = new ArtilleryBulletType(3f, 0, "shell"){ { hiteffect = BulletFx.flakExplosion; knockback = 0.8f; @@ -25,7 +25,7 @@ public class ArtilleryBullets extends BulletList implements ContentList{ } }; - plasticFrag = new BasicBulletType(2.5f, 6, "bullet") { + plasticFrag = new BasicBulletType(2.5f, 6, "bullet"){ { bulletWidth = 10f; bulletHeight = 12f; @@ -36,7 +36,7 @@ public class ArtilleryBullets extends BulletList implements ContentList{ } }; - plastic = new ArtilleryBulletType(3.3f, 0, "shell") { + plastic = new ArtilleryBulletType(3.3f, 0, "shell"){ { hiteffect = BulletFx.plasticExplosion; knockback = 1f; @@ -52,7 +52,7 @@ public class ArtilleryBullets extends BulletList implements ContentList{ } }; - homing = new ArtilleryBulletType(3f, 0, "shell") { + homing = new ArtilleryBulletType(3f, 0, "shell"){ { hiteffect = BulletFx.flakExplosion; knockback = 0.8f; @@ -66,7 +66,7 @@ public class ArtilleryBullets extends BulletList implements ContentList{ } }; - incindiary = new ArtilleryBulletType(3f, 0, "shell") { + incindiary = new ArtilleryBulletType(3f, 0, "shell"){ { hiteffect = BulletFx.blastExplosion; knockback = 0.8f; @@ -83,7 +83,7 @@ public class ArtilleryBullets extends BulletList implements ContentList{ } }; - explosive = new ArtilleryBulletType(2f, 0, "shell") { + explosive = new ArtilleryBulletType(2f, 0, "shell"){ { hiteffect = BulletFx.blastExplosion; knockback = 0.8f; @@ -97,7 +97,7 @@ public class ArtilleryBullets extends BulletList implements ContentList{ } }; - surge = new ArtilleryBulletType(3f, 0, "shell") { + surge = new ArtilleryBulletType(3f, 0, "shell"){ { //TODO } diff --git a/core/src/io/anuke/mindustry/content/bullets/BulletList.java b/core/src/io/anuke/mindustry/content/bullets/BulletList.java index dac973f2e0..ba0e465799 100644 --- a/core/src/io/anuke/mindustry/content/bullets/BulletList.java +++ b/core/src/io/anuke/mindustry/content/bullets/BulletList.java @@ -5,10 +5,10 @@ import io.anuke.mindustry.entities.bullet.BulletType; import io.anuke.mindustry.game.Content; import io.anuke.mindustry.type.ContentList; -public abstract class BulletList implements ContentList { +public abstract class BulletList implements ContentList{ @Override - public Array getAll() { + public Array getAll(){ return BulletType.all(); } } diff --git a/core/src/io/anuke/mindustry/content/bullets/FlakBullets.java b/core/src/io/anuke/mindustry/content/bullets/FlakBullets.java index fdcec72362..276cb76c7d 100644 --- a/core/src/io/anuke/mindustry/content/bullets/FlakBullets.java +++ b/core/src/io/anuke/mindustry/content/bullets/FlakBullets.java @@ -4,34 +4,34 @@ import io.anuke.mindustry.entities.bullet.BasicBulletType; import io.anuke.mindustry.entities.bullet.BulletType; import io.anuke.mindustry.type.ContentList; -public class FlakBullets extends BulletList implements ContentList { +public class FlakBullets extends BulletList implements ContentList{ public static BulletType lead, plastic, explosive, surge; @Override - public void load() { + public void load(){ - lead = new BasicBulletType(3f, 5, "bullet") { + lead = new BasicBulletType(3f, 5, "bullet"){ { bulletWidth = 7f; bulletHeight = 9f; } }; - plastic = new BasicBulletType(3f, 5, "bullet") { + plastic = new BasicBulletType(3f, 5, "bullet"){ { bulletWidth = 7f; bulletHeight = 9f; } }; - explosive = new BasicBulletType(3f, 5, "bullet") { + explosive = new BasicBulletType(3f, 5, "bullet"){ { bulletWidth = 7f; bulletHeight = 9f; } }; - surge = new BasicBulletType(3f, 5, "bullet") { + surge = new BasicBulletType(3f, 5, "bullet"){ { bulletWidth = 7f; bulletHeight = 9f; diff --git a/core/src/io/anuke/mindustry/content/bullets/MissileBullets.java b/core/src/io/anuke/mindustry/content/bullets/MissileBullets.java index f004eac290..ceea3423f2 100644 --- a/core/src/io/anuke/mindustry/content/bullets/MissileBullets.java +++ b/core/src/io/anuke/mindustry/content/bullets/MissileBullets.java @@ -6,13 +6,13 @@ import io.anuke.mindustry.entities.bullet.MissileBulletType; import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.type.ContentList; -public class MissileBullets extends BulletList implements ContentList { +public class MissileBullets extends BulletList implements ContentList{ public static BulletType explosive, incindiary, surge, javelin; @Override - public void load() { + public void load(){ - explosive = new MissileBulletType(1.8f, 10, "missile") { + explosive = new MissileBulletType(1.8f, 10, "missile"){ { bulletWidth = 8f; bulletHeight = 8f; @@ -26,7 +26,7 @@ public class MissileBullets extends BulletList implements ContentList { } }; - incindiary = new MissileBulletType(2f, 12, "missile") { + incindiary = new MissileBulletType(2f, 12, "missile"){ { frontColor = Palette.lightishOrange; backColor = Palette.lightOrange; @@ -44,14 +44,14 @@ public class MissileBullets extends BulletList implements ContentList { } }; - surge = new MissileBulletType(3f, 5, "bullet") { + surge = new MissileBulletType(3f, 5, "bullet"){ { bulletWidth = 7f; bulletHeight = 9f; } }; - javelin = new MissileBulletType(2.5f, 10, "missile") { + javelin = new MissileBulletType(2.5f, 10, "missile"){ { bulletWidth = 8f; bulletHeight = 8f; diff --git a/core/src/io/anuke/mindustry/content/bullets/StandardBullets.java b/core/src/io/anuke/mindustry/content/bullets/StandardBullets.java index 37efcda5e0..0c0939ac67 100644 --- a/core/src/io/anuke/mindustry/content/bullets/StandardBullets.java +++ b/core/src/io/anuke/mindustry/content/bullets/StandardBullets.java @@ -5,27 +5,27 @@ import io.anuke.mindustry.entities.bullet.BulletType; import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.type.ContentList; -public class StandardBullets extends BulletList implements ContentList { +public class StandardBullets extends BulletList implements ContentList{ public static BulletType tungsten, lead, carbide, thorium, homing, tracer; @Override - public void load() { + public void load(){ - tungsten = new BasicBulletType(3.2f, 10, "bullet") { + tungsten = new BasicBulletType(3.2f, 10, "bullet"){ { bulletWidth = 9f; bulletHeight = 11f; } }; - lead = new BasicBulletType(2.5f, 5, "bullet") { + lead = new BasicBulletType(2.5f, 5, "bullet"){ { bulletWidth = 7f; bulletHeight = 9f; } }; - carbide = new BasicBulletType(3.5f, 18, "bullet") { + carbide = new BasicBulletType(3.5f, 18, "bullet"){ { bulletWidth = 9f; bulletHeight = 12f; @@ -33,7 +33,7 @@ public class StandardBullets extends BulletList implements ContentList { } }; - thorium = new BasicBulletType(4f, 29, "bullet") { + thorium = new BasicBulletType(4f, 29, "bullet"){ { bulletWidth = 10f; bulletHeight = 13f; @@ -41,7 +41,7 @@ public class StandardBullets extends BulletList implements ContentList { } }; - homing = new BasicBulletType(3f, 9, "bullet") { + homing = new BasicBulletType(3f, 9, "bullet"){ { bulletWidth = 7f; bulletHeight = 9f; @@ -49,7 +49,7 @@ public class StandardBullets extends BulletList implements ContentList { } }; - tracer = new BasicBulletType(3.2f, 11, "bullet") { + tracer = new BasicBulletType(3.2f, 11, "bullet"){ { bulletWidth = 10f; bulletHeight = 12f; diff --git a/core/src/io/anuke/mindustry/content/bullets/TurretBullets.java b/core/src/io/anuke/mindustry/content/bullets/TurretBullets.java index 3912d60949..177acacb35 100644 --- a/core/src/io/anuke/mindustry/content/bullets/TurretBullets.java +++ b/core/src/io/anuke/mindustry/content/bullets/TurretBullets.java @@ -29,13 +29,13 @@ import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.world; -public class TurretBullets extends BulletList implements ContentList { +public class TurretBullets extends BulletList implements ContentList{ public static BulletType fireball, basicFlame, lancerLaser, fuseShot, waterShot, cryoShot, lavaShot, oilShot, lightning, driverBolt; @Override - public void load() { + public void load(){ - fireball = new BulletType(1f, 4) { + fireball = new BulletType(1f, 4){ { pierce = true; hitTiles = false; @@ -45,12 +45,12 @@ public class TurretBullets extends BulletList implements ContentList { } @Override - public void init(Bullet b) { + public void init(Bullet b){ b.getVelocity().setLength(0.6f + Mathf.random(2f)); } @Override - public void draw(Bullet b) { + public void draw(Bullet b){ //TODO add color to the bullet depending on the color of the flame it came from Draw.color(Palette.lightFlame, Palette.darkFlame, Color.GRAY, b.fin()); Fill.circle(b.x, b.y, 3f * b.fout()); @@ -58,25 +58,25 @@ public class TurretBullets extends BulletList implements ContentList { } @Override - public void update(Bullet b) { - if (Mathf.chance(0.04 * Timers.delta())) { + public void update(Bullet b){ + if(Mathf.chance(0.04 * Timers.delta())){ Tile tile = world.tileWorld(b.x, b.y); - if (tile != null) { + if(tile != null){ Fire.create(tile); } } - if (Mathf.chance(0.1 * Timers.delta())) { + if(Mathf.chance(0.1 * Timers.delta())){ Effects.effect(EnvironmentFx.fireballsmoke, b.x, b.y); } - if (Mathf.chance(0.1 * Timers.delta())) { + if(Mathf.chance(0.1 * Timers.delta())){ Effects.effect(EnvironmentFx.ballfire, b.x, b.y); } } }; - basicFlame = new BulletType(2f, 5) { + basicFlame = new BulletType(2f, 5){ { hitsize = 7f; lifetime = 30f; @@ -88,11 +88,11 @@ public class TurretBullets extends BulletList implements ContentList { } @Override - public void draw(Bullet b) { + public void draw(Bullet b){ } }; - lancerLaser = new BulletType(0.001f, 110) { + lancerLaser = new BulletType(0.001f, 110){ Color[] colors = {Palette.lancerLaser.cpy().mul(1f, 1f, 1f, 0.4f), Palette.lancerLaser, Color.WHITE}; float[] tscales = {1f, 0.7f, 0.5f, 0.2f}; float[] lenscales = {1f, 1.1f, 1.13f, 1.14f}; @@ -107,19 +107,19 @@ public class TurretBullets extends BulletList implements ContentList { } @Override - public void init(Bullet b) { + public void init(Bullet b){ Damage.collideLine(b, b.getTeam(), hiteffect, b.x, b.y, b.angle(), length); } @Override - public void draw(Bullet b) { + public void draw(Bullet b){ float f = Mathf.curve(b.fin(), 0f, 0.2f); float baseLen = length * f; Lines.lineAngle(b.x, b.y, b.angle(), baseLen); - for (int s = 0; s < 3; s++) { + for(int s = 0; s < 3; s++){ Draw.color(colors[s]); - for (int i = 0; i < tscales.length; i++) { + for(int i = 0; i < tscales.length; i++){ Lines.stroke(7f * b.fout() * (s == 0 ? 1.5f : s == 1 ? 1f : 0.3f) * tscales[i]); Lines.lineAngle(b.x, b.y, b.angle(), baseLen * lenscales[i]); } @@ -128,24 +128,24 @@ public class TurretBullets extends BulletList implements ContentList { } }; - fuseShot = new BulletType(0.01f, 100) { + fuseShot = new BulletType(0.01f, 100){ //TODO }; - waterShot = new LiquidBulletType(Liquids.water) { + waterShot = new LiquidBulletType(Liquids.water){ { status = StatusEffects.wet; statusIntensity = 0.5f; knockback = 0.65f; } }; - cryoShot = new LiquidBulletType(Liquids.cryofluid) { + cryoShot = new LiquidBulletType(Liquids.cryofluid){ { status = StatusEffects.freezing; statusIntensity = 0.5f; } }; - lavaShot = new LiquidBulletType(Liquids.lava) { + lavaShot = new LiquidBulletType(Liquids.lava){ { damage = 4; speed = 1.9f; @@ -154,7 +154,7 @@ public class TurretBullets extends BulletList implements ContentList { statusIntensity = 0.5f; } }; - oilShot = new LiquidBulletType(Liquids.oil) { + oilShot = new LiquidBulletType(Liquids.oil){ { speed = 2f; drag = 0.03f; @@ -162,7 +162,7 @@ public class TurretBullets extends BulletList implements ContentList { statusIntensity = 0.5f; } }; - lightning = new BulletType(0.001f, 10) { + lightning = new BulletType(0.001f, 10){ { lifetime = 1; despawneffect = Fx.none; @@ -170,16 +170,16 @@ public class TurretBullets extends BulletList implements ContentList { } @Override - public void draw(Bullet b) { + public void draw(Bullet b){ } @Override - public void init(Bullet b) { + public void init(Bullet b){ Lightning.create(b.getTeam(), hiteffect, Palette.lancerLaser, damage, b.x, b.y, b.angle(), 30); } }; - driverBolt = new BulletType(5f, 20) { + driverBolt = new BulletType(5f, 20){ { collidesTiles = false; lifetime = 200f; @@ -189,7 +189,7 @@ public class TurretBullets extends BulletList implements ContentList { } @Override - public void draw(Bullet b) { + public void draw(Bullet b){ Draw.color(Color.LIGHT_GRAY); Fill.square(b.x, b.y, 3f, b.angle()); @@ -199,7 +199,7 @@ public class TurretBullets extends BulletList implements ContentList { } @Override - public void update(Bullet b) { + public void update(Bullet b){ //data MUST be an instance of DriverBulletData if(!(b.getData() instanceof DriverBulletData)){ hit(b); @@ -208,7 +208,7 @@ public class TurretBullets extends BulletList implements ContentList { float hitDst = 7f; - DriverBulletData data = (DriverBulletData)b.getData(); + DriverBulletData data = (DriverBulletData) b.getData(); //if the target is dead, just keep flying until the bullet explodes if(data.to.isDead()){ @@ -245,15 +245,15 @@ public class TurretBullets extends BulletList implements ContentList { } @Override - public void despawned(Bullet b) { + public void despawned(Bullet b){ super.despawned(b); if(!(b.getData() instanceof DriverBulletData)) return; - DriverBulletData data = (DriverBulletData)b.getData(); + DriverBulletData data = (DriverBulletData) b.getData(); data.to.isRecieving = false; - for(int i = 0; i < data.items.length; i ++){ + for(int i = 0; i < data.items.length; i++){ int amountDropped = Mathf.random(0, data.items[i]); if(amountDropped > 0){ float angle = b.angle() + Mathf.range(100f); @@ -264,7 +264,7 @@ public class TurretBullets extends BulletList implements ContentList { } @Override - public void hit(Bullet b, float hitx, float hity) { + public void hit(Bullet b, float hitx, float hity){ super.hit(b, hitx, hity); despawned(b); } diff --git a/core/src/io/anuke/mindustry/content/bullets/WeaponBullets.java b/core/src/io/anuke/mindustry/content/bullets/WeaponBullets.java index d7195ee768..04997b8c68 100644 --- a/core/src/io/anuke/mindustry/content/bullets/WeaponBullets.java +++ b/core/src/io/anuke/mindustry/content/bullets/WeaponBullets.java @@ -16,12 +16,12 @@ import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.world; -public class WeaponBullets extends BulletList { +public class WeaponBullets extends BulletList{ public static BulletType tungstenShotgun, bombExplosive, bombIncendiary, bombOil, shellCarbide; @Override - public void load() { - tungstenShotgun = new BasicBulletType(5f, 8, "bullet") { + public void load(){ + tungstenShotgun = new BasicBulletType(5f, 8, "bullet"){ { bulletWidth = 8f; bulletHeight = 9f; @@ -49,10 +49,10 @@ public class WeaponBullets extends BulletList { } @Override - public void hit(Bullet b, float x, float y) { + public void hit(Bullet b, float x, float y){ super.hit(b, x, y); - for (int i = 0; i < 3; i++) { + for(int i = 0; i < 3; i++){ float cx = x + Mathf.range(10f); float cy = y + Mathf.range(10f); Tile tile = world.tileWorld(cx, cy); @@ -73,17 +73,17 @@ public class WeaponBullets extends BulletList { } @Override - public void hit(Bullet b, float x, float y) { + public void hit(Bullet b, float x, float y){ super.hit(b, x, y); - for (int i = 0; i < 3; i++) { + for(int i = 0; i < 3; i++){ Tile tile = world.tileWorld(x + Mathf.range(8f), y + Mathf.range(8f)); Puddle.deposit(tile, Liquids.oil, 5f); } } }; - shellCarbide = new BasicBulletType(3.4f, 20, "bullet") { + shellCarbide = new BasicBulletType(3.4f, 20, "bullet"){ { bulletWidth = 10f; bulletHeight = 12f; diff --git a/core/src/io/anuke/mindustry/content/fx/BlockFx.java b/core/src/io/anuke/mindustry/content/fx/BlockFx.java index 14e77406c6..9260c76b0f 100644 --- a/core/src/io/anuke/mindustry/content/fx/BlockFx.java +++ b/core/src/io/anuke/mindustry/content/fx/BlockFx.java @@ -19,7 +19,7 @@ public class BlockFx extends FxList implements ContentList{ public static Effect reactorsmoke, nuclearsmoke, nuclearcloud, redgeneratespark, generatespark, fuelburn, plasticburn, pulverize, pulverizeRed, pulverizeRedder, pulverizeSmall, pulverizeMedium, producesmoke, smeltsmoke, formsmoke, blastsmoke, lava, dooropen, doorclose, dooropenlarge, doorcloselarge, purify, purifyoil, purifystone, generate, mine, mineBig, mineHuge, smelt, teleportActivate, teleport, teleportOut, ripple, bubble; @Override - public void load() { + public void load(){ reactorsmoke = new Effect(17, e -> { Angles.randLenVectors(e.id, 4, e.fin() * 8f, (x, y) -> { diff --git a/core/src/io/anuke/mindustry/content/fx/BulletFx.java b/core/src/io/anuke/mindustry/content/fx/BulletFx.java index d5977c3ef9..73a53a6c70 100644 --- a/core/src/io/anuke/mindustry/content/fx/BulletFx.java +++ b/core/src/io/anuke/mindustry/content/fx/BulletFx.java @@ -10,12 +10,12 @@ import io.anuke.ucore.graphics.Lines; import io.anuke.ucore.util.Angles; import io.anuke.ucore.util.Mathf; -public class BulletFx extends FxList implements ContentList { +public class BulletFx extends FxList implements ContentList{ public static Effect hitBulletSmall, hitBulletBig, hitFlameSmall, hitLiquid, hitLancer, despawn, flakExplosion, blastExplosion, plasticExplosion, artilleryTrail, incendTrail, missileTrail; @Override - public void load() { + public void load(){ hitBulletSmall = new Effect(14, e -> { Draw.color(Color.WHITE, Palette.lightOrange, e.fin()); diff --git a/core/src/io/anuke/mindustry/content/fx/EnvironmentFx.java b/core/src/io/anuke/mindustry/content/fx/EnvironmentFx.java index d1eb624141..e8f3fe6b2e 100644 --- a/core/src/io/anuke/mindustry/content/fx/EnvironmentFx.java +++ b/core/src/io/anuke/mindustry/content/fx/EnvironmentFx.java @@ -10,11 +10,11 @@ import io.anuke.ucore.graphics.Fill; import io.anuke.ucore.util.Angles; import io.anuke.ucore.util.Mathf; -public class EnvironmentFx extends FxList implements ContentList { +public class EnvironmentFx extends FxList implements ContentList{ public static Effect burning, fire, smoke, steam, fireballsmoke, ballfire, freezing, melting, wet, oily; @Override - public void load() { + public void load(){ burning = new Effect(35f, e -> { Draw.color(Palette.lightFlame, Palette.darkFlame, e.fin()); diff --git a/core/src/io/anuke/mindustry/content/fx/ExplosionFx.java b/core/src/io/anuke/mindustry/content/fx/ExplosionFx.java index 78f4a7e4fa..457c2dfe32 100644 --- a/core/src/io/anuke/mindustry/content/fx/ExplosionFx.java +++ b/core/src/io/anuke/mindustry/content/fx/ExplosionFx.java @@ -10,11 +10,11 @@ import io.anuke.ucore.graphics.Lines; import io.anuke.ucore.util.Angles; import io.anuke.ucore.util.Mathf; -public class ExplosionFx extends FxList implements ContentList { +public class ExplosionFx extends FxList implements ContentList{ public static Effect shockwave, bigShockwave, nuclearShockwave, explosion, blockExplosion, blockExplosionSmoke; @Override - public void load() { + public void load(){ shockwave = new Effect(10f, 80f, e -> { Draw.color(Color.WHITE, Color.LIGHT_GRAY, e.fin()); diff --git a/core/src/io/anuke/mindustry/content/fx/Fx.java b/core/src/io/anuke/mindustry/content/fx/Fx.java index 693a412742..f76f12d233 100644 --- a/core/src/io/anuke/mindustry/content/fx/Fx.java +++ b/core/src/io/anuke/mindustry/content/fx/Fx.java @@ -11,59 +11,59 @@ import io.anuke.ucore.util.Angles; import static io.anuke.mindustry.Vars.tilesize; -public class Fx extends FxList implements ContentList { - public static Effect none, placeBlock, breakBlock, smoke, spawn, tapBlock, select; +public class Fx extends FxList implements ContentList{ + public static Effect none, placeBlock, breakBlock, smoke, spawn, tapBlock, select; - @Override - public void load() { + @Override + public void load(){ - none = new Effect(0, 0f, e -> { - }); + none = new Effect(0, 0f, e -> { + }); - placeBlock = new Effect(16, e -> { - Draw.color(Palette.accent); - Lines.stroke(3f - e.fin() * 2f); - Lines.square(e.x, e.y, tilesize / 2f * e.rotation + e.fin() * 3f); - Draw.reset(); - }); + placeBlock = new Effect(16, e -> { + Draw.color(Palette.accent); + Lines.stroke(3f - e.fin() * 2f); + Lines.square(e.x, e.y, tilesize / 2f * e.rotation + e.fin() * 3f); + Draw.reset(); + }); - tapBlock = new Effect(12, e -> { - Draw.color(Palette.accent); - Lines.stroke(3f - e.fin() * 2f); - Lines.circle(e.x, e.y, 4f + (tilesize/1.5f * e.rotation) * e.fin()); - Draw.reset(); - }); + tapBlock = new Effect(12, e -> { + Draw.color(Palette.accent); + Lines.stroke(3f - e.fin() * 2f); + Lines.circle(e.x, e.y, 4f + (tilesize / 1.5f * e.rotation) * e.fin()); + Draw.reset(); + }); - breakBlock = new Effect(12, e -> { - Draw.color(Palette.remove); - Lines.stroke(3f - e.fin() * 2f); - Lines.square(e.x, e.y, tilesize / 2f * e.rotation + e.fin() * 3f); + breakBlock = new Effect(12, e -> { + Draw.color(Palette.remove); + Lines.stroke(3f - e.fin() * 2f); + Lines.square(e.x, e.y, tilesize / 2f * e.rotation + e.fin() * 3f); - Angles.randLenVectors(e.id, 3 + (int) (e.rotation * 3), e.rotation * 2f + (tilesize * e.rotation) * e.finpow(), (x, y) -> { - Fill.square(e.x + x, e.y + y, 1f + e.fout() * (3f + e.rotation)); - }); - Draw.reset(); - }); + Angles.randLenVectors(e.id, 3 + (int) (e.rotation * 3), e.rotation * 2f + (tilesize * e.rotation) * e.finpow(), (x, y) -> { + Fill.square(e.x + x, e.y + y, 1f + e.fout() * (3f + e.rotation)); + }); + Draw.reset(); + }); - select = new Effect(23, e -> { - Draw.color(Palette.accent); - Lines.stroke(e.fout() * 3f); - Lines.circle(e.x, e.y, 3f + e.fin() * 14f); - Draw.reset(); - }); + select = new Effect(23, e -> { + Draw.color(Palette.accent); + Lines.stroke(e.fout() * 3f); + Lines.circle(e.x, e.y, 3f + e.fin() * 14f); + Draw.reset(); + }); - smoke = new Effect(100, e -> { - Draw.color(Color.GRAY, Palette.darkishGray, e.fin()); - float size = 7f - e.fin() * 7f; - Draw.rect("circle", e.x, e.y, size, size); - Draw.reset(); - }); + smoke = new Effect(100, e -> { + Draw.color(Color.GRAY, Palette.darkishGray, e.fin()); + float size = 7f - e.fin() * 7f; + Draw.rect("circle", e.x, e.y, size, size); + Draw.reset(); + }); - spawn = new Effect(23, e -> { - Lines.stroke(2f * e.fout()); - Draw.color(Palette.accent); - Lines.poly(e.x, e.y, 4, 3f + e.fin() * 8f); - Draw.reset(); - }); - } + spawn = new Effect(23, e -> { + Lines.stroke(2f * e.fout()); + Draw.color(Palette.accent); + Lines.poly(e.x, e.y, 4, 3f + e.fin() * 8f); + Draw.reset(); + }); + } } diff --git a/core/src/io/anuke/mindustry/content/fx/FxList.java b/core/src/io/anuke/mindustry/content/fx/FxList.java index f1fd467602..fe87cc2eb8 100644 --- a/core/src/io/anuke/mindustry/content/fx/FxList.java +++ b/core/src/io/anuke/mindustry/content/fx/FxList.java @@ -7,7 +7,7 @@ import io.anuke.mindustry.type.ContentList; public abstract class FxList implements ContentList{ @Override - public Array getAll() { + public Array getAll(){ return Array.with(); } } diff --git a/core/src/io/anuke/mindustry/content/fx/ShootFx.java b/core/src/io/anuke/mindustry/content/fx/ShootFx.java index b0a83f7f80..2e55246cc8 100644 --- a/core/src/io/anuke/mindustry/content/fx/ShootFx.java +++ b/core/src/io/anuke/mindustry/content/fx/ShootFx.java @@ -12,11 +12,11 @@ import io.anuke.ucore.graphics.Shapes; import io.anuke.ucore.util.Angles; import io.anuke.ucore.util.Mathf; -public class ShootFx extends FxList implements ContentList { +public class ShootFx extends FxList implements ContentList{ public static Effect shootSmall, shootSmallSmoke, shootBig, shootBig2, shootBigSmoke, shootBigSmoke2, shootSmallFlame, shootLiquid, shellEjectSmall, shellEjectMedium, shellEjectBig, lancerLaserShoot, lancerLaserShootSmoke, lancerLaserCharge, lancerLaserChargeBegin, lightningCharge, lightningShoot; @Override - public void load() { + public void load(){ shootSmall = new Effect(8, e -> { Draw.color(Palette.lighterOrange, Palette.lightOrange, e.fin()); @@ -111,7 +111,7 @@ public class ShootFx extends FxList implements ContentList { shellEjectMedium = new GroundEffect(34f, 400f, e -> { Draw.color(Palette.lightOrange, Color.LIGHT_GRAY, Palette.lightishGray, e.fin()); float rot = e.rotation + 90f; - for (int i : Mathf.signs) { + for(int i : Mathf.signs){ float len = (2f + e.finpow() * 10f) * i; float lr = rot + e.fin() * 20f * i; Draw.rect("casing", @@ -122,7 +122,7 @@ public class ShootFx extends FxList implements ContentList { Draw.color(Color.LIGHT_GRAY, Color.GRAY, e.fin()); - for (int i : Mathf.signs) { + for(int i : Mathf.signs){ Angles.randLenVectors(e.id, 4, 1f + e.finpow() * 11f, e.rotation + 90f * i, 20f, (x, y) -> { Fill.circle(e.x + x, e.y + y, e.fout() * 1.5f); }); @@ -134,7 +134,7 @@ public class ShootFx extends FxList implements ContentList { shellEjectBig = new GroundEffect(22f, 400f, e -> { Draw.color(Palette.lightOrange, Color.LIGHT_GRAY, Palette.lightishGray, e.fin()); float rot = e.rotation + 90f; - for (int i : Mathf.signs) { + for(int i : Mathf.signs){ float len = (4f + e.finpow() * 8f) * i; float lr = rot + Mathf.randomSeedRange(e.id + i + 6, 20f * e.fin()) * i; Draw.rect("casing", @@ -146,7 +146,7 @@ public class ShootFx extends FxList implements ContentList { Draw.color(Color.LIGHT_GRAY); - for (int i : Mathf.signs) { + for(int i : Mathf.signs){ Angles.randLenVectors(e.id, 4, -e.finpow() * 15f, e.rotation + 90f * i, 25f, (x, y) -> { Fill.circle(e.x + x, e.y + y, e.fout() * 2f); }); @@ -158,7 +158,7 @@ public class ShootFx extends FxList implements ContentList { lancerLaserShoot = new Effect(21f, e -> { Draw.color(Palette.lancerLaser); - for (int i : Mathf.signs) { + for(int i : Mathf.signs){ Shapes.tri(e.x, e.y, 4f * e.fout(), 29f, e.rotation + 90f * i); } diff --git a/core/src/io/anuke/mindustry/content/fx/UnitFx.java b/core/src/io/anuke/mindustry/content/fx/UnitFx.java index 3035fce5b1..69117a0237 100644 --- a/core/src/io/anuke/mindustry/content/fx/UnitFx.java +++ b/core/src/io/anuke/mindustry/content/fx/UnitFx.java @@ -10,11 +10,11 @@ import io.anuke.ucore.graphics.Lines; import io.anuke.ucore.util.Angles; import io.anuke.ucore.util.Mathf; -public class UnitFx extends FxList implements ContentList { +public class UnitFx extends FxList implements ContentList{ public static Effect vtolHover, unitDrop, unitPickup, pickup; @Override - public void load() { + public void load(){ vtolHover = new Effect(40f, e -> { float len = e.finpow() * 10f; diff --git a/core/src/io/anuke/mindustry/core/ContentLoader.java b/core/src/io/anuke/mindustry/core/ContentLoader.java index d60fd098a3..db6a5ed7a2 100644 --- a/core/src/io/anuke/mindustry/core/ContentLoader.java +++ b/core/src/io/anuke/mindustry/core/ContentLoader.java @@ -25,76 +25,80 @@ import io.anuke.ucore.core.Effects; import io.anuke.ucore.function.Consumer; import io.anuke.ucore.util.Log; -/**Loads all game content. - * Call load() before doing anything with content.*/ -public class ContentLoader { +/** + * Loads all game content. + * Call load() before doing anything with content. + */ +public class ContentLoader{ private static boolean loaded = false; private static ObjectSet> contentSet = new OrderedSet<>(); private static OrderedMap> contentMap = new OrderedMap<>(); private static ObjectSet> initialization = new ObjectSet<>(); private static ContentList[] content = { - //effects - new BlockFx(), - new BulletFx(), - new EnvironmentFx(), - new ExplosionFx(), - new Fx(), - new ShootFx(), - new UnitFx(), + //effects + new BlockFx(), + new BulletFx(), + new EnvironmentFx(), + new ExplosionFx(), + new Fx(), + new ShootFx(), + new UnitFx(), - //items - new Items(), + //items + new Items(), - //status effects - new StatusEffects(), + //status effects + new StatusEffects(), - //liquids - new Liquids(), + //liquids + new Liquids(), - //bullets - new ArtilleryBullets(), - new FlakBullets(), - new MissileBullets(), - new StandardBullets(), - new TurretBullets(), - new WeaponBullets(), + //bullets + new ArtilleryBullets(), + new FlakBullets(), + new MissileBullets(), + new StandardBullets(), + new TurretBullets(), + new WeaponBullets(), - //ammotypes - new AmmoTypes(), + //ammotypes + new AmmoTypes(), - //weapons - new Weapons(), + //weapons + new Weapons(), - //mechs - new Mechs(), + //mechs + new Mechs(), - //units - new UnitTypes(), + //units + new UnitTypes(), - //blocks - new Blocks(), - new DefenseBlocks(), - new DistributionBlocks(), - new ProductionBlocks(), - new TurretBlocks(), - new DebugBlocks(), - new LiquidBlocks(), - new StorageBlocks(), - new UnitBlocks(), - new PowerBlocks(), - new CraftingBlocks(), - new UpgradeBlocks(), - new OreBlocks(), + //blocks + new Blocks(), + new DefenseBlocks(), + new DistributionBlocks(), + new ProductionBlocks(), + new TurretBlocks(), + new DebugBlocks(), + new LiquidBlocks(), + new StorageBlocks(), + new UnitBlocks(), + new PowerBlocks(), + new CraftingBlocks(), + new UpgradeBlocks(), + new OreBlocks(), - //not really a content class, but this makes initialization easier - new ColorMapper(), + //not really a content class, but this makes initialization easier + new ColorMapper(), - //recipes - new Recipes(), + //recipes + new Recipes(), }; - /**Creates all content types.*/ + /** + * Creates all content types. + */ public static void load(){ if(loaded){ Log.info("Content already loaded, skipping."); @@ -103,11 +107,11 @@ public class ContentLoader { registerTypes(); - for (ContentList list : content){ + for(ContentList list : content){ list.load(); } - for (ContentList list : content){ + for(ContentList list : content){ if(list.getAll().size != 0){ String type = list.getAll().first().getContentTypeName(); @@ -134,7 +138,9 @@ public class ContentLoader { loaded = true; } - /**Initializes all content with the specified function.*/ + /** + * Initializes all content with the specified function. + */ public static void initialize(Consumer callable){ if(initialization.contains(callable)) return; @@ -155,8 +161,10 @@ public class ContentLoader { return contentMap; } - /**Registers sync IDs for all types of sync entities. - * Do not register units here!*/ + /** + * Registers sync IDs for all types of sync entities. + * Do not register units here! + */ private static void registerTypes(){ TypeTrait.registerType(Player.class, Player::new); TypeTrait.registerType(ItemDrop.class, ItemDrop::new); diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index 1c53e73208..6a9dca0998 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -30,148 +30,152 @@ import io.anuke.ucore.util.Atlas; import static io.anuke.mindustry.Vars.*; -/**Control module. +/** + * Control module. * Handles all input, saving, keybinds and keybinds. * Should not handle any logic-critical state. - * This class is not created in the headless server.*/ + * This class is not created in the headless server. + */ public class Control extends Module{ - /**Minimum period of time between the same sound being played.*/ - private static final long minSoundPeriod = 100; + /** + * Minimum period of time between the same sound being played. + */ + private static final long minSoundPeriod = 100; - private boolean hiscore = false; - private boolean wasPaused = false; - private Saves saves; - private ContentDatabase db; - private InputHandler[] inputs = {}; - private ObjectMap soundMap = new ObjectMap<>(); + private boolean hiscore = false; + private boolean wasPaused = false; + private Saves saves; + private ContentDatabase db; + private InputHandler[] inputs = {}; + private ObjectMap soundMap = new ObjectMap<>(); private Throwable error; private Input gdxInput; - public Control(){ + public Control(){ - saves = new Saves(); - db = new ContentDatabase(); + saves = new Saves(); + db = new ContentDatabase(); - Inputs.useControllers(!gwt); + Inputs.useControllers(!gwt); - Gdx.input.setCatchBackKey(true); + Gdx.input.setCatchBackKey(true); - Effects.setShakeFalloff(10000f); + Effects.setShakeFalloff(10000f); - ContentLoader.initialize(Content::init); - Core.atlas = new Atlas("sprites.atlas"); - Core.atlas.setErrorRegion("error"); - ContentLoader.initialize(Content::load); + ContentLoader.initialize(Content::init); + Core.atlas = new Atlas("sprites.atlas"); + Core.atlas.setErrorRegion("error"); + ContentLoader.initialize(Content::load); - db.load(); + db.load(); - gdxInput = Gdx.input; + gdxInput = Gdx.input; - Sounds.load("shoot.mp3", "place.mp3", "explosion.mp3", "enemyshoot.mp3", - "corexplode.mp3", "break.mp3", "spawn.mp3", "flame.mp3", "die.mp3", - "respawn.mp3", "purchase.mp3", "flame2.mp3", "bigshot.mp3", "laser.mp3", "lasershot.mp3", - "ping.mp3", "tesla.mp3", "waveend.mp3", "railgun.mp3", "blast.mp3", "bang2.mp3"); + Sounds.load("shoot.mp3", "place.mp3", "explosion.mp3", "enemyshoot.mp3", + "corexplode.mp3", "break.mp3", "spawn.mp3", "flame.mp3", "die.mp3", + "respawn.mp3", "purchase.mp3", "flame2.mp3", "bigshot.mp3", "laser.mp3", "lasershot.mp3", + "ping.mp3", "tesla.mp3", "waveend.mp3", "railgun.mp3", "blast.mp3", "bang2.mp3"); - Sounds.setFalloff(9000f); - Sounds.setPlayer((sound, volume) -> { - long time = TimeUtils.millis(); - long value = soundMap.get(sound, 0L); + Sounds.setFalloff(9000f); + Sounds.setPlayer((sound, volume) -> { + long time = TimeUtils.millis(); + long value = soundMap.get(sound, 0L); - if(TimeUtils.timeSinceMillis(value) >= minSoundPeriod){ - threads.run(() -> sound.play(volume)); - soundMap.put(sound, time); - } - }); + if(TimeUtils.timeSinceMillis(value) >= minSoundPeriod){ + threads.run(() -> sound.play(volume)); + soundMap.put(sound, time); + } + }); Musics.load("1.mp3", "2.mp3", "3.mp3", "4.mp3", "5.mp3", "6.mp3"); DefaultKeybinds.load(); - Settings.defaultList( - "ip", "localhost", - "port", port+"", - "color-0", Color.rgba8888(playerColors[8]), - "color-1", Color.rgba8888(playerColors[11]), - "color-2", Color.rgba8888(playerColors[13]), - "color-3", Color.rgba8888(playerColors[9]), - "name", "player", - "lastBuild", 0 - ); + Settings.defaultList( + "ip", "localhost", + "port", port + "", + "color-0", Color.rgba8888(playerColors[8]), + "color-1", Color.rgba8888(playerColors[11]), + "color-2", Color.rgba8888(playerColors[13]), + "color-3", Color.rgba8888(playerColors[9]), + "name", "player", + "lastBuild", 0 + ); - KeyBinds.load(); + KeyBinds.load(); - addPlayer(0); + addPlayer(0); - saves.load(); + saves.load(); - Events.on(StateChangeEvent.class, (from, to) -> { - if((from == State.playing && to == State.menu) || (from == State.menu && to != State.menu)){ - Timers.runTask(5f, Platform.instance::updateRPC); - } - }); + Events.on(StateChangeEvent.class, (from, to) -> { + if((from == State.playing && to == State.menu) || (from == State.menu && to != State.menu)){ + Timers.runTask(5f, Platform.instance::updateRPC); + } + }); - Events.on(PlayEvent.class, () -> { - for(Player player : players){ + Events.on(PlayEvent.class, () -> { + for(Player player : players){ player.add(); } - state.set(State.playing); - }); + state.set(State.playing); + }); - Events.on(WorldLoadGraphicsEvent.class, () -> { - if(mobile){ - Core.camera.position.set(players[0].x, players[0].y, 0); - } - }); + Events.on(WorldLoadGraphicsEvent.class, () -> { + if(mobile){ + Core.camera.position.set(players[0].x, players[0].y, 0); + } + }); - Events.on(ResetEvent.class, () -> { - for(Player player : players){ - player.reset(); + Events.on(ResetEvent.class, () -> { + for(Player player : players){ + player.reset(); } - hiscore = false; + hiscore = false; - saves.resetSave(); - }); + saves.resetSave(); + }); - Events.on(WaveEvent.class, () -> { + Events.on(WaveEvent.class, () -> { - int last = Settings.getInt("hiscore" + world.getMap().name, 0); + int last = Settings.getInt("hiscore" + world.getMap().name, 0); - if(state.wave > last && !state.mode.infiniteResources && !state.mode.disableWaveTimer){ - Settings.putInt("hiscore" + world.getMap().name, state.wave); - Settings.save(); - hiscore = true; - } + if(state.wave > last && !state.mode.infiniteResources && !state.mode.disableWaveTimer){ + Settings.putInt("hiscore" + world.getMap().name, state.wave); + Settings.save(); + hiscore = true; + } - Platform.instance.updateRPC(); - }); + Platform.instance.updateRPC(); + }); - Events.on(GameOverEvent.class, () -> { - Effects.shake(5, 6, Core.camera.position.x, Core.camera.position.y); + Events.on(GameOverEvent.class, () -> { + Effects.shake(5, 6, Core.camera.position.x, Core.camera.position.y); - //TODO game over effect - ui.restart.show(); + //TODO game over effect + ui.restart.show(); - Timers.runTask(30f, () -> state.set(State.menu)); - }); + Timers.runTask(30f, () -> state.set(State.menu)); + }); - Events.on(WorldLoadEvent.class, () -> threads.runGraphics(() -> Events.fire(WorldLoadGraphicsEvent.class))); - } + Events.on(WorldLoadEvent.class, () -> threads.runGraphics(() -> Events.fire(WorldLoadGraphicsEvent.class))); + } - public void addPlayer(int index){ - if(players.length != index + 1){ - Player[] old = players; - players = new Player[index + 1]; + public void addPlayer(int index){ + if(players.length != index + 1){ + Player[] old = players; + players = new Player[index + 1]; System.arraycopy(old, 0, players, 0, old.length); } if(inputs.length != index + 1){ - InputHandler[] oldi = inputs; - inputs = new InputHandler[index + 1]; - System.arraycopy(oldi, 0, inputs, 0, oldi.length); - } + InputHandler[] oldi = inputs; + inputs = new InputHandler[index + 1]; + System.arraycopy(oldi, 0, inputs, 0, oldi.length); + } Player setTo = (index == 0 ? null : players[0]); @@ -205,8 +209,8 @@ public class Control extends Module{ } public void removePlayer(){ - players[players.length-1].remove(); - inputs[inputs.length-1].remove(); + players[players.length - 1].remove(); + inputs[inputs.length - 1].remove(); Player[] old = players; players = new Player[players.length - 1]; @@ -217,191 +221,191 @@ public class Control extends Module{ System.arraycopy(oldi, 0, inputs, 0, inputs.length); } - public ContentDatabase database() { - return db; - } - - public Input gdxInput(){ - return gdxInput; + public ContentDatabase database(){ + return db; } - public void setError(Throwable error){ - this.error = error; - } - - public Saves getSaves(){ - return saves; - } - - public InputHandler input(int index){ - return inputs[index]; - } - - public void triggerUpdateInput(){ - //Gdx.input = proxy; + public Input gdxInput(){ + return gdxInput; } - public void playMap(Map map){ - ui.loadfrag.show(); + public void setError(Throwable error){ + this.error = error; + } - Timers.run(5f, () -> - threads.run(() -> { - logic.reset(); - world.loadMap(map); - logic.play(); + public Saves getSaves(){ + return saves; + } - Gdx.app.postRunnable(ui.loadfrag::hide); - })); - } + public InputHandler input(int index){ + return inputs[index]; + } - public boolean isHighScore(){ - return hiscore; - } + public void triggerUpdateInput(){ + //Gdx.input = proxy; + } - private void checkUnlockableBlocks(){ - TileEntity entity = players[0].getClosestCore(); + public void playMap(Map map){ + ui.loadfrag.show(); - if(entity == null) return; + Timers.run(5f, () -> + threads.run(() -> { + logic.reset(); + world.loadMap(map); + logic.play(); - entity.items.forEach((item, amount) -> control.database().unlockContent(item)); + Gdx.app.postRunnable(ui.loadfrag::hide); + })); + } - if(players[0].inventory.hasItem()){ - control.database().unlockContent(players[0].inventory.getItem().item); - } + public boolean isHighScore(){ + return hiscore; + } - for(int i = 0 ; i < Recipe.all().size; i ++){ - Recipe recipe = Recipe.all().get(i); - if(!recipe.debugOnly && entity.items.has(recipe.requirements, 1.4f)){ - if(control.database().unlockContent(recipe)){ - ui.hudfrag.showUnlock(recipe); - } - } - } - } + private void checkUnlockableBlocks(){ + TileEntity entity = players[0].getClosestCore(); - @Override - public void dispose(){ - Platform.instance.onGameExit(); - ContentLoader.dispose(); - Net.dispose(); - ui.editor.dispose(); - inputs = new InputHandler[]{}; - players = new Player[]{}; - } + if(entity == null) return; - @Override - public void pause(){ - wasPaused = state.is(State.paused); - if(state.is(State.playing)) state.set(State.paused); - } + entity.items.forEach((item, amount) -> control.database().unlockContent(item)); - @Override - public void resume(){ - if(state.is(State.paused) && !wasPaused){ + if(players[0].inventory.hasItem()){ + control.database().unlockContent(players[0].inventory.getItem().item); + } + + for(int i = 0; i < Recipe.all().size; i++){ + Recipe recipe = Recipe.all().get(i); + if(!recipe.debugOnly && entity.items.has(recipe.requirements, 1.4f)){ + if(control.database().unlockContent(recipe)){ + ui.hudfrag.showUnlock(recipe); + } + } + } + } + + @Override + public void dispose(){ + Platform.instance.onGameExit(); + ContentLoader.dispose(); + Net.dispose(); + ui.editor.dispose(); + inputs = new InputHandler[]{}; + players = new Player[]{}; + } + + @Override + public void pause(){ + wasPaused = state.is(State.paused); + if(state.is(State.playing)) state.set(State.paused); + } + + @Override + public void resume(){ + if(state.is(State.paused) && !wasPaused){ state.set(State.playing); - } - } + } + } - @Override - public void init(){ - EntityPhysics.initPhysics(); + @Override + public void init(){ + EntityPhysics.initPhysics(); - Platform.instance.updateRPC(); + Platform.instance.updateRPC(); - if(!Settings.has("4.0-warning")){ - Settings.putBool("4.0-warning", true); + if(!Settings.has("4.0-warning")){ + Settings.putBool("4.0-warning", true); - Timers.run(5f, () -> { - FloatingDialog dialog = new FloatingDialog("[orange]WARNING![]"); - dialog.buttons().addButton("$text.ok", dialog::hide).size(100f, 60f); - dialog.content().add("The beta version you are about to play should be considered very unstable, and is [accent]not representative of the final 4.0 release.[]\n\n " + - "A large portion of content is still unimplemented. \nAll current art and UI is temporary, and will be re-drawn before release. " + - "\n\n[accent]Saves and maps may be corrupted without warning between updates.[] You have been warned!").wrap().width(500f); - dialog.show(); + Timers.run(5f, () -> { + FloatingDialog dialog = new FloatingDialog("[orange]WARNING![]"); + dialog.buttons().addButton("$text.ok", dialog::hide).size(100f, 60f); + dialog.content().add("The beta version you are about to play should be considered very unstable, and is [accent]not representative of the final 4.0 release.[]\n\n " + + "A large portion of content is still unimplemented. \nAll current art and UI is temporary, and will be re-drawn before release. " + + "\n\n[accent]Saves and maps may be corrupted without warning between updates.[] You have been warned!").wrap().width(500f); + dialog.show(); - }); - } + }); + } - if(!Settings.has("4.0-no-sound")){ - Settings.putBool("4.0-no-sound", true); + if(!Settings.has("4.0-no-sound")){ + Settings.putBool("4.0-no-sound", true); - Timers.run(4f, () -> { - FloatingDialog dialog = new FloatingDialog("[orange]Attention![]"); - dialog.buttons().addButton("$text.ok", dialog::hide).size(100f, 60f); - dialog.content().add("You might have noticed that 4.0 does not have any sound.\nThis is [orange]intentional![] Sound will be added in a later update.\n\n[LIGHT_GRAY](now stop reporting this as a bug)").wrap().width(500f); - dialog.show(); + Timers.run(4f, () -> { + FloatingDialog dialog = new FloatingDialog("[orange]Attention![]"); + dialog.buttons().addButton("$text.ok", dialog::hide).size(100f, 60f); + dialog.content().add("You might have noticed that 4.0 does not have any sound.\nThis is [orange]intentional![] Sound will be added in a later update.\n\n[LIGHT_GRAY](now stop reporting this as a bug)").wrap().width(500f); + dialog.show(); - }); - } - } + }); + } + } - /**Called from main logic thread.*/ - public void runUpdateLogic(){ - if(!state.is(State.menu)) { - renderer.minimap().updateUnitArray(); - } - } + /** Called from main logic thread.*/ + public void runUpdateLogic(){ + if(!state.is(State.menu)){ + renderer.minimap().updateUnitArray(); + } + } - @Override - public void update(){ + @Override + public void update(){ - if(error != null){ - throw new RuntimeException(error); - } + if(error != null){ + throw new RuntimeException(error); + } if(Inputs.keyTap("console")){ - console = !console; - } + console = !console; + } saves.update(); - triggerUpdateInput(); + triggerUpdateInput(); - for(InputHandler inputHandler : inputs){ - inputHandler.updateController(); - } + for(InputHandler inputHandler : inputs){ + inputHandler.updateController(); + } - if(!state.is(State.menu)){ - for(InputHandler input : inputs){ - input.update(); + if(!state.is(State.menu)){ + for(InputHandler input : inputs){ + input.update(); } //check unlocks every 2 seconds - if(!state.mode.infiniteResources && Timers.get("timerCheckUnlock", 120)){ - checkUnlockableBlocks(); + if(!state.mode.infiniteResources && Timers.get("timerCheckUnlock", 120)){ + checkUnlockableBlocks(); - //save if the db changed, but don't save unlocks - if(db.isDirty() && !debug){ - db.save(); - } - } + //save if the db changed, but don't save unlocks + if(db.isDirty() && !debug){ + db.save(); + } + } - if(Inputs.keyTap("pause") && !ui.restart.isShown() && (state.is(State.paused) || state.is(State.playing))){ + if(Inputs.keyTap("pause") && !ui.restart.isShown() && (state.is(State.paused) || state.is(State.playing))){ state.set(state.is(State.playing) ? State.paused : State.playing); - } + } - if(Inputs.keyTap("menu")){ - if(state.is(State.paused)){ - ui.paused.hide(); + if(Inputs.keyTap("menu")){ + if(state.is(State.paused)){ + ui.paused.hide(); state.set(State.playing); - }else if (!ui.restart.isShown()){ - if(ui.chatfrag.chatOpen()) { - ui.chatfrag.hide(); - }else{ - ui.paused.show(); + }else if(!ui.restart.isShown()){ + if(ui.chatfrag.chatOpen()){ + ui.chatfrag.hide(); + }else{ + ui.paused.show(); state.set(State.paused); - } - } - } + } + } + } - if(!state.is(State.paused) || Net.active()){ - Entities.update(effectGroup); - Entities.update(groundEffectGroup); - } - }else{ - if(!state.is(State.paused) || Net.active()){ - Timers.update(); - } - } - } + if(!state.is(State.paused) || Net.active()){ + Entities.update(effectGroup); + Entities.update(groundEffectGroup); + } + }else{ + if(!state.is(State.paused) || Net.active()){ + Timers.update(); + } + } + } } diff --git a/core/src/io/anuke/mindustry/core/GameState.java b/core/src/io/anuke/mindustry/core/GameState.java index b368a9867e..92eee9a4d3 100644 --- a/core/src/io/anuke/mindustry/core/GameState.java +++ b/core/src/io/anuke/mindustry/core/GameState.java @@ -8,31 +8,30 @@ import io.anuke.mindustry.game.TeamInfo; import io.anuke.ucore.core.Events; public class GameState{ - private State state = State.menu; + public int wave = 1; + public float wavetime; + public boolean gameOver = false; + public GameMode mode = GameMode.waves; + public Difficulty difficulty = Difficulty.normal; + public boolean friendlyFire; + public WaveSpawner spawner = new WaveSpawner(); + public TeamInfo teams = new TeamInfo(); + private State state = State.menu; - public int wave = 1; - public float wavetime; - public boolean gameOver = false; - public GameMode mode = GameMode.waves; - public Difficulty difficulty = Difficulty.normal; - public boolean friendlyFire; - public WaveSpawner spawner = new WaveSpawner(); - public TeamInfo teams = new TeamInfo(); - - public void set(State astate){ - Events.fire(StateChangeEvent.class, state, astate); - state = astate; - } - - public boolean is(State astate){ - return state == astate; - } + public void set(State astate){ + Events.fire(StateChangeEvent.class, state, astate); + state = astate; + } - public State getState(){ - return state; - } - - public enum State{ - paused, playing, menu - } + public boolean is(State astate){ + return state == astate; + } + + public State getState(){ + return state; + } + + public enum State{ + paused, playing, menu + } } diff --git a/core/src/io/anuke/mindustry/core/Logic.java b/core/src/io/anuke/mindustry/core/Logic.java index d065be9098..2e07b0a2e6 100644 --- a/core/src/io/anuke/mindustry/core/Logic.java +++ b/core/src/io/anuke/mindustry/core/Logic.java @@ -24,13 +24,15 @@ import io.anuke.ucore.modules.Module; import static io.anuke.mindustry.Vars.*; -/**Logic module. +/** + * Logic module. * Handles all logic for entities and waves. * Handles game state events. * Does not store any game state itself. - * - * This class should not call any outside methods to change state of modules, but instead fire events.*/ -public class Logic extends Module { + *

+ * This class should not call any outside methods to change state of modules, but instead fire events. + */ +public class Logic extends Module{ public boolean doUpdate = true; public Logic(){ @@ -49,11 +51,11 @@ public class Logic extends Module { //fill inventory with items for debugging - for (TeamData team : state.teams.getTeams()) { - for (Tile tile : team.cores) { - if(debug) { - for (Item item : Item.all()) { - if (item.type == ItemType.material) { + for(TeamData team : state.teams.getTeams()){ + for(Tile tile : team.cores){ + if(debug){ + for(Item item : Item.all()){ + if(item.type == ItemType.material){ tile.entity.items.add(item, 1000); } } @@ -85,7 +87,7 @@ public class Logic extends Module { public void runWave(){ state.spawner.spawnEnemies(); - state.wave ++; + state.wave++; state.wavetime = wavespace * state.difficulty.timeScaling; Events.fire(WaveEvent.class); @@ -137,7 +139,8 @@ public class Logic extends Module { runWave(); } - if(!Entities.defaultGroup().isEmpty()) throw new RuntimeException("Do not add anything to the default group!"); + if(!Entities.defaultGroup().isEmpty()) + throw new RuntimeException("Do not add anything to the default group!"); Entities.update(bulletGroup); for(EntityGroup group : unitGroups){ diff --git a/core/src/io/anuke/mindustry/core/NetClient.java b/core/src/io/anuke/mindustry/core/NetClient.java index 5b820adf88..4ba984c6d3 100644 --- a/core/src/io/anuke/mindustry/core/NetClient.java +++ b/core/src/io/anuke/mindustry/core/NetClient.java @@ -36,38 +36,64 @@ import java.util.Random; import static io.anuke.mindustry.Vars.*; -public class NetClient extends Module { - private final static float dataTimeout = 60*18; +public class NetClient extends Module{ + private final static float dataTimeout = 60 * 18; private final static float playerSyncTime = 2; private Timer timer = new Timer(5); - /**Whether the client is currently connecting.*/ + /** + * Whether the client is currently connecting. + */ private boolean connecting = false; - /**If true, no message will be shown on disconnect.*/ + /** + * If true, no message will be shown on disconnect. + */ private boolean quiet = false; - /**Counter for data timeout.*/ + /** + * Counter for data timeout. + */ private float timeoutTime = 0f; - /**Last sent client snapshot ID.*/ + /** + * Last sent client snapshot ID. + */ private int lastSent; - /**Last snapshot ID recieved.*/ + /** + * Last snapshot ID recieved. + */ private int lastSnapshotBaseID = -1; - /**Last snapshot recieved.*/ + /** + * Last snapshot recieved. + */ private byte[] lastSnapshotBase; - /**Current snapshot that is being built from chinks.*/ + /** + * Current snapshot that is being built from chinks. + */ private byte[] currentSnapshot; - /**Array of recieved chunk statuses.*/ + /** + * Array of recieved chunk statuses. + */ private boolean[] recievedChunks; - /**Counter of how many chunks have been recieved.*/ + /** + * Counter of how many chunks have been recieved. + */ private int recievedChunkCounter; - /**ID of snapshot that is currently being constructed.*/ + /** + * ID of snapshot that is currently being constructed. + */ private int currentSnapshotID = -1; - /**Decoder for uncompressing snapshots.*/ + /** + * Decoder for uncompressing snapshots. + */ private DEZDecoder decoder = new DEZDecoder(); - /**List of entities that were removed, and need not be added while syncing.*/ + /** + * List of entities that were removed, and need not be added while syncing. + */ private IntSet removed = new IntSet(); - /**Byte stream for reading in snapshots.*/ + /** + * Byte stream for reading in snapshots. + */ private ReusableByteArrayInputStream byteStream = new ReusableByteArrayInputStream(); private DataInputStream dataStream = new DataInputStream(byteStream); @@ -120,7 +146,7 @@ public class NetClient extends Module { }); Net.handleClient(Disconnect.class, packet -> { - if (quiet) return; + if(quiet) return; Timers.runTask(3f, ui.loadfrag::hide); @@ -145,6 +171,166 @@ public class NetClient extends Module { }); } + @Remote(variants = Variant.one, priority = PacketPriority.high) + public static void onKick(KickReason reason){ + netClient.disconnectQuietly(); + state.set(State.menu); + if(!reason.quiet) ui.showError("$text.server.kicked." + reason.name()); + ui.loadfrag.hide(); + } + + @Remote(variants = Variant.one) + public static void onPositionSet(float x, float y){ + players[0].x = x; + players[0].y = y; + } + + @Remote(variants = Variant.one) + public static void onTraceInfo(TraceInfo info){ + Player player = playerGroup.getByID(info.playerid); + ui.traces.show(player, info); + } + + @Remote + public static void onPlayerDisconnect(int playerid){ + playerGroup.removeByID(playerid); + } + + @Remote(variants = Variant.one, priority = PacketPriority.low, unreliable = true) + public static void onSnapshot(byte[] chunk, int snapshotID, short chunkID, int totalLength, int base){ + if(NetServer.showSnapshotSize) + Log.info("Recieved snapshot: len {0} ID {1} chunkID {2} totalLength {3} base {4} client-base {5}", chunk.length, snapshotID, chunkID, totalLength, base, netClient.lastSnapshotBaseID); + + //skip snapshot IDs that have already been recieved OR snapshots that are too far in front + if(snapshotID < netClient.lastSnapshotBaseID || base != netClient.lastSnapshotBaseID){ + if(NetServer.showSnapshotSize) Log.info("//SKIP SNAPSHOT"); + return; + } + + try{ + byte[] snapshot; + + //total length exceeds that needed to hold one snapshot, therefore, it is split into chunks + if(totalLength > NetServer.maxSnapshotSize){ + //total amount of chunks to recieve + int totalChunks = Mathf.ceil((float) totalLength / NetServer.maxSnapshotSize); + + //reset status when a new snapshot sending begins + if(netClient.currentSnapshotID != snapshotID){ + netClient.currentSnapshotID = snapshotID; + netClient.currentSnapshot = new byte[totalLength]; + netClient.recievedChunkCounter = 0; + netClient.recievedChunks = new boolean[totalChunks]; + } + + //if this chunk hasn't been recieved yet... + if(!netClient.recievedChunks[chunkID]){ + netClient.recievedChunks[chunkID] = true; + netClient.recievedChunkCounter++; //update recieved status + //copy the recieved bytes into the holding array + System.arraycopy(chunk, 0, netClient.currentSnapshot, chunkID * NetServer.maxSnapshotSize, + Math.min(NetServer.maxSnapshotSize, totalLength - chunkID * NetServer.maxSnapshotSize)); + } + + //when all chunks have been recieved, begin + if(netClient.recievedChunkCounter >= totalChunks){ + snapshot = netClient.currentSnapshot; + }else{ + return; + } + }else{ + snapshot = chunk; + } + + if(NetServer.showSnapshotSize) + Log.info("Finished recieving snapshot ID {0} length {1}", snapshotID, chunk.length); + + byte[] result; + int length; + if(base == -1){ //fresh snapshot + result = snapshot; + length = snapshot.length; + netClient.lastSnapshotBase = Arrays.copyOf(snapshot, snapshot.length); + }else{ //otherwise, last snapshot must not be null, decode it + if(NetServer.showSnapshotSize) + Log.info("Base size: {0} Patch size: {1}", netClient.lastSnapshotBase.length, snapshot.length); + netClient.decoder.init(netClient.lastSnapshotBase, snapshot); + result = netClient.decoder.decode(); + length = netClient.decoder.getDecodedLength(); + //set last snapshot to a copy to prevent issues + netClient.lastSnapshotBase = Arrays.copyOf(result, length); + } + + netClient.lastSnapshotBaseID = snapshotID; + + //set stream bytes to begin snapshot reaeding + netClient.byteStream.setBytes(result, 0, length); + + //get data input for reading from the stream + DataInputStream input = netClient.dataStream; + + //read wave info + state.wavetime = input.readFloat(); + state.wave = input.readInt(); + + byte cores = input.readByte(); + for(int i = 0; i < cores; i++){ + int pos = input.readInt(); + world.tile(pos).entity.items.read(input); + } + + long timestamp = input.readLong(); + + byte totalGroups = input.readByte(); + //for each group... + for(int i = 0; i < totalGroups; i++){ + //read group info + byte groupID = input.readByte(); + short amount = input.readShort(); + + EntityGroup group = Entities.getGroup(groupID); + + //go through each entity + for(int j = 0; j < amount; j++){ + int position = netClient.byteStream.position(); //save position to check read/write correctness + int id = input.readInt(); + byte typeID = input.readByte(); + + SyncTrait entity = (SyncTrait) group.getByID(id); + boolean add = false; + + //entity must not be added yet, so create it + if(entity == null){ + entity = (SyncTrait) TypeTrait.getTypeByID(typeID).get(); //create entity from supplier + entity.resetID(id); + if(!netClient.isEntityUsed(entity.getID())){ + add = true; + } + } + + //read the entity + entity.read(input, timestamp); + + byte readLength = input.readByte(); + if(netClient.byteStream.position() - position - 1 != readLength){ + throw new RuntimeException("Error reading entity of type '" + group.getType() + "': Read length mismatch [write=" + readLength + ", read=" + (netClient.byteStream.position() - position - 1) + "]"); + } + + if(add){ + entity.add(); + netClient.addRemovedEntity(entity.getID()); + } + } + } + + //confirm that snapshot has been recieved + netClient.lastSnapshotBaseID = snapshotID; + + }catch(Exception e){ + throw new RuntimeException(e); + } + } + @Override public void update(){ if(!Net.client()) return; @@ -224,161 +410,4 @@ public class NetClient extends Module { return result; } } - - @Remote(variants = Variant.one, priority = PacketPriority.high) - public static void onKick(KickReason reason){ - netClient.disconnectQuietly(); - state.set(State.menu); - if(!reason.quiet) ui.showError("$text.server.kicked." + reason.name()); - ui.loadfrag.hide(); - } - - @Remote(variants = Variant.one) - public static void onPositionSet(float x, float y){ - players[0].x = x; - players[0].y = y; - } - - @Remote(variants = Variant.one) - public static void onTraceInfo(TraceInfo info){ - Player player = playerGroup.getByID(info.playerid); - ui.traces.show(player, info); - } - - @Remote - public static void onPlayerDisconnect(int playerid){ - playerGroup.removeByID(playerid); - } - - @Remote(variants = Variant.one, priority = PacketPriority.low, unreliable = true) - public static void onSnapshot(byte[] chunk, int snapshotID, short chunkID, int totalLength, int base){ - if(NetServer.showSnapshotSize) Log.info("Recieved snapshot: len {0} ID {1} chunkID {2} totalLength {3} base {4} client-base {5}", chunk.length, snapshotID, chunkID, totalLength, base, netClient.lastSnapshotBaseID); - - //skip snapshot IDs that have already been recieved OR snapshots that are too far in front - if(snapshotID < netClient.lastSnapshotBaseID || base != netClient.lastSnapshotBaseID){ - if(NetServer.showSnapshotSize) Log.info("//SKIP SNAPSHOT"); - return; - } - - try { - byte[] snapshot; - - //total length exceeds that needed to hold one snapshot, therefore, it is split into chunks - if(totalLength > NetServer.maxSnapshotSize) { - //total amount of chunks to recieve - int totalChunks = Mathf.ceil((float) totalLength / NetServer.maxSnapshotSize); - - //reset status when a new snapshot sending begins - if (netClient.currentSnapshotID != snapshotID) { - netClient.currentSnapshotID = snapshotID; - netClient.currentSnapshot = new byte[totalLength]; - netClient.recievedChunkCounter = 0; - netClient.recievedChunks = new boolean[totalChunks]; - } - - //if this chunk hasn't been recieved yet... - if (!netClient.recievedChunks[chunkID]) { - netClient.recievedChunks[chunkID] = true; - netClient.recievedChunkCounter ++; //update recieved status - //copy the recieved bytes into the holding array - System.arraycopy(chunk, 0, netClient.currentSnapshot, chunkID * NetServer.maxSnapshotSize, - Math.min(NetServer.maxSnapshotSize, totalLength - chunkID * NetServer.maxSnapshotSize)); - } - - //when all chunks have been recieved, begin - if(netClient.recievedChunkCounter >= totalChunks){ - snapshot = netClient.currentSnapshot; - }else{ - return; - } - }else{ - snapshot = chunk; - } - - if(NetServer.showSnapshotSize) Log.info("Finished recieving snapshot ID {0} length {1}", snapshotID, chunk.length); - - byte[] result; - int length; - if (base == -1) { //fresh snapshot - result = snapshot; - length = snapshot.length; - netClient.lastSnapshotBase = Arrays.copyOf(snapshot, snapshot.length); - } else { //otherwise, last snapshot must not be null, decode it - if(NetServer.showSnapshotSize) Log.info("Base size: {0} Patch size: {1}", netClient.lastSnapshotBase.length, snapshot.length); - netClient.decoder.init(netClient.lastSnapshotBase, snapshot); - result = netClient.decoder.decode(); - length = netClient.decoder.getDecodedLength(); - //set last snapshot to a copy to prevent issues - netClient.lastSnapshotBase = Arrays.copyOf(result, length); - } - - netClient.lastSnapshotBaseID = snapshotID; - - //set stream bytes to begin snapshot reaeding - netClient.byteStream.setBytes(result, 0, length); - - //get data input for reading from the stream - DataInputStream input = netClient.dataStream; - - //read wave info - state.wavetime = input.readFloat(); - state.wave = input.readInt(); - - byte cores = input.readByte(); - for (int i = 0; i < cores; i++) { - int pos = input.readInt(); - world.tile(pos).entity.items.read(input); - } - - long timestamp = input.readLong(); - - byte totalGroups = input.readByte(); - //for each group... - for (int i = 0; i < totalGroups; i++) { - //read group info - byte groupID = input.readByte(); - short amount = input.readShort(); - - EntityGroup group = Entities.getGroup(groupID); - - //go through each entity - for (int j = 0; j < amount; j++) { - int position = netClient.byteStream.position(); //save position to check read/write correctness - int id = input.readInt(); - byte typeID = input.readByte(); - - SyncTrait entity = (SyncTrait) group.getByID(id); - boolean add = false; - - //entity must not be added yet, so create it - if(entity == null){ - entity = (SyncTrait) TypeTrait.getTypeByID(typeID).get(); //create entity from supplier - entity.resetID(id); - if(!netClient.isEntityUsed(entity.getID())){ - add = true; - } - } - - //read the entity - entity.read(input, timestamp); - - byte readLength = input.readByte(); - if(netClient.byteStream.position() - position - 1 != readLength){ - throw new RuntimeException("Error reading entity of type '"+ group.getType() + "': Read length mismatch [write=" + readLength + ", read=" + (netClient.byteStream.position() - position - 1)+ "]"); - } - - if(add){ - entity.add(); - netClient.addRemovedEntity(entity.getID()); - } - } - } - - //confirm that snapshot has been recieved - netClient.lastSnapshotBaseID = snapshotID; - - }catch (Exception e){ - throw new RuntimeException(e); - } - } } \ No newline at end of file diff --git a/core/src/io/anuke/mindustry/core/NetServer.java b/core/src/io/anuke/mindustry/core/NetServer.java index 2abffd3abf..fa2c5ac999 100644 --- a/core/src/io/anuke/mindustry/core/NetServer.java +++ b/core/src/io/anuke/mindustry/core/NetServer.java @@ -45,20 +45,30 @@ public class NetServer extends Module{ private final static byte[] reusableSnapArray = new byte[maxSnapshotSize]; private final static float serverSyncTime = 4, kickDuration = 30 * 1000; private final static Vector2 vector = new Vector2(); - /**If a play goes away of their server-side coordinates by this distance, they get teleported back.*/ + /** + * If a play goes away of their server-side coordinates by this distance, they get teleported back. + */ private final static float correctDist = 16f; public final Administration admins = new Administration(); - /**Maps connection IDs to players.*/ + /** + * Maps connection IDs to players. + */ private IntMap connections = new IntMap<>(); private boolean closing = false; - /**Stream for writing player sync data to.*/ + /** + * Stream for writing player sync data to. + */ private CountableByteArrayOutputStream syncStream = new CountableByteArrayOutputStream(); - /**Data stream for writing player sync data to.*/ + /** + * Data stream for writing player sync data to. + */ private DataOutputStream dataStream = new DataOutputStream(syncStream); - /**Encoder for computing snapshot deltas.*/ + /** + * Encoder for computing snapshot deltas. + */ private DEZEncoder encoder = new DEZEncoder(); public NetServer(){ @@ -105,14 +115,14 @@ public class NetServer extends Module{ boolean preventDuplicates = headless; - if(preventDuplicates) { - for (Player player : playerGroup.all()) { - if (player.name.equalsIgnoreCase(packet.name)) { + if(preventDuplicates){ + for(Player player : playerGroup.all()){ + if(player.name.equalsIgnoreCase(packet.name)){ kick(id, KickReason.nameInUse); return; } - if (player.uuid.equals(packet.uuid)) { + if(player.uuid.equals(packet.uuid)){ kick(id, KickReason.idInUse); return; } @@ -181,7 +191,7 @@ public class NetServer extends Module{ long elapsed = TimeUtils.timeSinceMillis(connection.lastRecievedClientTime); - float maxSpeed = (packet.boosting && !player.mech.flying ? player.mech.boostSpeed : player.mech.speed)*2.5f; + float maxSpeed = (packet.boosting && !player.mech.flying ? player.mech.boostSpeed : player.mech.speed) * 2.5f; //extra 1.1x multiplicaton is added just in case float maxMove = elapsed / 1000f * 60f * maxSpeed * 1.1f; @@ -238,6 +248,86 @@ public class NetServer extends Module{ }); } + /** + * Sends a raw byte[] snapshot to a client, splitting up into chunks when needed. + */ + private static void sendSplitSnapshot(int userid, byte[] bytes, int snapshotID, int base){ + if(bytes.length < maxSnapshotSize){ + Call.onSnapshot(userid, bytes, snapshotID, (short) 0, bytes.length, base); + }else{ + int remaining = bytes.length; + int offset = 0; + int chunkid = 0; + while(remaining > 0){ + int used = Math.min(remaining, maxSnapshotSize); + byte[] toSend; + //re-use sent byte arrays when possible + if(used == maxSnapshotSize){ + toSend = reusableSnapArray; + System.arraycopy(bytes, offset, toSend, 0, Math.min(offset + maxSnapshotSize, bytes.length) - offset); + }else{ + toSend = Arrays.copyOfRange(bytes, offset, Math.min(offset + maxSnapshotSize, bytes.length)); + } + Call.onSnapshot(userid, toSend, snapshotID, (short) chunkid, bytes.length, base); + + remaining -= used; + offset += used; + chunkid++; + } + } + } + + public static void onDisconnect(Player player){ + Call.sendMessage("[accent]" + player.name + " has disconnected."); + Call.onPlayerDisconnect(player.id); + player.remove(); + netServer.connections.remove(player.con.id); + } + + @Remote(targets = Loc.client, called = Loc.server) + public static void onAdminRequest(Player player, Player other, AdminAction action){ + + if(!player.isAdmin){ + Log.err("ACCESS DENIED: Player {0} / {1} attempted to perform admin action without proper security access.", + player.name, player.con.address); + return; + } + + if(other == null || (other.isAdmin && other != player)){ //fun fact: this means you can ban yourself + Log.err("{0} attempted to perform admin action on nonexistant or admin player.", player.name); + return; + } + + if(action == AdminAction.wave){ + //no verification is done, so admins can hypothetically spam waves + //not a real issue, because server owners may want to do just that + state.wavetime = 0f; + }else if(action == AdminAction.ban){ + netServer.admins.banPlayerIP(other.con.address); + netServer.kick(other.con.id, KickReason.banned); + Log.info("&lc{0} has banned {1}.", player.name, other.name); + }else if(action == AdminAction.kick){ + netServer.kick(other.con.id, KickReason.kick); + Log.info("&lc{0} has kicked {1}.", player.name, other.name); + }else if(action == AdminAction.trace){ + //TODO + if(player.con != null){ + Call.onTraceInfo(player.con.id, netServer.admins.getTraceByID(other.uuid)); + }else{ + NetClient.onTraceInfo(netServer.admins.getTraceByID(other.uuid)); + } + Log.info("&lc{0} has requested trace info of {1}.", player.name, other.name); + } + } + + @Remote(targets = Loc.client) + public static void connectConfirm(Player player){ + player.add(); + player.con.hasConnected = true; + Call.sendMessage("[accent]" + player.name + " has connected."); + Log.info("&y{0} has connected.", player.name); + } + public void update(){ if(!headless && !closing && Net.server() && state.is(State.menu)){ closing = true; @@ -270,7 +360,7 @@ public class NetServer extends Module{ if((reason == KickReason.kick || reason == KickReason.banned) && admins.getTraceByID(getUUID(con.id)).uuid != null){ PlayerInfo info = admins.getInfo(admins.getTraceByID(getUUID(con.id)).uuid); - info.timesKicked ++; + info.timesKicked++; info.lastKicked = TimeUtils.millis(); } @@ -288,7 +378,7 @@ public class NetServer extends Module{ String fixName(String name){ - for(int i = 0; i < name.length(); i ++){ + for(int i = 0; i < name.length(); i++){ if(name.charAt(i) == '[' && i != name.length() - 1 && name.charAt(i + 1) != '[' && (i == 0 || name.charAt(i - 1) != '[')){ String prev = name.substring(0, i); String next = name.substring(i); @@ -303,7 +393,7 @@ public class NetServer extends Module{ String checkColor(String str){ - for(int i = 1; i < str.length(); i ++){ + for(int i = 1; i < str.length(); i++){ if(str.charAt(i) == ']'){ String color = str.substring(1, i); @@ -318,7 +408,7 @@ public class NetServer extends Module{ if(result.a <= 0.8f){ return str.substring(i + 1); } - }catch (Exception e){ + }catch(Exception e){ return str; } } @@ -328,10 +418,10 @@ public class NetServer extends Module{ } void sync(){ - try { + try{ //iterate through each player - for (Player player : connections.values()) { + for(Player player : connections.values()){ NetConnection connection = player.con; if(!connection.isConnected()){ @@ -344,7 +434,8 @@ public class NetServer extends Module{ //if the player hasn't acknowledged that it has recieved the packet, send the same thing again if(connection.currentBaseID < connection.lastSentSnapshotID){ - if(showSnapshotSize) Log.info("Re-sending snapshot: {0} bytes, ID {1} base {2} baselength {3}", connection.lastSentSnapshot.length, connection.lastSentSnapshotID, connection.lastSentBase, connection.currentBaseSnapshot.length); + if(showSnapshotSize) + Log.info("Re-sending snapshot: {0} bytes, ID {1} base {2} baselength {3}", connection.lastSentSnapshot.length, connection.lastSentSnapshotID, connection.lastSentBase, connection.currentBaseSnapshot.length); sendSplitSnapshot(connection.id, connection.lastSentSnapshot, connection.lastSentSnapshotID, connection.lastSentBase); return; } @@ -371,17 +462,17 @@ public class NetServer extends Module{ int totalGroups = 0; - for (EntityGroup group : Entities.getAllGroups()) { - if (!group.isEmpty() && (group.all().get(0) instanceof SyncTrait)) totalGroups ++; + for(EntityGroup group : Entities.getAllGroups()){ + if(!group.isEmpty() && (group.all().get(0) instanceof SyncTrait)) totalGroups++; } //write total amount of serializable groups dataStream.writeByte(totalGroups); //check for syncable groups - for (EntityGroup group : Entities.getAllGroups()) { + for(EntityGroup group : Entities.getAllGroups()){ //TODO range-check sync positions to optimize? - if (group.isEmpty() || !(group.all().get(0) instanceof SyncTrait)) continue; + if(group.isEmpty() || !(group.all().get(0) instanceof SyncTrait)) continue; //make sure mapping is enabled for this group if(!group.mappingEnabled()){ @@ -391,8 +482,8 @@ public class NetServer extends Module{ int amount = 0; for(Entity entity : group.all()){ - if(((SyncTrait)entity).isSyncing()){ - amount ++; + if(((SyncTrait) entity).isSyncing()){ + amount++; } } @@ -401,15 +492,16 @@ public class NetServer extends Module{ dataStream.writeShort(amount); for(Entity entity : group.all()){ - if(!((SyncTrait)entity).isSyncing()) continue; + if(!((SyncTrait) entity).isSyncing()) continue; int position = syncStream.position(); //write all entities now dataStream.writeInt(entity.getID()); //write id - dataStream.writeByte(((SyncTrait)entity).getTypeID()); //write type ID - ((SyncTrait)entity).write(dataStream); //write entity + dataStream.writeByte(((SyncTrait) entity).getTypeID()); //write type ID + ((SyncTrait) entity).write(dataStream); //write entity int length = syncStream.position() - position; //length must always be less than 127 bytes - if(length > 127) throw new RuntimeException("Write size for entity of type " + group.getType() + " must not exceed 127!"); + if(length > 127) + throw new RuntimeException("Write size for entity of type " + group.getType() + " must not exceed 127!"); dataStream.writeByte(length); } } @@ -433,7 +525,8 @@ public class NetServer extends Module{ //send diff, otherwise byte[] diff = ByteDeltaEncoder.toDiff(new ByteMatcherHash(connection.currentBaseSnapshot, bytes), encoder); - if(showSnapshotSize) Log.info("Shrank snapshot: {0} -> {1}, Base {2} ID {3} base length = {4}", bytes.length, diff.length, connection.currentBaseID, connection.currentBaseID + 1, connection.currentBaseSnapshot.length); + if(showSnapshotSize) + Log.info("Shrank snapshot: {0} -> {1}, Base {2} ID {3} base length = {4}", bytes.length, diff.length, connection.currentBaseID, connection.currentBaseID + 1, connection.currentBaseSnapshot.length); sendSplitSnapshot(connection.id, diff, connection.currentBaseID + 1, connection.currentBaseID); connection.lastSentSnapshot = diff; connection.lastSentSnapshotID = connection.currentBaseID + 1; @@ -441,86 +534,8 @@ public class NetServer extends Module{ } } - }catch (IOException e){ + }catch(IOException e){ e.printStackTrace(); } } - - /**Sends a raw byte[] snapshot to a client, splitting up into chunks when needed.*/ - private static void sendSplitSnapshot(int userid, byte[] bytes, int snapshotID, int base){ - if(bytes.length < maxSnapshotSize){ - Call.onSnapshot(userid, bytes, snapshotID, (short)0, bytes.length, base); - }else{ - int remaining = bytes.length; - int offset = 0; - int chunkid = 0; - while(remaining > 0){ - int used = Math.min(remaining, maxSnapshotSize); - byte[] toSend; - //re-use sent byte arrays when possible - if(used == maxSnapshotSize){ - toSend = reusableSnapArray; - System.arraycopy(bytes, offset, toSend, 0, Math.min(offset + maxSnapshotSize, bytes.length) - offset); - }else { - toSend = Arrays.copyOfRange(bytes, offset, Math.min(offset + maxSnapshotSize, bytes.length)); - } - Call.onSnapshot(userid, toSend, snapshotID, (short)chunkid, bytes.length, base); - - remaining -= used; - offset += used; - chunkid ++; - } - } - } - - public static void onDisconnect(Player player){ - Call.sendMessage("[accent]" + player.name + " has disconnected."); - Call.onPlayerDisconnect(player.id); - player.remove(); - netServer.connections.remove(player.con.id); - } - - @Remote(targets = Loc.client, called = Loc.server) - public static void onAdminRequest(Player player, Player other, AdminAction action){ - - if(!player.isAdmin){ - Log.err("ACCESS DENIED: Player {0} / {1} attempted to perform admin action without proper security access.", - player.name, player.con.address); - return; - } - - if(other == null || (other.isAdmin && other != player)){ //fun fact: this means you can ban yourself - Log.err("{0} attempted to perform admin action on nonexistant or admin player.", player.name); - return; - } - - if(action == AdminAction.wave) { - //no verification is done, so admins can hypothetically spam waves - //not a real issue, because server owners may want to do just that - state.wavetime = 0f; - }else if(action == AdminAction.ban){ - netServer.admins.banPlayerIP(other.con.address); - netServer.kick(other.con.id, KickReason.banned); - Log.info("&lc{0} has banned {1}.", player.name, other.name); - }else if(action == AdminAction.kick){ - netServer.kick(other.con.id, KickReason.kick); - Log.info("&lc{0} has kicked {1}.", player.name, other.name); - }else if(action == AdminAction.trace){ - //TODO - if(player.con != null) { - Call.onTraceInfo(player.con.id, netServer.admins.getTraceByID(other.uuid)); - }else{ - NetClient.onTraceInfo(netServer.admins.getTraceByID(other.uuid)); - } - Log.info("&lc{0} has requested trace info of {1}.", player.name, other.name); - } - } - - @Remote(targets = Loc.client) - public static void connectConfirm(Player player){ - player.add(); - player.con.hasConnected = true; - Call.sendMessage("[accent]" + player.name + " has connected."); - Log.info("&y{0} has connected.", player.name); - } } diff --git a/core/src/io/anuke/mindustry/core/Platform.java b/core/src/io/anuke/mindustry/core/Platform.java index c4064fd5fb..7462ba3eb2 100644 --- a/core/src/io/anuke/mindustry/core/Platform.java +++ b/core/src/io/anuke/mindustry/core/Platform.java @@ -11,63 +11,129 @@ import java.util.Date; import java.util.Locale; import java.util.Random; -public abstract class Platform { - /**Each separate game platform should set this instance to their own implementation.*/ - public static Platform instance = new Platform() {}; +public abstract class Platform{ + /** + * Each separate game platform should set this instance to their own implementation. + */ + public static Platform instance = new Platform(){ + }; - /**Format the date using the default date formatter.*/ - public String format(Date date){return "invalid";} - /**Format a number by adding in commas or periods where needed.*/ - public String format(int number){return "invalid";} - /**Show a native error dialog.*/ - public void showError(String text){} - /**Add a text input dialog that should show up after the field is tapped.*/ - public void addDialog(TextField field){ - addDialog(field, 16); - } - /**See addDialog().*/ - public void addDialog(TextField field, int maxLength){} - /**Update discord RPC.*/ - public void updateRPC(){} - /**Called when the game is exited.*/ - public void onGameExit(){} - /**Open donation dialog. Currently android only.*/ - public void openDonations(){} - /**Whether donating is supported.*/ - public boolean canDonate(){ - return false; - } - /**Whether discord RPC is supported.*/ - public boolean hasDiscord(){return true;} - /**Return the localized name for the locale. This is basically a workaround for GWT not supporting getName().*/ - public String getLocaleName(Locale locale){ - return locale.toString(); - } - /**Whether joining games is supported.*/ - public boolean canJoinGame(){ - return true; - } - /**Whether debug mode is enabled.*/ - public boolean isDebug(){return false;} - /**Must be a base64 string 8 bytes in length.*/ - public String getUUID(){ - String uuid = Settings.getString("uuid", ""); - if(uuid.isEmpty()){ - byte[] result = new byte[8]; - new Random().nextBytes(result); - uuid = new String(Base64Coder.encode(result)); - Settings.putString("uuid", uuid); - Settings.save(); - return uuid; - } - return uuid; - } - /**Only used for iOS or android: open the share menu for a map or save.*/ - public void shareFile(FileHandle file){} - /**Download a file. Only used on GWT backend.*/ - public void downloadFile(String name, byte[] bytes){} + /** + * Format the date using the default date formatter. + */ + public String format(Date date){ + return "invalid"; + } - /**Show a file chooser. Desktop only. + /** + * Format a number by adding in commas or periods where needed. + */ + public String format(int number){ + return "invalid"; + } + + /** + * Show a native error dialog. + */ + public void showError(String text){ + } + + /** + * Add a text input dialog that should show up after the field is tapped. + */ + public void addDialog(TextField field){ + addDialog(field, 16); + } + + /** + * See addDialog(). + */ + public void addDialog(TextField field, int maxLength){ + } + + /** + * Update discord RPC. + */ + public void updateRPC(){ + } + + /** + * Called when the game is exited. + */ + public void onGameExit(){ + } + + /** + * Open donation dialog. Currently android only. + */ + public void openDonations(){ + } + + /** + * Whether donating is supported. + */ + public boolean canDonate(){ + return false; + } + + /** + * Whether discord RPC is supported. + */ + public boolean hasDiscord(){ + return true; + } + + /** + * Return the localized name for the locale. This is basically a workaround for GWT not supporting getName(). + */ + public String getLocaleName(Locale locale){ + return locale.toString(); + } + + /** + * Whether joining games is supported. + */ + public boolean canJoinGame(){ + return true; + } + + /** + * Whether debug mode is enabled. + */ + public boolean isDebug(){ + return false; + } + + /** + * Must be a base64 string 8 bytes in length. + */ + public String getUUID(){ + String uuid = Settings.getString("uuid", ""); + if(uuid.isEmpty()){ + byte[] result = new byte[8]; + new Random().nextBytes(result); + uuid = new String(Base64Coder.encode(result)); + Settings.putString("uuid", uuid); + Settings.save(); + return uuid; + } + return uuid; + } + + /** + * Only used for iOS or android: open the share menu for a map or save. + */ + public void shareFile(FileHandle file){ + } + + /** + * Download a file. Only used on GWT backend. + */ + public void downloadFile(String name, byte[] bytes){ + } + + /** + * Show a file chooser. Desktop only. * * @param text File chooser title text * @param content Description of the type of files to be loaded @@ -75,24 +141,54 @@ public abstract class Platform { * @param open Whether to open or save files * @param filetype File extension to filter */ - public void showFileChooser(String text, String content, Consumer cons, boolean open, String filetype){} - /**Use the default thread provider from the kryonet module for this.*/ - public ThreadProvider getThreadProvider(){ - return new ThreadProvider() { - @Override public boolean isOnThread() {return true;} - @Override public void sleep(long ms) {} - @Override public void start(Runnable run) {} - @Override public void stop() {} - @Override public void notify(Object object) {} - @Override public void wait(Object object) {} - }; - } + public void showFileChooser(String text, String content, Consumer cons, boolean open, String filetype){ + } - //TODO iOS implementation - /**Forces the app into landscape mode. Currently Android only.*/ - public void beginForceLandscape(){} + /** + * Use the default thread provider from the kryonet module for this. + */ + public ThreadProvider getThreadProvider(){ + return new ThreadProvider(){ + @Override + public boolean isOnThread(){ + return true; + } - //TODO iOS implementation - /**Stops forcing the app into landscape orientation. Currently Android only.*/ - public void endForceLandscape(){} + @Override + public void sleep(long ms){ + } + + @Override + public void start(Runnable run){ + } + + @Override + public void stop(){ + } + + @Override + public void notify(Object object){ + } + + @Override + public void wait(Object object){ + } + }; + } + + //TODO iOS implementation + + /** + * Forces the app into landscape mode. Currently Android only. + */ + public void beginForceLandscape(){ + } + + //TODO iOS implementation + + /** + * Stops forcing the app into landscape orientation. Currently Android only. + */ + public void endForceLandscape(){ + } } diff --git a/core/src/io/anuke/mindustry/core/Renderer.java b/core/src/io/anuke/mindustry/core/Renderer.java index 095fac27d5..29ddc9762a 100644 --- a/core/src/io/anuke/mindustry/core/Renderer.java +++ b/core/src/io/anuke/mindustry/core/Renderer.java @@ -47,429 +47,429 @@ import static io.anuke.ucore.core.Core.batch; import static io.anuke.ucore.core.Core.camera; public class Renderer extends RendererModule{ - public Surface effectSurface; - - private int targetscale = baseCameraScale; - private Texture background = new Texture("sprites/background.png"); + public Surface effectSurface; - private Rectangle rect = new Rectangle(), rect2 = new Rectangle(); - private Vector2 avgPosition = new Translator(); - private Vector2 tmpVector1 = new Translator(); - private Vector2 tmpVector2 = new Translator(); + private int targetscale = baseCameraScale; + private Texture background = new Texture("sprites/background.png"); - private BlockRenderer blocks = new BlockRenderer(); - private MinimapRenderer minimap = new MinimapRenderer(); - private OverlayRenderer overlays = new OverlayRenderer(); - private FogRenderer fog = new FogRenderer(); + private Rectangle rect = new Rectangle(), rect2 = new Rectangle(); + private Vector2 avgPosition = new Translator(); + private Vector2 tmpVector1 = new Translator(); + private Vector2 tmpVector2 = new Translator(); - public Renderer() { - pixelate = true; - Lines.setCircleVertices(14); + private BlockRenderer blocks = new BlockRenderer(); + private MinimapRenderer minimap = new MinimapRenderer(); + private OverlayRenderer overlays = new OverlayRenderer(); + private FogRenderer fog = new FogRenderer(); - Shaders.init(); + public Renderer(){ + pixelate = true; + Lines.setCircleVertices(14); - Core.cameraScale = baseCameraScale; - Effects.setEffectProvider((effect, color, x, y, rotation, data) -> { - if(effect == Fx.none) return; - if(Settings.getBool("effects")){ - Rectangle view = rect.setSize(camera.viewportWidth, camera.viewportHeight) - .setCenter(camera.position.x, camera.position.y); - Rectangle pos = rect2.setSize(effect.size).setCenter(x, y); + Shaders.init(); - if(view.overlaps(pos)){ + Core.cameraScale = baseCameraScale; + Effects.setEffectProvider((effect, color, x, y, rotation, data) -> { + if(effect == Fx.none) return; + if(Settings.getBool("effects")){ + Rectangle view = rect.setSize(camera.viewportWidth, camera.viewportHeight) + .setCenter(camera.position.x, camera.position.y); + Rectangle pos = rect2.setSize(effect.size).setCenter(x, y); - if(!(effect instanceof GroundEffect)) { - EffectEntity entity = Pooling.obtain(EffectEntity.class); - entity.effect = effect; - entity.color = color; - entity.rotation = rotation; - entity.data = data; - entity.id ++; - entity.set(x, y); - if(data instanceof BaseEntity){ - entity.setParent((BaseEntity)data); - } - threads.runGraphics(() -> effectGroup.add(entity)); - }else{ - GroundEffectEntity entity = Pooling.obtain(GroundEffectEntity.class); - entity.effect = effect; - entity.color = color; - entity.rotation = rotation; - entity.id ++; - entity.data = data; - entity.set(x, y); - threads.runGraphics(() -> groundEffectGroup.add(entity)); - } - } - } - }); + if(view.overlaps(pos)){ - Cursors.cursorScaling = 3; - Cursors.outlineColor = Color.valueOf("444444"); + if(!(effect instanceof GroundEffect)){ + EffectEntity entity = Pooling.obtain(EffectEntity.class); + entity.effect = effect; + entity.color = color; + entity.rotation = rotation; + entity.data = data; + entity.id++; + entity.set(x, y); + if(data instanceof BaseEntity){ + entity.setParent((BaseEntity) data); + } + threads.runGraphics(() -> effectGroup.add(entity)); + }else{ + GroundEffectEntity entity = Pooling.obtain(GroundEffectEntity.class); + entity.effect = effect; + entity.color = color; + entity.rotation = rotation; + entity.id++; + entity.data = data; + entity.set(x, y); + threads.runGraphics(() -> groundEffectGroup.add(entity)); + } + } + } + }); - Cursors.arrow = Cursors.loadCursor("cursor"); - Cursors.hand = Cursors.loadCursor("hand"); - Cursors.ibeam = Cursors.loadCursor("ibar"); - Cursors.loadCustom("drill"); - Cursors.loadCustom("unload"); + Cursors.cursorScaling = 3; + Cursors.outlineColor = Color.valueOf("444444"); - clearColor = Hue.lightness(0.4f); - clearColor.a = 1f; + Cursors.arrow = Cursors.loadCursor("cursor"); + Cursors.hand = Cursors.loadCursor("hand"); + Cursors.ibeam = Cursors.loadCursor("ibar"); + Cursors.loadCustom("drill"); + Cursors.loadCustom("unload"); - background.setWrap(TextureWrap.Repeat, TextureWrap.Repeat); - } + clearColor = Hue.lightness(0.4f); + clearColor.a = 1f; - @Override - public void init(){ - int scale = Core.cameraScale; + background.setWrap(TextureWrap.Repeat, TextureWrap.Repeat); + } + + @Override + public void init(){ + int scale = Core.cameraScale; effectSurface = Graphics.createSurface(scale); - pixelSurface = Graphics.createSurface(scale); - } + pixelSurface = Graphics.createSurface(scale); + } - @Override - public void update(){ + @Override + public void update(){ - if(Core.cameraScale != targetscale){ - float targetzoom = (float) Core.cameraScale / targetscale; - camera.zoom = Mathf.lerpDelta(camera.zoom, targetzoom, 0.2f); + if(Core.cameraScale != targetscale){ + float targetzoom = (float) Core.cameraScale / targetscale; + camera.zoom = Mathf.lerpDelta(camera.zoom, targetzoom, 0.2f); - if(Mathf.in(camera.zoom, targetzoom, 0.005f)){ - camera.zoom = 1f; - Graphics.setCameraScale(targetscale); - for(Player player : players) { + if(Mathf.in(camera.zoom, targetzoom, 0.005f)){ + camera.zoom = 1f; + Graphics.setCameraScale(targetscale); + for(Player player : players){ control.input(player.playerIndex).resetCursor(); } - } - }else{ - camera.zoom = Mathf.lerpDelta(camera.zoom, 1f, 0.2f); - } + } + }else{ + camera.zoom = Mathf.lerpDelta(camera.zoom, 1f, 0.2f); + } - if(state.is(State.menu)){ - Graphics.clear(Color.BLACK); - }else{ + if(state.is(State.menu)){ + Graphics.clear(Color.BLACK); + }else{ Vector2 position = averagePosition(); if(!mobile){ - setCamera(position.x + 0.0001f, position.y + 0.0001f); - } + setCamera(position.x + 0.0001f, position.y + 0.0001f); + } - clampCamera(-tilesize / 2f, -tilesize / 2f + 1, world.width() * tilesize - tilesize / 2f, world.height() * tilesize - tilesize / 2f); + clampCamera(-tilesize / 2f, -tilesize / 2f + 1, world.width() * tilesize - tilesize / 2f, world.height() * tilesize - tilesize / 2f); - float prex = camera.position.x, prey = camera.position.y; - updateShake(0.75f); + float prex = camera.position.x, prey = camera.position.y; + updateShake(0.75f); - float deltax = camera.position.x - prex, deltay = camera.position.y - prey; - float lastx = camera.position.x, lasty = camera.position.y; - - if(snapCamera){ - camera.position.set((int) camera.position.x, (int) camera.position.y, 0); - } - - if(Gdx.graphics.getHeight() / Core.cameraScale % 2 == 1){ - camera.position.add(0, -0.5f, 0); - } + float deltax = camera.position.x - prex, deltay = camera.position.y - prey; + float lastx = camera.position.x, lasty = camera.position.y; - if(Gdx.graphics.getWidth() / Core.cameraScale % 2 == 1){ - camera.position.add(-0.5f, 0, 0); - } - - draw(); + if(snapCamera){ + camera.position.set((int) camera.position.x, (int) camera.position.y, 0); + } - camera.position.set(lastx - deltax, lasty - deltay, 0); - } + if(Gdx.graphics.getHeight() / Core.cameraScale % 2 == 1){ + camera.position.add(0, -0.5f, 0); + } - if(debug && !ui.chatfrag.chatOpen()) { - renderer.record(); //this only does something if GdxGifRecorder is on the class path, which it usually isn't - } - } + if(Gdx.graphics.getWidth() / Core.cameraScale % 2 == 1){ + camera.position.add(-0.5f, 0, 0); + } - @Override - public void draw(){ - camera.update(); + draw(); - Graphics.clear(clearColor); - - batch.setProjectionMatrix(camera.combined); + camera.position.set(lastx - deltax, lasty - deltay, 0); + } - Graphics.surface(pixelSurface, false); + if(debug && !ui.chatfrag.chatOpen()){ + renderer.record(); //this only does something if GdxGifRecorder is on the class path, which it usually isn't + } + } - drawPadding(); - - blocks.drawFloor(); + @Override + public void draw(){ + camera.update(); - drawAndInterpolate(groundEffectGroup, e -> e instanceof BelowLiquidTrait); - drawAndInterpolate(puddleGroup); - drawAndInterpolate(groundEffectGroup, e -> !(e instanceof BelowLiquidTrait)); + Graphics.clear(clearColor); - blocks.processBlocks(); - blocks.drawBlocks(Layer.block); + batch.setProjectionMatrix(camera.combined); - Graphics.shader(Shaders.blockbuild, false); + Graphics.surface(pixelSurface, false); + + drawPadding(); + + blocks.drawFloor(); + + drawAndInterpolate(groundEffectGroup, e -> e instanceof BelowLiquidTrait); + drawAndInterpolate(puddleGroup); + drawAndInterpolate(groundEffectGroup, e -> !(e instanceof BelowLiquidTrait)); + + blocks.processBlocks(); + blocks.drawBlocks(Layer.block); + + Graphics.shader(Shaders.blockbuild, false); blocks.drawBlocks(Layer.placement); Graphics.shader(); blocks.drawBlocks(Layer.overlay); if(itemGroup.size() > 0){ - Shaders.outline.color.set(Team.none.color); + Shaders.outline.color.set(Team.none.color); - Graphics.beginShaders(Shaders.outline); - drawAndInterpolate(itemGroup); - Graphics.endShaders(); - } + Graphics.beginShaders(Shaders.outline); + drawAndInterpolate(itemGroup); + Graphics.endShaders(); + } drawAllTeams(false); - blocks.skipLayer(Layer.turret); - blocks.drawBlocks(Layer.laser); + blocks.skipLayer(Layer.turret); + blocks.drawBlocks(Layer.laser); - drawFlyerShadows(); + drawFlyerShadows(); - drawAllTeams(true); + drawAllTeams(true); - drawAndInterpolate(bulletGroup); - drawAndInterpolate(effectGroup); + drawAndInterpolate(bulletGroup); + drawAndInterpolate(effectGroup); - overlays.drawBottom(); - drawAndInterpolate(playerGroup, p -> true, Player::drawBuildRequests); - overlays.drawTop(); + overlays.drawBottom(); + drawAndInterpolate(playerGroup, p -> true, Player::drawBuildRequests); + overlays.drawTop(); - Graphics.flushSurface(); + Graphics.flushSurface(); - if(showPaths && debug) drawDebug(); + if(showPaths && debug) drawDebug(); - batch.end(); + batch.end(); - if(showFog){ - fog.draw(); - } + if(showFog){ + fog.draw(); + } - Graphics.beginCam(); - EntityDraw.setClip(false); - drawAndInterpolate(playerGroup, p -> !p.isDead() && !p.isLocal, Player::drawName); - EntityDraw.setClip(true); - Graphics.end(); - } + Graphics.beginCam(); + EntityDraw.setClip(false); + drawAndInterpolate(playerGroup, p -> !p.isDead() && !p.isLocal, Player::drawName); + EntityDraw.setClip(true); + Graphics.end(); + } - private void drawFlyerShadows(){ - Graphics.surface(effectSurface, true, false); + private void drawFlyerShadows(){ + Graphics.surface(effectSurface, true, false); - float trnsX = 12, trnsY = -13; + float trnsX = 12, trnsY = -13; - Graphics.end(); - Core.batch.getTransformMatrix().translate(trnsX, trnsY, 0); - Graphics.begin(); + Graphics.end(); + Core.batch.getTransformMatrix().translate(trnsX, trnsY, 0); + Graphics.begin(); - for(EntityGroup group : unitGroups){ - if(!group.isEmpty()){ - drawAndInterpolate(group, unit -> unit.isFlying() && !unit.isDead(), Unit::drawShadow); - } - } + for(EntityGroup group : unitGroups){ + if(!group.isEmpty()){ + drawAndInterpolate(group, unit -> unit.isFlying() && !unit.isDead(), Unit::drawShadow); + } + } - if(!playerGroup.isEmpty()){ - drawAndInterpolate(playerGroup, unit -> unit.isFlying() && !unit.isDead(), Unit::drawShadow); - } + if(!playerGroup.isEmpty()){ + drawAndInterpolate(playerGroup, unit -> unit.isFlying() && !unit.isDead(), Unit::drawShadow); + } - Graphics.end(); - Core.batch.getTransformMatrix().translate(-trnsX, -trnsY, 0); - Graphics.begin(); + Graphics.end(); + Core.batch.getTransformMatrix().translate(-trnsX, -trnsY, 0); + Graphics.begin(); - //TODO this actually isn't necessary - Draw.color(0, 0, 0, 0.15f); - Graphics.flushSurface(); - Draw.color(); - } + //TODO this actually isn't necessary + Draw.color(0, 0, 0, 0.15f); + Graphics.flushSurface(); + Draw.color(); + } - private void drawAllTeams(boolean flying){ - for(Team team : Team.all){ - EntityGroup group = unitGroups[team.ordinal()]; + private void drawAllTeams(boolean flying){ + for(Team team : Team.all){ + EntityGroup group = unitGroups[team.ordinal()]; - if(group.count(p -> p.isFlying() == flying) + - playerGroup.count(p -> p.isFlying() == flying && p.getTeam() == team) == 0 && flying) continue; + if(group.count(p -> p.isFlying() == flying) + + playerGroup.count(p -> p.isFlying() == flying && p.getTeam() == team) == 0 && flying) continue; - drawAndInterpolate(unitGroups[team.ordinal()], u -> u.isFlying() == flying && !u.isDead(), Unit::drawUnder); - drawAndInterpolate(playerGroup, p -> p.isFlying() == flying && p.getTeam() == team, Unit::drawUnder); + drawAndInterpolate(unitGroups[team.ordinal()], u -> u.isFlying() == flying && !u.isDead(), Unit::drawUnder); + drawAndInterpolate(playerGroup, p -> p.isFlying() == flying && p.getTeam() == team, Unit::drawUnder); - Shaders.outline.color.set(team.color); - Shaders.mix.color.set(Color.WHITE); + Shaders.outline.color.set(team.color); + Shaders.mix.color.set(Color.WHITE); - Graphics.beginShaders(Shaders.outline); - Graphics.shader(Shaders.mix, true); - drawAndInterpolate(unitGroups[team.ordinal()], u -> u.isFlying() == flying && !u.isDead()); - drawAndInterpolate(playerGroup, p -> p.isFlying() == flying && p.getTeam() == team); - Graphics.shader(); - blocks.drawTeamBlocks(Layer.turret, team); - Graphics.endShaders(); + Graphics.beginShaders(Shaders.outline); + Graphics.shader(Shaders.mix, true); + drawAndInterpolate(unitGroups[team.ordinal()], u -> u.isFlying() == flying && !u.isDead()); + drawAndInterpolate(playerGroup, p -> p.isFlying() == flying && p.getTeam() == team); + Graphics.shader(); + blocks.drawTeamBlocks(Layer.turret, team); + Graphics.endShaders(); - drawAndInterpolate(unitGroups[team.ordinal()], u -> u.isFlying() == flying && !u.isDead(), Unit::drawOver); - drawAndInterpolate(playerGroup, p -> p.isFlying() == flying && p.getTeam() == team, Unit::drawOver); - } - } + drawAndInterpolate(unitGroups[team.ordinal()], u -> u.isFlying() == flying && !u.isDead(), Unit::drawOver); + drawAndInterpolate(playerGroup, p -> p.isFlying() == flying && p.getTeam() == team, Unit::drawOver); + } + } - public void drawAndInterpolate(EntityGroup group){ - drawAndInterpolate(group, t -> true, DrawTrait::draw); - } + public void drawAndInterpolate(EntityGroup group){ + drawAndInterpolate(group, t -> true, DrawTrait::draw); + } - public void drawAndInterpolate(EntityGroup group, Predicate toDraw){ - drawAndInterpolate(group, toDraw, DrawTrait::draw); - } + public void drawAndInterpolate(EntityGroup group, Predicate toDraw){ + drawAndInterpolate(group, toDraw, DrawTrait::draw); + } - public void drawAndInterpolate(EntityGroup group, Predicate toDraw, Consumer drawer){ - EntityDraw.drawWith(group, toDraw, t -> { - float lastx = t.getX(), lasty = t.getY(), lastrot = 0f; + public void drawAndInterpolate(EntityGroup group, Predicate toDraw, Consumer drawer){ + EntityDraw.drawWith(group, toDraw, t -> { + float lastx = t.getX(), lasty = t.getY(), lastrot = 0f; - if(threads.doInterpolate() && threads.isEnabled() && t instanceof SolidTrait){ - SolidTrait s = (SolidTrait)t; + if(threads.doInterpolate() && threads.isEnabled() && t instanceof SolidTrait){ + SolidTrait s = (SolidTrait) t; - lastrot = s.getRotation(); + lastrot = s.getRotation(); - if(s.lastUpdated() != 0){ - float timeSinceUpdate = TimeUtils.timeSinceMillis(s.lastUpdated()); - float alpha = Math.min(timeSinceUpdate / s.updateSpacing(), 1f); + if(s.lastUpdated() != 0){ + float timeSinceUpdate = TimeUtils.timeSinceMillis(s.lastUpdated()); + float alpha = Math.min(timeSinceUpdate / s.updateSpacing(), 1f); - tmpVector1.set(s.lastPosition().x, s.lastPosition().y) - .lerp(tmpVector2.set(lastx, lasty), alpha); - s.setRotation(Mathf.slerp(s.lastPosition().z, lastrot, alpha)); + tmpVector1.set(s.lastPosition().x, s.lastPosition().y) + .lerp(tmpVector2.set(lastx, lasty), alpha); + s.setRotation(Mathf.slerp(s.lastPosition().z, lastrot, alpha)); - s.setX(tmpVector1.x); - s.setY(tmpVector1.y); - } - } + s.setX(tmpVector1.x); + s.setY(tmpVector1.y); + } + } - //TODO extremely hacky - if(t instanceof Player && ((Player) t).getCarry() != null && ((Player) t).getCarry() instanceof Player && ((Player) ((Player) t).getCarry()).isLocal){ - ((Player) t).x = ((Player) t).getCarry().getX(); - ((Player) t).y = ((Player) t).getCarry().getY(); - } + //TODO extremely hacky + if(t instanceof Player && ((Player) t).getCarry() != null && ((Player) t).getCarry() instanceof Player && ((Player) ((Player) t).getCarry()).isLocal){ + ((Player) t).x = ((Player) t).getCarry().getX(); + ((Player) t).y = ((Player) t).getCarry().getY(); + } - drawer.accept(t); + drawer.accept(t); - t.setX(lastx); - t.setY(lasty); + t.setX(lastx); + t.setY(lasty); - if(threads.doInterpolate() && threads.isEnabled()) { + if(threads.doInterpolate() && threads.isEnabled()){ - if (t instanceof SolidTrait) { - ((SolidTrait) t).setRotation(lastrot); - } - } - }); - } + if(t instanceof SolidTrait){ + ((SolidTrait) t).setRotation(lastrot); + } + } + }); + } - @Override - public void resize(int width, int height){ - super.resize(width, height); - for(Player player : players) { + @Override + public void resize(int width, int height){ + super.resize(width, height); + for(Player player : players){ control.input(player.playerIndex).resetCursor(); } - camera.position.set(players[0].x, players[0].y, 0); - } + camera.position.set(players[0].x, players[0].y, 0); + } - @Override - public void dispose() { - background.dispose(); - fog.dispose(); - } + @Override + public void dispose(){ + background.dispose(); + fog.dispose(); + } - public Vector2 averagePosition(){ - avgPosition.setZero(); + public Vector2 averagePosition(){ + avgPosition.setZero(); - drawAndInterpolate(playerGroup, p -> p.isLocal, p -> { - avgPosition.add(p.x, p.y); - }); + drawAndInterpolate(playerGroup, p -> p.isLocal, p -> { + avgPosition.add(p.x, p.y); + }); avgPosition.scl(1f / players.length); return avgPosition; } - public FogRenderer fog() { - return fog; - } + public FogRenderer fog(){ + return fog; + } - public MinimapRenderer minimap() { - return minimap; - } + public MinimapRenderer minimap(){ + return minimap; + } - void drawPadding(){ - float vw = world.width() * tilesize; - float cw = camera.viewportWidth * camera.zoom; - float ch = camera.viewportHeight * camera.zoom; - if(vw < cw){ - batch.draw(background, - camera.position.x + vw/2, - Mathf.round(camera.position.y - ch/2, tilesize), - (cw - vw) /2, - ch + tilesize, - 0, 0, - ((cw - vw) / 2 / tilesize), -ch / tilesize + 1); + void drawPadding(){ + float vw = world.width() * tilesize; + float cw = camera.viewportWidth * camera.zoom; + float ch = camera.viewportHeight * camera.zoom; + if(vw < cw){ + batch.draw(background, + camera.position.x + vw / 2, + Mathf.round(camera.position.y - ch / 2, tilesize), + (cw - vw) / 2, + ch + tilesize, + 0, 0, + ((cw - vw) / 2 / tilesize), -ch / tilesize + 1); - batch.draw(background, - camera.position.x - vw/2, - Mathf.round(camera.position.y - ch/2, tilesize), - -(cw - vw) /2, - ch + tilesize, - 0, 0, - -((cw - vw) / 2 / tilesize), -ch / tilesize + 1); - } - } + batch.draw(background, + camera.position.x - vw / 2, + Mathf.round(camera.position.y - ch / 2, tilesize), + -(cw - vw) / 2, + ch + tilesize, + 0, 0, + -((cw - vw) / 2 / tilesize), -ch / tilesize + 1); + } + } - void drawDebug(){ - int rangex = (int)(Core.camera.viewportWidth/tilesize/2), rangey = (int)(Core.camera.viewportHeight/tilesize/2); + void drawDebug(){ + int rangex = (int) (Core.camera.viewportWidth / tilesize / 2), rangey = (int) (Core.camera.viewportHeight / tilesize / 2); - for(int x = -rangex; x <= rangex; x++) { - for (int y = -rangey; y <= rangey; y++) { - int worldx = Mathf.scl(camera.position.x, tilesize) + x; - int worldy = Mathf.scl(camera.position.y, tilesize) + y; + for(int x = -rangex; x <= rangex; x++){ + for(int y = -rangey; y <= rangey; y++){ + int worldx = Mathf.scl(camera.position.x, tilesize) + x; + int worldy = Mathf.scl(camera.position.y, tilesize) + y; - if(world.tile(worldx, worldy) == null) continue; + if(world.tile(worldx, worldy) == null) continue; - float value = world.pathfinder().getDebugValue(worldx, worldy); - Draw.color(Color.PURPLE); - Draw.alpha((value % 10f) / 10f); - Lines.square(worldx * tilesize, worldy*tilesize, 4f); - } - } + float value = world.pathfinder().getDebugValue(worldx, worldy); + Draw.color(Color.PURPLE); + Draw.alpha((value % 10f) / 10f); + Lines.square(worldx * tilesize, worldy * tilesize, 4f); + } + } - Draw.color(Color.ORANGE); - Draw.tcolor(Color.ORANGE); + Draw.color(Color.ORANGE); + Draw.tcolor(Color.ORANGE); - ObjectIntMap seen = new ObjectIntMap<>(); + ObjectIntMap seen = new ObjectIntMap<>(); - for(BlockFlag flag : BlockFlag.values()){ - for(Tile tile : world.indexer().getEnemy(Team.blue, flag)){ - int index = seen.getAndIncrement(tile, 0, 1); - Draw.tscl(0.125f); - Draw.text(flag.name(), tile.drawx(), tile.drawy() + tile.block().size * tilesize/2f + 4 + index * 3); - Lines.square(tile.drawx(), tile.drawy(), tile.block().size * tilesize/2f); - } - } - Draw.tscl(fontScale); - Draw.tcolor(); + for(BlockFlag flag : BlockFlag.values()){ + for(Tile tile : world.indexer().getEnemy(Team.blue, flag)){ + int index = seen.getAndIncrement(tile, 0, 1); + Draw.tscl(0.125f); + Draw.text(flag.name(), tile.drawx(), tile.drawy() + tile.block().size * tilesize / 2f + 4 + index * 3); + Lines.square(tile.drawx(), tile.drawy(), tile.block().size * tilesize / 2f); + } + } + Draw.tscl(fontScale); + Draw.tcolor(); - Draw.color(); - } + Draw.color(); + } - public BlockRenderer getBlocks() { - return blocks; - } + public BlockRenderer getBlocks(){ + return blocks; + } - public void setCameraScale(int amount){ - targetscale = amount; - clampScale(); - //scale up all surfaces in preparation for the zoom - for(Surface surface : Graphics.getSurfaces()){ - surface.setScale(targetscale); - } - } + public void setCameraScale(int amount){ + targetscale = amount; + clampScale(); + //scale up all surfaces in preparation for the zoom + for(Surface surface : Graphics.getSurfaces()){ + surface.setScale(targetscale); + } + } - public void scaleCamera(int amount){ - setCameraScale(targetscale + amount); - } + public void scaleCamera(int amount){ + setCameraScale(targetscale + amount); + } - public void clampScale(){ - float s = io.anuke.ucore.scene.ui.layout.Unit.dp.scl(1f); - targetscale = Mathf.clamp(targetscale, Math.round(s*2), Math.round(s*5)); - } + public void clampScale(){ + float s = io.anuke.ucore.scene.ui.layout.Unit.dp.scl(1f); + targetscale = Mathf.clamp(targetscale, Math.round(s * 2), Math.round(s * 5)); + } } diff --git a/core/src/io/anuke/mindustry/core/ThreadHandler.java b/core/src/io/anuke/mindustry/core/ThreadHandler.java index c90a32131c..22bc5ff2fe 100644 --- a/core/src/io/anuke/mindustry/core/ThreadHandler.java +++ b/core/src/io/anuke/mindustry/core/ThreadHandler.java @@ -9,30 +9,29 @@ import io.anuke.ucore.util.Log; import static io.anuke.mindustry.Vars.control; import static io.anuke.mindustry.Vars.logic; -public class ThreadHandler { +public class ThreadHandler{ private final Queue toRun = new Queue<>(); private final ThreadProvider impl; + private final Object updateLock = new Object(); private float delta = 1f; private float smoothDelta = 1f; private long frame = 0, lastDeltaUpdate; private float framesSinceUpdate; private boolean enabled; - - private final Object updateLock = new Object(); private boolean rendered = true; public ThreadHandler(ThreadProvider impl){ this.impl = impl; Timers.setDeltaProvider(() -> { - float result = impl.isOnThread() ? delta : Gdx.graphics.getDeltaTime()*60f; + float result = impl.isOnThread() ? delta : Gdx.graphics.getDeltaTime() * 60f; return Math.min(Float.isNaN(result) ? 1f : result, 15f); }); } public void run(Runnable r){ - if(enabled) { - synchronized (toRun) { + if(enabled){ + synchronized(toRun){ toRun.addLast(r); } }else{ @@ -41,7 +40,7 @@ public class ThreadHandler { } public void runGraphics(Runnable r){ - if(enabled) { + if(enabled){ Gdx.app.postRunnable(r); }else{ r.run(); @@ -49,8 +48,8 @@ public class ThreadHandler { } public void runDelay(Runnable r){ - if(enabled) { - synchronized (toRun) { + if(enabled){ + synchronized(toRun){ toRun.addLast(r); } }else{ @@ -59,7 +58,7 @@ public class ThreadHandler { } public int getTPS(){ - return (int)(60/smoothDelta); + return (int) (60 / smoothDelta); } public long getFrameID(){ @@ -76,12 +75,16 @@ public class ThreadHandler { framesSinceUpdate += Timers.delta(); - synchronized (updateLock) { + synchronized(updateLock){ rendered = true; impl.notify(updateLock); } } + public boolean isEnabled(){ + return enabled; + } + public void setEnabled(boolean enabled){ if(enabled){ logic.doUpdate = false; @@ -98,10 +101,6 @@ public class ThreadHandler { } } - public boolean isEnabled(){ - return enabled; - } - public boolean doInterpolate(){ return enabled && Gdx.graphics.getFramesPerSecond() - getTPS() > 20 && getTPS() < 30; } @@ -111,13 +110,13 @@ public class ThreadHandler { } private void runLogic(){ - try { - while (true) { + try{ + while(true){ long time = TimeUtils.nanoTime(); while(true){ Runnable r; - synchronized (toRun){ + synchronized(toRun){ if(toRun.size > 0){ r = toRun.removeFirst(); }else{ @@ -135,12 +134,12 @@ public class ThreadHandler { long elapsed = TimeUtils.nanosToMillis(TimeUtils.timeSinceNanos(time)); long target = (long) ((1000) / 60f); - if (elapsed < target) { + if(elapsed < target){ impl.sleep(target - elapsed); } - synchronized(updateLock) { - while(!rendered) { + synchronized(updateLock){ + while(!rendered){ impl.wait(updateLock); } rendered = false; @@ -154,22 +153,27 @@ public class ThreadHandler { smoothDelta = delta; } - frame ++; + frame++; framesSinceUpdate = 0; } - } catch (InterruptedException ex) { + }catch(InterruptedException ex){ Log.info("Stopping logic thread."); - } catch (Throwable ex) { + }catch(Throwable ex){ control.setError(ex); } } - public interface ThreadProvider { + public interface ThreadProvider{ boolean isOnThread(); + void sleep(long ms) throws InterruptedException; + void start(Runnable run); + void stop(); + void wait(Object object) throws InterruptedException; + void notify(Object object); } } diff --git a/core/src/io/anuke/mindustry/core/UI.java b/core/src/io/anuke/mindustry/core/UI.java index 821ea28cff..059d58f5c3 100644 --- a/core/src/io/anuke/mindustry/core/UI.java +++ b/core/src/io/anuke/mindustry/core/UI.java @@ -37,29 +37,7 @@ import static io.anuke.mindustry.Vars.players; import static io.anuke.ucore.scene.actions.Actions.*; public class UI extends SceneModule{ - public AboutDialog about; - public RestartDialog restart; - public LevelDialog levels; - public MapsDialog maps; - public LoadDialog load; - public DiscordDialog discord; - public JoinDialog join; - public HostDialog host; - public PausedDialog paused; - public SettingsMenuDialog settings; - public ControlsDialog controls; - public MapEditorDialog editor; - public LanguageDialog language; - public BansDialog bans; - public AdminsDialog admins; - public TraceDialog traces; - public RollbackDialog rollback; - public ChangelogDialog changelog; - public LocalPlayerDialog localplayers; - public UnlocksDialog unlocks; - public ContentInfoDialog content; - - public final MenuFragment menufrag = new MenuFragment(); + public final MenuFragment menufrag = new MenuFragment(); public final HudFragment hudfrag = new HudFragment(); public final ChatFragment chatfrag = new ChatFragment(); public final PlayerListFragment listfrag = new PlayerListFragment(); @@ -67,239 +45,246 @@ public class UI extends SceneModule{ public final LoadingFragment loadfrag = new LoadingFragment(); public final DebugFragment debugfrag = new DebugFragment(); + public AboutDialog about; + public RestartDialog restart; + public LevelDialog levels; + public MapsDialog maps; + public LoadDialog load; + public DiscordDialog discord; + public JoinDialog join; + public HostDialog host; + public PausedDialog paused; + public SettingsMenuDialog settings; + public ControlsDialog controls; + public MapEditorDialog editor; + public LanguageDialog language; + public BansDialog bans; + public AdminsDialog admins; + public TraceDialog traces; + public RollbackDialog rollback; + public ChangelogDialog changelog; + public LocalPlayerDialog localplayers; + public UnlocksDialog unlocks; + public ContentInfoDialog content; + private Locale lastLocale; - - public UI() { - Dialog.setShowAction(()-> sequence( - alpha(0f), - originCenter(), - moveToAligned(Gdx.graphics.getWidth()/2, Gdx.graphics.getHeight()/2, Align.center), - scaleTo(0.0f, 1f), - parallel( - scaleTo(1f, 1f, 0.1f, Interpolation.fade), - fadeIn(0.1f, Interpolation.fade) - ) - )); - - Dialog.setHideAction(()-> sequence( - parallel( - scaleTo(0.01f, 0.01f, 0.1f, Interpolation.fade), - fadeOut(0.1f, Interpolation.fade) - ) - )); - - TooltipManager.getInstance().animations = false; - - Settings.setErrorHandler(()-> Timers.run(1f, ()-> showError("[crimson]Failed to access local storage.\nSettings will not be saved."))); - - Dialog.closePadR = -1; - Dialog.closePadT = 5; - - Colors.put("description", Palette.description); - Colors.put("turretinfo", Palette.turretinfo); - Colors.put("iteminfo", Palette.iteminfo); - Colors.put("powerinfo", Palette.powerinfo); - Colors.put("liquidinfo", Palette.liquidinfo); - Colors.put("craftinfo", Palette.craftinfo); - Colors.put("missingitems", Palette.missingitems); - Colors.put("health", Palette.health); - Colors.put("healthstats", Palette.healthstats); - Colors.put("interact", Palette.interact); - Colors.put("accent", Palette.accent); - Colors.put("place", Palette.place); - Colors.put("remove", Palette.remove); - Colors.put("placeRotate", Palette.placeRotate); - Colors.put("range", Palette.range); - Colors.put("power", Palette.power); - } - @Override - protected void loadSkin(){ - skin = new Skin(Gdx.files.internal("ui/uiskin.json"), Core.atlas); - Mathf.each(font -> { - font.setUseIntegerPositions(false); - font.getData().setScale(Vars.fontScale); - font.getData().down += Unit.dp.scl(4f); - font.getData().lineHeight -= Unit.dp.scl(2f); - }, skin.font(), skin.getFont("default-font-chat"), skin.getFont("korean")); - } + public UI(){ + Dialog.setShowAction(() -> sequence( + alpha(0f), + originCenter(), + moveToAligned(Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() / 2, Align.center), + scaleTo(0.0f, 1f), + parallel( + scaleTo(1f, 1f, 0.1f, Interpolation.fade), + fadeIn(0.1f, Interpolation.fade) + ) + )); - @Override - public synchronized void update(){ - if(Vars.debug && !Vars.showUI) return; + Dialog.setHideAction(() -> sequence( + parallel( + scaleTo(0.01f, 0.01f, 0.1f, Interpolation.fade), + fadeOut(0.1f, Interpolation.fade) + ) + )); - if(Graphics.drawing()) Graphics.end(); - - act(); + TooltipManager.getInstance().animations = false; - Graphics.begin(); + Settings.setErrorHandler(() -> Timers.run(1f, () -> showError("[crimson]Failed to access local storage.\nSettings will not be saved."))); - for(int i = 0; i < players.length; i ++){ - InputHandler input = control.input(i); + Dialog.closePadR = -1; + Dialog.closePadT = 5; - if(input.isCursorVisible()) { + Colors.put("description", Palette.description); + Colors.put("turretinfo", Palette.turretinfo); + Colors.put("iteminfo", Palette.iteminfo); + Colors.put("powerinfo", Palette.powerinfo); + Colors.put("liquidinfo", Palette.liquidinfo); + Colors.put("craftinfo", Palette.craftinfo); + Colors.put("missingitems", Palette.missingitems); + Colors.put("health", Palette.health); + Colors.put("healthstats", Palette.healthstats); + Colors.put("interact", Palette.interact); + Colors.put("accent", Palette.accent); + Colors.put("place", Palette.place); + Colors.put("remove", Palette.remove); + Colors.put("placeRotate", Palette.placeRotate); + Colors.put("range", Palette.range); + Colors.put("power", Palette.power); + } + + @Override + protected void loadSkin(){ + skin = new Skin(Gdx.files.internal("ui/uiskin.json"), Core.atlas); + Mathf.each(font -> { + font.setUseIntegerPositions(false); + font.getData().setScale(Vars.fontScale); + font.getData().down += Unit.dp.scl(4f); + font.getData().lineHeight -= Unit.dp.scl(2f); + }, skin.font(), skin.getFont("default-font-chat"), skin.getFont("korean")); + } + + @Override + public synchronized void update(){ + if(Vars.debug && !Vars.showUI) return; + + if(Graphics.drawing()) Graphics.end(); + + act(); + + Graphics.begin(); + + for(int i = 0; i < players.length; i++){ + InputHandler input = control.input(i); + + if(input.isCursorVisible()){ Draw.color(); float scl = Unit.dp.scl(3f); - Draw.rect("controller-cursor", input.getMouseX(), Gdx.graphics.getHeight() - input.getMouseY(), 16*scl, 16*scl); + Draw.rect("controller-cursor", input.getMouseX(), Gdx.graphics.getHeight() - input.getMouseY(), 16 * scl, 16 * scl); } } - Graphics.end(); + Graphics.end(); Draw.color(); - } + } - @Override - public void init(){ - editor = new MapEditorDialog(); - controls = new ControlsDialog(); - restart = new RestartDialog(); - join = new JoinDialog(); - discord = new DiscordDialog(); - load = new LoadDialog(); - levels = new LevelDialog(); - language = new LanguageDialog(); - settings = new SettingsMenuDialog(); - paused = new PausedDialog(); - changelog = new ChangelogDialog(); - about = new AboutDialog(); - host = new HostDialog(); - bans = new BansDialog(); - admins = new AdminsDialog(); - traces = new TraceDialog(); - rollback = new RollbackDialog(); - maps = new MapsDialog(); - localplayers = new LocalPlayerDialog(); - unlocks = new UnlocksDialog(); - content = new ContentInfoDialog(); + @Override + public void init(){ + editor = new MapEditorDialog(); + controls = new ControlsDialog(); + restart = new RestartDialog(); + join = new JoinDialog(); + discord = new DiscordDialog(); + load = new LoadDialog(); + levels = new LevelDialog(); + language = new LanguageDialog(); + settings = new SettingsMenuDialog(); + paused = new PausedDialog(); + changelog = new ChangelogDialog(); + about = new AboutDialog(); + host = new HostDialog(); + bans = new BansDialog(); + admins = new AdminsDialog(); + traces = new TraceDialog(); + rollback = new RollbackDialog(); + maps = new MapsDialog(); + localplayers = new LocalPlayerDialog(); + unlocks = new UnlocksDialog(); + content = new ContentInfoDialog(); - build.begin(scene); + build.begin(scene); - Group group = Core.scene.getRoot(); + Group group = Core.scene.getRoot(); - backfrag.build(group); - hudfrag.build(group); - menufrag.build(group); - chatfrag.container().build(group); - listfrag.build(group); - debugfrag.build(group); - loadfrag.build(group); + backfrag.build(group); + hudfrag.build(group); + menufrag.build(group); + chatfrag.container().build(group); + listfrag.build(group); + debugfrag.build(group); + loadfrag.build(group); - build.end(); - } + build.end(); + } - @Override - public boolean hasMouse() { - return super.hasMouse(); - } + @Override + public boolean hasMouse(){ + return super.hasMouse(); + } - @Override - public void resize(int width, int height) { - super.resize(width, height); + @Override + public void resize(int width, int height){ + super.resize(width, height); - Events.fire(ResizeEvent.class); - } + Events.fire(ResizeEvent.class); + } - public Locale getLocale(){ - String loc = Settings.getString("locale"); - if(loc.equals("default")){ - return Locale.getDefault(); - }else{ - if(lastLocale == null || !lastLocale.toString().equals(loc)){ - if(loc.contains("_")){ - String[] split = loc.split("_"); - lastLocale = new Locale(split[0], split[1]); - }else{ - lastLocale = new Locale(loc); - } - } + public Locale getLocale(){ + String loc = Settings.getString("locale"); + if(loc.equals("default")){ + return Locale.getDefault(); + }else{ + if(lastLocale == null || !lastLocale.toString().equals(loc)){ + if(loc.contains("_")){ + String[] split = loc.split("_"); + lastLocale = new Locale(split[0], split[1]); + }else{ + lastLocale = new Locale(loc); + } + } - return lastLocale; - } - } + return lastLocale; + } + } - public void loadAnd(Callable call){ - loadAnd("$text.loading", call); - } + public void loadAnd(Callable call){ + loadAnd("$text.loading", call); + } - public void loadAnd(String text, Callable call){ - loadfrag.show(text); - Timers.runTask(7f, () -> { - call.run(); - loadfrag.hide(); - }); - } + public void loadAnd(String text, Callable call){ + loadfrag.show(text); + Timers.runTask(7f, () -> { + call.run(); + loadfrag.hide(); + }); + } - public void showTextInput(String title, String text, String def, TextFieldFilter filter, Consumer confirmed){ - new Dialog(title, "dialog"){{ - content().margin(30).add(text).padRight(6f); - TextField field = content().addField(def, t->{}).size(170f, 50f).get(); - field.setTextFieldFilter((f, c) -> field.getText().length() < 12 && filter.acceptChar(f, c)); - Platform.instance.addDialog(field); - buttons().defaults().size(120, 54).pad(4); - buttons().addButton("$text.ok", () -> { - confirmed.accept(field.getText()); - hide(); - }).disabled(b -> field.getText().isEmpty()); - buttons().addButton("$text.cancel", this::hide); - }}.show(); - } + public void showTextInput(String title, String text, String def, TextFieldFilter filter, Consumer confirmed){ + new Dialog(title, "dialog"){{ + content().margin(30).add(text).padRight(6f); + TextField field = content().addField(def, t -> { + }).size(170f, 50f).get(); + field.setTextFieldFilter((f, c) -> field.getText().length() < 12 && filter.acceptChar(f, c)); + Platform.instance.addDialog(field); + buttons().defaults().size(120, 54).pad(4); + buttons().addButton("$text.ok", () -> { + confirmed.accept(field.getText()); + hide(); + }).disabled(b -> field.getText().isEmpty()); + buttons().addButton("$text.cancel", this::hide); + }}.show(); + } - public void showTextInput(String title, String text, String def, Consumer confirmed){ - showTextInput(title, text, def, (field, c) -> true, confirmed); - } + public void showTextInput(String title, String text, String def, Consumer confirmed){ + showTextInput(title, text, def, (field, c) -> true, confirmed); + } - public void showInfoFade(String info){ - Table table = new Table(); - table.setFillParent(true); - table.actions(Actions.fadeOut(7f, Interpolation.fade), Actions.removeActor()); - table.top().add(info).padTop(8); - Core.scene.add(table); - } + public void showInfoFade(String info){ + Table table = new Table(); + table.setFillParent(true); + table.actions(Actions.fadeOut(7f, Interpolation.fade), Actions.removeActor()); + table.top().add(info).padTop(8); + Core.scene.add(table); + } - public void showInfo(String info){ - new Dialog("$text.info.title", "dialog"){{ - getCell(content()).growX(); - content().margin(15).add(info).width(400f).wrap().get().setAlignment(Align.center, Align.center); - buttons().addButton("$text.ok", this::hide).size(90, 50).pad(4); - }}.show(); - } + public void showInfo(String info){ + new Dialog("$text.info.title", "dialog"){{ + getCell(content()).growX(); + content().margin(15).add(info).width(400f).wrap().get().setAlignment(Align.center, Align.center); + buttons().addButton("$text.ok", this::hide).size(90, 50).pad(4); + }}.show(); + } - public void showError(String text){ - new Dialog("$text.error.title", "dialog"){{ - content().margin(15).add(text).width(400f).wrap().get().setAlignment(Align.center, Align.center); - buttons().addButton("$text.ok", this::hide).size(90, 50).pad(4); - }}.show(); - } + public void showError(String text){ + new Dialog("$text.error.title", "dialog"){{ + content().margin(15).add(text).width(400f).wrap().get().setAlignment(Align.center, Align.center); + buttons().addButton("$text.ok", this::hide).size(90, 50).pad(4); + }}.show(); + } - public void showConfirm(String title, String text, Listenable confirmed){ - FloatingDialog dialog = new FloatingDialog(title); - dialog.content().add(text).width(400f).wrap().pad(4f).get().setAlignment(Align.center, Align.center); - dialog.buttons().defaults().size(200f, 54f).pad(2f); - dialog.buttons().addButton("$text.cancel", dialog::hide); - dialog.buttons().addButton("$text.ok", () -> { - dialog.hide(); - confirmed.listen(); - }); - dialog.keyDown(Keys.ESCAPE, dialog::hide); - dialog.keyDown(Keys.BACK, dialog::hide); - dialog.show(); - } - - public void showConfirmListen(String title, String text, Consumer listener){ - FloatingDialog dialog = new FloatingDialog(title); - dialog.content().add(text).pad(4f); - dialog.buttons().defaults().size(200f, 54f).pad(2f); - dialog.buttons().addButton("$text.cancel", () -> { - dialog.hide(); - listener.accept(true); - }); - dialog.buttons().addButton("$text.ok", () -> { - dialog.hide(); - listener.accept(true); - }); - dialog.show(); - } - + public void showConfirm(String title, String text, Listenable confirmed){ + FloatingDialog dialog = new FloatingDialog(title); + dialog.content().add(text).width(400f).wrap().pad(4f).get().setAlignment(Align.center, Align.center); + dialog.buttons().defaults().size(200f, 54f).pad(2f); + dialog.buttons().addButton("$text.cancel", dialog::hide); + dialog.buttons().addButton("$text.ok", () -> { + dialog.hide(); + confirmed.listen(); + }); + dialog.keyDown(Keys.ESCAPE, dialog::hide); + dialog.keyDown(Keys.BACK, dialog::hide); + dialog.show(); + } } diff --git a/core/src/io/anuke/mindustry/core/World.java b/core/src/io/anuke/mindustry/core/World.java index 73a03e013b..0a6a0300de 100644 --- a/core/src/io/anuke/mindustry/core/World.java +++ b/core/src/io/anuke/mindustry/core/World.java @@ -11,7 +11,10 @@ import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.game.EventType.TileChangeEvent; import io.anuke.mindustry.game.EventType.WorldLoadEvent; import io.anuke.mindustry.game.Team; -import io.anuke.mindustry.io.*; +import io.anuke.mindustry.io.Map; +import io.anuke.mindustry.io.MapIO; +import io.anuke.mindustry.io.MapMeta; +import io.anuke.mindustry.io.Maps; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.mapgen.WorldGenerator; @@ -27,124 +30,130 @@ import io.anuke.ucore.util.Tmp; import static io.anuke.mindustry.Vars.*; public class World extends Module{ - private int seed; - - private Map currentMap; - private Tile[][] tiles; - private Pathfinder pathfinder = new Pathfinder(); - private BlockIndexer indexer = new BlockIndexer(); - private Maps maps = new Maps(); + private int seed; - private Array tempTiles = new ThreadArray<>(); - private boolean generating, invalidMap; - - public World(){ - maps.load(); - } - - @Override - public void dispose(){ - maps.dispose(); - } - - public Maps maps(){ - return maps; - } + private Map currentMap; + private Tile[][] tiles; + private Pathfinder pathfinder = new Pathfinder(); + private BlockIndexer indexer = new BlockIndexer(); + private Maps maps = new Maps(); - public BlockIndexer indexer() { - return indexer; - } + private Array tempTiles = new ThreadArray<>(); + private boolean generating, invalidMap; - public Pathfinder pathfinder(){ - return pathfinder; - } + public World(){ + maps.load(); + } - public boolean isInvalidMap() { - return invalidMap; - } + @Override + public void dispose(){ + maps.dispose(); + } - public boolean solid(int x, int y){ - Tile tile = tile(x, y); - - return tile == null || tile.solid(); - } - - public boolean passable(int x, int y){ - Tile tile = tile(x, y); - - return tile != null && tile.passable(); - } - - public boolean wallSolid(int x, int y){ - Tile tile = tile(x, y); - return tile == null || tile.block().solid; - } - - public boolean isAccessible(int x, int y){ - return !wallSolid(x, y-1) || !wallSolid(x, y+1) || !wallSolid(x-1, y) ||!wallSolid(x+1, y); - } - - public boolean floorBlends(int x, int y, Block block){ - Tile tile = tile(x, y); - return tile == null || tile.floor().id <= block.id; - } - - public Map getMap(){ - return currentMap; - } - - public int width(){ - return tiles == null ? 0 : tiles.length; - } - - public int height(){ - return tiles == null ? 0 : tiles[0].length; - } + public Maps maps(){ + return maps; + } - public int toPacked(int x, int y){ - return x + y *width(); - } + public BlockIndexer indexer(){ + return indexer; + } - public Tile tile(int packed){ - return tiles == null ? null : tile(packed % width(), packed / width()); - } - - public Tile tile(int x, int y){ - if(tiles == null){ - return null; - } - if(!Mathf.inBounds(x, y, tiles)) return null; - return tiles[x][y]; - } + public Pathfinder pathfinder(){ + return pathfinder; + } - public Tile rawTile(int x, int y){ - return tiles[x][y]; - } - - public Tile tileWorld(float x, float y){ - return tile(Mathf.scl2(x, tilesize), Mathf.scl2(y, tilesize)); - } + public boolean isInvalidMap(){ + return invalidMap; + } - public int toTile(float coord){ - return Mathf.scl2(coord, tilesize); - } - - public Tile[][] getTiles(){ - return tiles; - } - - private void clearTileEntities(){ - for(int x = 0; x < tiles.length; x ++){ - for(int y = 0; y < tiles[0].length; y ++){ - if(tiles[x][y] != null && tiles[x][y].entity != null){ - tiles[x][y].entity.remove(); - } - } - } - } + public boolean solid(int x, int y){ + Tile tile = tile(x, y); - /**Resizes the tile array to the specified size and returns the resulting tile array. - * Only use for loading saves!*/ + return tile == null || tile.solid(); + } + + public boolean passable(int x, int y){ + Tile tile = tile(x, y); + + return tile != null && tile.passable(); + } + + public boolean wallSolid(int x, int y){ + Tile tile = tile(x, y); + return tile == null || tile.block().solid; + } + + public boolean isAccessible(int x, int y){ + return !wallSolid(x, y - 1) || !wallSolid(x, y + 1) || !wallSolid(x - 1, y) || !wallSolid(x + 1, y); + } + + public boolean floorBlends(int x, int y, Block block){ + Tile tile = tile(x, y); + return tile == null || tile.floor().id <= block.id; + } + + public Map getMap(){ + return currentMap; + } + + public void setMap(Map map){ + this.currentMap = map; + } + + public int width(){ + return tiles == null ? 0 : tiles.length; + } + + public int height(){ + return tiles == null ? 0 : tiles[0].length; + } + + public int toPacked(int x, int y){ + return x + y * width(); + } + + public Tile tile(int packed){ + return tiles == null ? null : tile(packed % width(), packed / width()); + } + + public Tile tile(int x, int y){ + if(tiles == null){ + return null; + } + if(!Mathf.inBounds(x, y, tiles)) return null; + return tiles[x][y]; + } + + public Tile rawTile(int x, int y){ + return tiles[x][y]; + } + + public Tile tileWorld(float x, float y){ + return tile(Mathf.scl2(x, tilesize), Mathf.scl2(y, tilesize)); + } + + public int toTile(float coord){ + return Mathf.scl2(coord, tilesize); + } + + public Tile[][] getTiles(){ + return tiles; + } + + private void clearTileEntities(){ + for(int x = 0; x < tiles.length; x++){ + for(int y = 0; y < tiles[0].length; y++){ + if(tiles[x][y] != null && tiles[x][y].entity != null){ + tiles[x][y].entity.remove(); + } + } + } + } + + /** + * Resizes the tile array to the specified size and returns the resulting tile array. + * Only use for loading saves! + */ public Tile[][] createTiles(int width, int height){ if(tiles != null){ clearTileEntities(); @@ -159,207 +168,214 @@ public class World extends Module{ return tiles; } - /**Call to signify the beginning of map loading. - * TileChangeEvents will not be fired until endMapLoad().*/ - public void beginMapLoad(){ - generating = true; - } + /** + * Call to signify the beginning of map loading. + * TileChangeEvents will not be fired until endMapLoad(). + */ + public void beginMapLoad(){ + generating = true; + } - /**Call to signify the end of map loading. Updates tile occlusions and sets up physics for the world. - * A WorldLoadEvent will be fire.*/ - public void endMapLoad(){ - for(int x = 0; x < tiles.length; x ++) { - for (int y = 0; y < tiles[0].length; y++) { - tiles[x][y].updateOcclusion(); + /** + * Call to signify the end of map loading. Updates tile occlusions and sets up physics for the world. + * A WorldLoadEvent will be fire. + */ + public void endMapLoad(){ + for(int x = 0; x < tiles.length; x++){ + for(int y = 0; y < tiles[0].length; y++){ + tiles[x][y].updateOcclusion(); - if(tiles[x][y].entity != null){ - tiles[x][y].entity.updateProximity(); - } - } - } + if(tiles[x][y].entity != null){ + tiles[x][y].entity.updateProximity(); + } + } + } - EntityPhysics.resizeTree(0, 0, tiles.length * tilesize, tiles[0].length * tilesize); + EntityPhysics.resizeTree(0, 0, tiles.length * tilesize, tiles[0].length * tilesize); - generating = false; - Events.fire(WorldLoadEvent.class); - } + generating = false; + Events.fire(WorldLoadEvent.class); + } - /**Loads up a procedural map. This does not call play(), but calls reset().*/ - public void loadProceduralMap(){ - Timers.mark(); - Timers.mark(); + /** + * Loads up a procedural map. This does not call play(), but calls reset(). + */ + public void loadProceduralMap(){ + Timers.mark(); + Timers.mark(); - logic.reset(); + logic.reset(); - beginMapLoad(); + beginMapLoad(); - int width = 400, height = 400; + int width = 400, height = 400; - Tile[][] tiles = createTiles(width, height); + Tile[][] tiles = createTiles(width, height); - Map map = new Map("Generated Map", new MapMeta(0, new ObjectMap<>(), width, height, null), true, () -> null); - setMap(map); + Map map = new Map("Generated Map", new MapMeta(0, new ObjectMap<>(), width, height, null), true, () -> null); + setMap(map); - EntityPhysics.resizeTree(0, 0, width * tilesize, height * tilesize); + EntityPhysics.resizeTree(0, 0, width * tilesize, height * tilesize); - Timers.mark(); - WorldGenerator.generateMap(tiles, Mathf.random(9999999)); - Log.info("Time to generate base map: {0}", Timers.elapsed()); + Timers.mark(); + WorldGenerator.generateMap(tiles, Mathf.random(9999999)); + Log.info("Time to generate base map: {0}", Timers.elapsed()); - Log.info("Time to generate fully without additional events: {0}", Timers.elapsed()); + Log.info("Time to generate fully without additional events: {0}", Timers.elapsed()); - endMapLoad(); + endMapLoad(); - Log.info("Full time to generate: {0}", Timers.elapsed()); - } + Log.info("Full time to generate: {0}", Timers.elapsed()); + } - public void setMap(Map map){ - this.currentMap = map; - } - - public void loadMap(Map map){ - loadMap(map, MathUtils.random(0, 999999)); - } - - public void loadMap(Map map, int seed){ - beginMapLoad(); - this.currentMap = map; - this.seed = seed; + public void loadMap(Map map){ + loadMap(map, MathUtils.random(0, 999999)); + } - int width = map.meta.width, height = map.meta.height; + public void loadMap(Map map, int seed){ + beginMapLoad(); + this.currentMap = map; + this.seed = seed; - createTiles(width, height); - - EntityPhysics.resizeTree(0, 0, width * tilesize, height * tilesize); + int width = map.meta.width, height = map.meta.height; - WorldGenerator.loadTileData(tiles, MapIO.readTileData(map, true), map.meta.hasOreGen(), seed); + createTiles(width, height); - if(!headless && state.teams.get(players[0].getTeam()).cores.size == 0){ - ui.showError("$text.map.nospawn"); - threads.runDelay(() -> state.set(State.menu)); - invalidMap = true; - }else{ - invalidMap = false; - } + EntityPhysics.resizeTree(0, 0, width * tilesize, height * tilesize); - endMapLoad(); - } + WorldGenerator.loadTileData(tiles, MapIO.readTileData(map, true), map.meta.hasOreGen(), seed); - public int getSeed(){ - return seed; - } + if(!headless && state.teams.get(players[0].getTeam()).cores.size == 0){ + ui.showError("$text.map.nospawn"); + threads.runDelay(() -> state.set(State.menu)); + invalidMap = true; + }else{ + invalidMap = false; + } - public void notifyChanged(Tile tile){ - if(!generating){ - threads.runDelay(() -> Events.fire(TileChangeEvent.class, tile)); - } - } + endMapLoad(); + } - public void removeBlock(Tile tile){ - if(!tile.block().isMultiblock() && !tile.isLinked()){ - tile.setBlock(Blocks.air); - }else{ - Tile target = tile.target(); - Array removals = target.getLinkedTiles(tempTiles); - for(Tile toremove : removals){ - //note that setting a new block automatically unlinks it - if(toremove != null) toremove.setBlock(Blocks.air); - } - } - } + public int getSeed(){ + return seed; + } - public void setBlock(Tile tile, Block block, Team team){ - tile.setBlock(block); - if (block.isMultiblock()) { - int offsetx = -(block.size - 1) / 2; - int offsety = -(block.size - 1) / 2; + public void notifyChanged(Tile tile){ + if(!generating){ + threads.runDelay(() -> Events.fire(TileChangeEvent.class, tile)); + } + } - for (int dx = 0; dx < block.size; dx++) { - for (int dy = 0; dy < block.size; dy++) { - int worldx = dx + offsetx + tile.x; - int worldy = dy + offsety + tile.y; - if (!(worldx == tile.x && worldy == tile.y)) { - Tile toplace = world.tile(worldx, worldy); - if (toplace != null) { - toplace.setLinked((byte) (dx + offsetx), (byte) (dy + offsety)); - toplace.setTeam(team); - } - } - } - } - } - } + public void removeBlock(Tile tile){ + if(!tile.block().isMultiblock() && !tile.isLinked()){ + tile.setBlock(Blocks.air); + }else{ + Tile target = tile.target(); + Array removals = target.getLinkedTiles(tempTiles); + for(Tile toremove : removals){ + //note that setting a new block automatically unlinks it + if(toremove != null) toremove.setBlock(Blocks.air); + } + } + } - /**Raycast, but with world coordinates.*/ - public GridPoint2 raycastWorld(float x, float y, float x2, float y2){ - return raycast(Mathf.scl2(x, tilesize), Mathf.scl2(y, tilesize), - Mathf.scl2(x2, tilesize), Mathf.scl2(y2, tilesize)); - } - - /**Input is in block coordinates, not world coordinates. - * @return null if no collisions found, block position otherwise.*/ - public GridPoint2 raycast(int x0f, int y0f, int x1, int y1){ - int x0 = x0f; - int y0 = y0f; - int dx = Math.abs(x1 - x0); - int dy = Math.abs(y1 - y0); + public void setBlock(Tile tile, Block block, Team team){ + tile.setBlock(block); + if(block.isMultiblock()){ + int offsetx = -(block.size - 1) / 2; + int offsety = -(block.size - 1) / 2; - int sx = x0 < x1 ? 1 : -1; - int sy = y0 < y1 ? 1 : -1; + for(int dx = 0; dx < block.size; dx++){ + for(int dy = 0; dy < block.size; dy++){ + int worldx = dx + offsetx + tile.x; + int worldy = dy + offsety + tile.y; + if(!(worldx == tile.x && worldy == tile.y)){ + Tile toplace = world.tile(worldx, worldy); + if(toplace != null){ + toplace.setLinked((byte) (dx + offsetx), (byte) (dy + offsety)); + toplace.setTeam(team); + } + } + } + } + } + } - int err = dx - dy; - int e2; - while(true){ + /** + * Raycast, but with world coordinates. + */ + public GridPoint2 raycastWorld(float x, float y, float x2, float y2){ + return raycast(Mathf.scl2(x, tilesize), Mathf.scl2(y, tilesize), + Mathf.scl2(x2, tilesize), Mathf.scl2(y2, tilesize)); + } - if(!passable(x0, y0)){ - return Tmp.g1.set(x0, y0); - } - if(x0 == x1 && y0 == y1) break; + /** + * Input is in block coordinates, not world coordinates. + * + * @return null if no collisions found, block position otherwise. + */ + public GridPoint2 raycast(int x0f, int y0f, int x1, int y1){ + int x0 = x0f; + int y0 = y0f; + int dx = Math.abs(x1 - x0); + int dy = Math.abs(y1 - y0); - e2 = 2 * err; - if(e2 > -dy){ - err = err - dy; - x0 = x0 + sx; - } + int sx = x0 < x1 ? 1 : -1; + int sy = y0 < y1 ? 1 : -1; - if(e2 < dx){ - err = err + dx; - y0 = y0 + sy; - } - } - return null; - } + int err = dx - dy; + int e2; + while(true){ - public void raycastEach(int x0f, int y0f, int x1, int y1, Raycaster cons){ - int x0 = x0f; - int y0 = y0f; - int dx = Math.abs(x1 - x0); - int dy = Math.abs(y1 - y0); + if(!passable(x0, y0)){ + return Tmp.g1.set(x0, y0); + } + if(x0 == x1 && y0 == y1) break; - int sx = x0 < x1 ? 1 : -1; - int sy = y0 < y1 ? 1 : -1; + e2 = 2 * err; + if(e2 > -dy){ + err = err - dy; + x0 = x0 + sx; + } - int err = dx - dy; - int e2; - while(true){ + if(e2 < dx){ + err = err + dx; + y0 = y0 + sy; + } + } + return null; + } - if(cons.accept(x0, y0)) break; - if(x0 == x1 && y0 == y1) break; + public void raycastEach(int x0f, int y0f, int x1, int y1, Raycaster cons){ + int x0 = x0f; + int y0 = y0f; + int dx = Math.abs(x1 - x0); + int dy = Math.abs(y1 - y0); - e2 = 2 * err; - if(e2 > -dy){ - err = err - dy; - x0 = x0 + sx; - } + int sx = x0 < x1 ? 1 : -1; + int sy = y0 < y1 ? 1 : -1; - if(e2 < dx){ - err = err + dx; - y0 = y0 + sy; - } - } - } + int err = dx - dy; + int e2; + while(true){ - public interface Raycaster{ - boolean accept(int x, int y); - } + if(cons.accept(x0, y0)) break; + if(x0 == x1 && y0 == y1) break; + + e2 = 2 * err; + if(e2 > -dy){ + err = err - dy; + x0 = x0 + sx; + } + + if(e2 < dx){ + err = err + dx; + y0 = y0 + sy; + } + } + } + + public interface Raycaster{ + boolean accept(int x, int y); + } } diff --git a/core/src/io/anuke/mindustry/editor/DrawOperation.java b/core/src/io/anuke/mindustry/editor/DrawOperation.java index 56fad5c41d..421a34bd6c 100755 --- a/core/src/io/anuke/mindustry/editor/DrawOperation.java +++ b/core/src/io/anuke/mindustry/editor/DrawOperation.java @@ -7,60 +7,66 @@ import io.anuke.mindustry.io.MapTileData.TileDataMarker; import io.anuke.ucore.util.Bits; public class DrawOperation{ - /**Data to apply operation to.*/ - private MapTileData data; - /**List of per-tile operations that occurred.*/ - private Array operations = new Array<>(); - /**Checks for duplicate operations, useful for brushes.*/ - private IntSet checks = new IntSet(); + /** + * Data to apply operation to. + */ + private MapTileData data; + /** + * List of per-tile operations that occurred. + */ + private Array operations = new Array<>(); + /** + * Checks for duplicate operations, useful for brushes. + */ + private IntSet checks = new IntSet(); - public DrawOperation(MapTileData data){ - this.data = data; - } + public DrawOperation(MapTileData data){ + this.data = data; + } - public boolean isEmpty(){ - return operations.size == 0; - } + public boolean isEmpty(){ + return operations.size == 0; + } - public boolean checkDuplicate(short x, short y){ - int i = Bits.packInt(x, y); - if(checks.contains(i)) return true; + public boolean checkDuplicate(short x, short y){ + int i = Bits.packInt(x, y); + if(checks.contains(i)) return true; - checks.add(i); - return false; - } + checks.add(i); + return false; + } - public void addOperation(TileOperation op){ - operations.add(op); - } + public void addOperation(TileOperation op){ + operations.add(op); + } - public void undo(MapEditor editor) { - for(int i = operations.size - 1; i >= 0; i --){ - TileOperation op = operations.get(i); - data.position(op.x, op.y); - data.write(op.from); - editor.renderer().updatePoint(op.x, op.y); - } - } + public void undo(MapEditor editor){ + for(int i = operations.size - 1; i >= 0; i--){ + TileOperation op = operations.get(i); + data.position(op.x, op.y); + data.write(op.from); + editor.renderer().updatePoint(op.x, op.y); + } + } - public void redo(MapEditor editor) { - for(TileOperation op : operations){ - data.position(op.x, op.y); - data.write(op.to); - editor.renderer().updatePoint(op.x, op.y); - } - } + public void redo(MapEditor editor){ + for(TileOperation op : operations){ + data.position(op.x, op.y); + data.write(op.to); + editor.renderer().updatePoint(op.x, op.y); + } + } - public static class TileOperation{ - public short x, y; - public TileDataMarker from; - public TileDataMarker to; + public static class TileOperation{ + public short x, y; + public TileDataMarker from; + public TileDataMarker to; - public TileOperation(short x, short y, TileDataMarker from, TileDataMarker to) { - this.x = x; - this.y = y; - this.from = from; - this.to = to; - } - } + public TileOperation(short x, short y, TileDataMarker from, TileDataMarker to){ + this.x = x; + this.y = y; + this.from = from; + this.to = to; + } + } } diff --git a/core/src/io/anuke/mindustry/editor/EditorTool.java b/core/src/io/anuke/mindustry/editor/EditorTool.java index c1bfe98750..70c69897e1 100644 --- a/core/src/io/anuke/mindustry/editor/EditorTool.java +++ b/core/src/io/anuke/mindustry/editor/EditorTool.java @@ -12,132 +12,132 @@ import io.anuke.ucore.util.Bits; import static io.anuke.mindustry.Vars.ui; public enum EditorTool{ - pick{ - public void touched(MapEditor editor, int x, int y){ - byte bf = editor.getMap().read(x, y, DataPosition.floor); - byte bw = editor.getMap().read(x, y, DataPosition.wall); - byte link = editor.getMap().read(x, y, DataPosition.link); + pick{ + public void touched(MapEditor editor, int x, int y){ + byte bf = editor.getMap().read(x, y, DataPosition.floor); + byte bw = editor.getMap().read(x, y, DataPosition.wall); + byte link = editor.getMap().read(x, y, DataPosition.link); - if(link != 0){ - x -= (Bits.getLeftByte(link) - 8); - y -= (Bits.getRightByte(link) - 8); - bf = editor.getMap().read(x, y, DataPosition.floor); - bw = editor.getMap().read(x, y, DataPosition.wall); - } + if(link != 0){ + x -= (Bits.getLeftByte(link) - 8); + y -= (Bits.getRightByte(link) - 8); + bf = editor.getMap().read(x, y, DataPosition.floor); + bw = editor.getMap().read(x, y, DataPosition.wall); + } - Block block = Block.getByID(bw == 0 ? bf : bw); - editor.setDrawBlock(block); - ui.editor.updateSelectedBlock(); - } - }, - pencil{ - { - edit = true; - draggable = true; - } + Block block = Block.getByID(bw == 0 ? bf : bw); + editor.setDrawBlock(block); + ui.editor.updateSelectedBlock(); + } + }, + pencil{ + { + edit = true; + draggable = true; + } - @Override - public void touched(MapEditor editor, int x, int y){ - editor.draw(x, y); - } - }, - eraser{ - { - edit = true; - draggable = true; - } + @Override + public void touched(MapEditor editor, int x, int y){ + editor.draw(x, y); + } + }, + eraser{ + { + edit = true; + draggable = true; + } - @Override - public void touched(MapEditor editor, int x, int y){ - editor.draw(x, y, Blocks.air); - } - }, - elevation{ - { - edit = true; - draggable = true; - } + @Override + public void touched(MapEditor editor, int x, int y){ + editor.draw(x, y, Blocks.air); + } + }, + elevation{ + { + edit = true; + draggable = true; + } - @Override - public void touched(MapEditor editor, int x, int y){ - editor.elevate(x, y); - } - }, - line{ - { + @Override + public void touched(MapEditor editor, int x, int y){ + editor.elevate(x, y); + } + }, + line{ + { - } - }, - fill{ - { - edit = true; - } - - public void touched(MapEditor editor, int x, int y){ - if(editor.getDrawBlock().isMultiblock()){ - //don't fill multiblocks, thanks - pencil.touched(editor, x, y); - return; - } + } + }, + fill{ + { + edit = true; + } - boolean floor = editor.getDrawBlock() instanceof Floor; + public void touched(MapEditor editor, int x, int y){ + if(editor.getDrawBlock().isMultiblock()){ + //don't fill multiblocks, thanks + pencil.touched(editor, x, y); + return; + } - byte bf = editor.getMap().read(x, y, DataPosition.floor); - byte bw = editor.getMap().read(x, y, DataPosition.wall); - boolean synth = editor.getDrawBlock().synthetic(); - byte brt = Bits.packByte((byte)editor.getDrawRotation(), (byte)editor.getDrawTeam().ordinal()); + boolean floor = editor.getDrawBlock() instanceof Floor; - byte dest = floor ? bf: bw; - byte draw = (byte)editor.getDrawBlock().id; + byte bf = editor.getMap().read(x, y, DataPosition.floor); + byte bw = editor.getMap().read(x, y, DataPosition.wall); + boolean synth = editor.getDrawBlock().synthetic(); + byte brt = Bits.packByte((byte) editor.getDrawRotation(), (byte) editor.getDrawTeam().ordinal()); - int width = editor.getMap().width(); - int height = editor.getMap().height(); + byte dest = floor ? bf : bw; + byte draw = (byte) editor.getDrawBlock().id; - IntSet set = new IntSet(); - IntArray points = new IntArray(); - points.add(asInt(x, y, editor.getMap().width())); + int width = editor.getMap().width(); + int height = editor.getMap().height(); - while(points.size != 0){ - int pos = points.pop(); - int px = pos % width; - int py = pos / width; - set.add(pos); + IntSet set = new IntSet(); + IntArray points = new IntArray(); + points.add(asInt(x, y, editor.getMap().width())); - byte nbf = editor.getMap().read(px, py, DataPosition.floor); - byte nbw = editor.getMap().read(px, py, DataPosition.wall); + while(points.size != 0){ + int pos = points.pop(); + int px = pos % width; + int py = pos / width; + set.add(pos); - if((floor ? nbf : nbw) == dest){ - TileDataMarker prev = editor.getPrev(px, py, false); + byte nbf = editor.getMap().read(px, py, DataPosition.floor); + byte nbw = editor.getMap().read(px, py, DataPosition.wall); - if(floor) { - editor.getMap().write(px, py, DataPosition.floor, draw); - }else { - editor.getMap().write(px, py, DataPosition.wall, draw); - } + if((floor ? nbf : nbw) == dest){ + TileDataMarker prev = editor.getPrev(px, py, false); - if(synth){ - editor.getMap().write(px, py, DataPosition.rotationTeam, brt); - } + if(floor){ + editor.getMap().write(px, py, DataPosition.floor, draw); + }else{ + editor.getMap().write(px, py, DataPosition.wall, draw); + } - if(px > 0 && !set.contains(asInt(px - 1, py, width))) points.add(asInt(px - 1, py, width)); - if(py > 0 && !set.contains(asInt(px, py - 1, width))) points.add(asInt(px, py - 1, width)); - if(px < width - 1 && !set.contains(asInt(px + 1, py, width))) points.add(asInt(px + 1, py, width)); - if(py < height - 1 && !set.contains(asInt(px, py + 1, width))) points.add(asInt(px, py + 1, width)); + if(synth){ + editor.getMap().write(px, py, DataPosition.rotationTeam, brt); + } - editor.onWrite(px, py, prev); - } - } - } - - int asInt(int x, int y, int width){ - return x+y*width; - } - }, - zoom; + if(px > 0 && !set.contains(asInt(px - 1, py, width))) points.add(asInt(px - 1, py, width)); + if(py > 0 && !set.contains(asInt(px, py - 1, width))) points.add(asInt(px, py - 1, width)); + if(px < width - 1 && !set.contains(asInt(px + 1, py, width))) points.add(asInt(px + 1, py, width)); + if(py < height - 1 && !set.contains(asInt(px, py + 1, width))) points.add(asInt(px, py + 1, width)); - boolean edit, draggable; - - public void touched(MapEditor editor, int x, int y){ - - } + editor.onWrite(px, py, prev); + } + } + } + + int asInt(int x, int y, int width){ + return x + y * width; + } + }, + zoom; + + boolean edit, draggable; + + public void touched(MapEditor editor, int x, int y){ + + } } diff --git a/core/src/io/anuke/mindustry/editor/MapEditor.java b/core/src/io/anuke/mindustry/editor/MapEditor.java index 6ad61bd62c..9d7c2fc44e 100644 --- a/core/src/io/anuke/mindustry/editor/MapEditor.java +++ b/core/src/io/anuke/mindustry/editor/MapEditor.java @@ -14,267 +14,267 @@ import io.anuke.ucore.util.Bits; import io.anuke.ucore.util.Mathf; public class MapEditor{ - public static final int minMapSize = 128, maxMapSize = 512; - public static final int[] brushSizes = {1, 2, 3, 4, 5, 9, 15}; - - private MapTileData map; - private ObjectMap tags = new ObjectMap<>(); - private MapRenderer renderer = new MapRenderer(this); + public static final int minMapSize = 128, maxMapSize = 512; + public static final int[] brushSizes = {1, 2, 3, 4, 5, 9, 15}; - private int brushSize = 1; - private byte elevation; - private int rotation; - private Block drawBlock = Blocks.stone; - private Team drawTeam = Team.none; - - public MapEditor(){ + private MapTileData map; + private ObjectMap tags = new ObjectMap<>(); + private MapRenderer renderer = new MapRenderer(this); - } - - public MapTileData getMap(){ - return map; - } + private int brushSize = 1; + private byte elevation; + private int rotation; + private Block drawBlock = Blocks.stone; + private Team drawTeam = Team.none; - public ObjectMap getTags() { - return tags; - } + public MapEditor(){ - public void beginEdit(MapTileData map, ObjectMap tags, boolean clear){ - this.map = map; - this.brushSize = 1; - this.tags = tags; + } - if(clear) { - for (int x = 0; x < map.width(); x++) { - for (int y = 0; y < map.height(); y++) { - map.write(x, y, DataPosition.floor, (byte) Blocks.stone.id); - } - } - } + public MapTileData getMap(){ + return map; + } - drawBlock = Blocks.stone; - renderer.resize(map.width(), map.height()); - } + public ObjectMap getTags(){ + return tags; + } - public void setDrawElevation(int elevation){ - this.elevation = (byte)elevation; - } + public void beginEdit(MapTileData map, ObjectMap tags, boolean clear){ + this.map = map; + this.brushSize = 1; + this.tags = tags; - public byte getDrawElevation(){ - return elevation; - } + if(clear){ + for(int x = 0; x < map.width(); x++){ + for(int y = 0; y < map.height(); y++){ + map.write(x, y, DataPosition.floor, (byte) Blocks.stone.id); + } + } + } - public int getDrawRotation(){ - return rotation; - } + drawBlock = Blocks.stone; + renderer.resize(map.width(), map.height()); + } - public void setDrawRotation(int rotation){ - this.rotation = rotation; - } + public byte getDrawElevation(){ + return elevation; + } - public void setDrawTeam(Team team){ - this.drawTeam = team; - } + public void setDrawElevation(int elevation){ + this.elevation = (byte) elevation; + } - public Team getDrawTeam() { - return drawTeam; - } + public int getDrawRotation(){ + return rotation; + } - public Block getDrawBlock(){ - return drawBlock; - } - - public void setDrawBlock(Block block){ - this.drawBlock = block; - } - - public void setBrushSize(int size){ - this.brushSize = size; - } + public void setDrawRotation(int rotation){ + this.rotation = rotation; + } - public int getBrushSize() { - return brushSize; - } + public Team getDrawTeam(){ + return drawTeam; + } - public void draw(int x, int y){ - draw(x, y, drawBlock); - } + public void setDrawTeam(Team team){ + this.drawTeam = team; + } - public void draw(int x, int y, Block drawBlock){ - if(x < 0 || y < 0 || x >= map.width() || y >= map.height()){ - return; - } + public Block getDrawBlock(){ + return drawBlock; + } - byte writeID = (byte)drawBlock.id; - byte partID = (byte)Blocks.blockpart.id; - byte rotationTeam = Bits.packByte(drawBlock.rotate ? (byte)rotation : 0, drawBlock.synthetic() ? (byte)drawTeam.ordinal() : 0); + public void setDrawBlock(Block block){ + this.drawBlock = block; + } - boolean isfloor = drawBlock instanceof Floor && drawBlock != Blocks.air; + public int getBrushSize(){ + return brushSize; + } - if(drawBlock.isMultiblock()) { + public void setBrushSize(int size){ + this.brushSize = size; + } - int offsetx = -(drawBlock.size - 1) / 2; - int offsety = -(drawBlock.size - 1) / 2; + public void draw(int x, int y){ + draw(x, y, drawBlock); + } - for(int i = 0; i < 2; i ++){ - for (int dx = 0; dx < drawBlock.size; dx++) { - for (int dy = 0; dy < drawBlock.size; dy++) { - int worldx = dx + offsetx + x; - int worldy = dy + offsety + y; + public void draw(int x, int y, Block drawBlock){ + if(x < 0 || y < 0 || x >= map.width() || y >= map.height()){ + return; + } - if (Mathf.inBounds(worldx, worldy, map.width(), map.height())) { - TileDataMarker prev = getPrev(worldx, worldy, false); + byte writeID = (byte) drawBlock.id; + byte partID = (byte) Blocks.blockpart.id; + byte rotationTeam = Bits.packByte(drawBlock.rotate ? (byte) rotation : 0, drawBlock.synthetic() ? (byte) drawTeam.ordinal() : 0); - if(i == 1) { - map.write(worldx, worldy, DataPosition.wall, partID); - map.write(worldx, worldy, DataPosition.rotationTeam, rotationTeam); - map.write(worldx, worldy, DataPosition.link, Bits.packByte((byte) (dx + offsetx + 8), (byte) (dy + offsety + 8))); - }else{ - byte link = map.read(worldx, worldy, DataPosition.link); - byte block = map.read(worldx, worldy, DataPosition.wall); + boolean isfloor = drawBlock instanceof Floor && drawBlock != Blocks.air; - if (link != 0) { - removeLinked(worldx - (Bits.getLeftByte(link) - 8), worldy - (Bits.getRightByte(link) - 8)); - }else if(Block.getByID(block).isMultiblock()){ - removeLinked(worldx, worldy); - } - } + if(drawBlock.isMultiblock()){ - onWrite(worldx, worldy, prev); - } - } - } - } + int offsetx = -(drawBlock.size - 1) / 2; + int offsety = -(drawBlock.size - 1) / 2; - TileDataMarker prev = getPrev(x, y, false); + for(int i = 0; i < 2; i++){ + for(int dx = 0; dx < drawBlock.size; dx++){ + for(int dy = 0; dy < drawBlock.size; dy++){ + int worldx = dx + offsetx + x; + int worldy = dy + offsety + y; - map.write(x, y, DataPosition.wall, writeID); - map.write(x, y, DataPosition.link, (byte)0); - map.write(x, y, DataPosition.rotationTeam, rotationTeam); + if(Mathf.inBounds(worldx, worldy, map.width(), map.height())){ + TileDataMarker prev = getPrev(worldx, worldy, false); - onWrite(x, y, prev); - }else{ + if(i == 1){ + map.write(worldx, worldy, DataPosition.wall, partID); + map.write(worldx, worldy, DataPosition.rotationTeam, rotationTeam); + map.write(worldx, worldy, DataPosition.link, Bits.packByte((byte) (dx + offsetx + 8), (byte) (dy + offsety + 8))); + }else{ + byte link = map.read(worldx, worldy, DataPosition.link); + byte block = map.read(worldx, worldy, DataPosition.wall); - for (int rx = -brushSize; rx <= brushSize; rx++) { - for (int ry = -brushSize; ry <= brushSize; ry++) { - if (Mathf.dst(rx, ry) <= brushSize - 0.5f) { - int wx = x + rx, wy = y + ry; + if(link != 0){ + removeLinked(worldx - (Bits.getLeftByte(link) - 8), worldy - (Bits.getRightByte(link) - 8)); + }else if(Block.getByID(block).isMultiblock()){ + removeLinked(worldx, worldy); + } + } - if (wx < 0 || wy < 0 || wx >= map.width() || wy >= map.height()) { - continue; - } + onWrite(worldx, worldy, prev); + } + } + } + } - TileDataMarker prev = getPrev(wx, wy, true); + TileDataMarker prev = getPrev(x, y, false); - if(!isfloor) { - byte link = map.read(wx, wy, DataPosition.link); + map.write(x, y, DataPosition.wall, writeID); + map.write(x, y, DataPosition.link, (byte) 0); + map.write(x, y, DataPosition.rotationTeam, rotationTeam); - if (link != 0) { - removeLinked(wx - (Bits.getLeftByte(link) - 8), wy - (Bits.getRightByte(link) - 8)); - } - } + onWrite(x, y, prev); + }else{ - if(isfloor){ - map.write(wx, wy, DataPosition.floor, writeID); - map.write(wx, wy, DataPosition.elevation, elevation); - }else{ - map.write(wx, wy, DataPosition.wall, writeID); - map.write(wx, wy, DataPosition.link, (byte)0); - map.write(wx, wy, DataPosition.rotationTeam, rotationTeam); - } + for(int rx = -brushSize; rx <= brushSize; rx++){ + for(int ry = -brushSize; ry <= brushSize; ry++){ + if(Mathf.dst(rx, ry) <= brushSize - 0.5f){ + int wx = x + rx, wy = y + ry; - onWrite(x + rx, y + ry, prev); - } - } - } - } - } + if(wx < 0 || wy < 0 || wx >= map.width() || wy >= map.height()){ + continue; + } - public void elevate(int x, int y){ - if(x < 0 || y < 0 || x >= map.width() || y >= map.height()){ - return; - } + TileDataMarker prev = getPrev(wx, wy, true); - for (int rx = -brushSize; rx <= brushSize; rx++) { - for (int ry = -brushSize; ry <= brushSize; ry++) { - if (Mathf.dst(rx, ry) <= brushSize - 0.5f) { - int wx = x + rx, wy = y + ry; + if(!isfloor){ + byte link = map.read(wx, wy, DataPosition.link); - if (wx < 0 || wy < 0 || wx >= map.width() || wy >= map.height()) { - continue; - } + if(link != 0){ + removeLinked(wx - (Bits.getLeftByte(link) - 8), wy - (Bits.getRightByte(link) - 8)); + } + } - TileDataMarker prev = getPrev(wx, wy, true); + if(isfloor){ + map.write(wx, wy, DataPosition.floor, writeID); + map.write(wx, wy, DataPosition.elevation, elevation); + }else{ + map.write(wx, wy, DataPosition.wall, writeID); + map.write(wx, wy, DataPosition.link, (byte) 0); + map.write(wx, wy, DataPosition.rotationTeam, rotationTeam); + } - map.write(wx, wy, DataPosition.elevation, elevation); + onWrite(x + rx, y + ry, prev); + } + } + } + } + } - onWrite(x + rx, y + ry, prev); - } - } - } - } + public void elevate(int x, int y){ + if(x < 0 || y < 0 || x >= map.width() || y >= map.height()){ + return; + } - private void removeLinked(int x, int y){ - Block block = Block.getByID(map.read(x, y, DataPosition.wall)); + for(int rx = -brushSize; rx <= brushSize; rx++){ + for(int ry = -brushSize; ry <= brushSize; ry++){ + if(Mathf.dst(rx, ry) <= brushSize - 0.5f){ + int wx = x + rx, wy = y + ry; - int offsetx = -(block.size-1)/2; - int offsety = -(block.size-1)/2; - for(int dx = 0; dx < block.size; dx ++){ - for(int dy = 0; dy < block.size; dy ++){ - int worldx = x + dx + offsetx, worldy = y + dy + offsety; - if(Mathf.inBounds(worldx, worldy, map.width(), map.height())){ - TileDataMarker prev = getPrev(worldx, worldy, false); + if(wx < 0 || wy < 0 || wx >= map.width() || wy >= map.height()){ + continue; + } - map.write(worldx, worldy, DataPosition.link, (byte)0); - map.write(worldx, worldy, DataPosition.rotationTeam, (byte)0); - map.write(worldx, worldy, DataPosition.wall, (byte)0); + TileDataMarker prev = getPrev(wx, wy, true); - onWrite(worldx, worldy, prev); - } - } - } - } + map.write(wx, wy, DataPosition.elevation, elevation); - boolean checkDupes(int x, int y){ - return Vars.ui.editor.getView().checkForDuplicates((short) x, (short) y); - } + onWrite(x + rx, y + ry, prev); + } + } + } + } - void onWrite(int x, int y, TileDataMarker previous){ - if(previous == null){ - renderer.updatePoint(x, y); - return; - } + private void removeLinked(int x, int y){ + Block block = Block.getByID(map.read(x, y, DataPosition.wall)); - TileDataMarker current = map.new TileDataMarker(); - map.position(x, y); - map.read(current); + int offsetx = -(block.size - 1) / 2; + int offsety = -(block.size - 1) / 2; + for(int dx = 0; dx < block.size; dx++){ + for(int dy = 0; dy < block.size; dy++){ + int worldx = x + dx + offsetx, worldy = y + dy + offsety; + if(Mathf.inBounds(worldx, worldy, map.width(), map.height())){ + TileDataMarker prev = getPrev(worldx, worldy, false); - Vars.ui.editor.getView().addTileOp(new TileOperation((short) x, (short) y, previous, current)); - renderer.updatePoint(x, y); - } + map.write(worldx, worldy, DataPosition.link, (byte) 0); + map.write(worldx, worldy, DataPosition.rotationTeam, (byte) 0); + map.write(worldx, worldy, DataPosition.wall, (byte) 0); - TileDataMarker getPrev(int x, int y, boolean checkDupes){ - if(checkDupes && checkDupes(x, y)){ - return null; - }else{ - TileDataMarker marker = map.newDataMarker(); - map.position(x, y); - map.read(marker); - return marker; - } - } + onWrite(worldx, worldy, prev); + } + } + } + } - public MapRenderer renderer() { - return renderer; - } + boolean checkDupes(int x, int y){ + return Vars.ui.editor.getView().checkForDuplicates((short) x, (short) y); + } - public void resize(int width, int height){ - map = new MapTileData(width, height); - for (int x = 0; x < map.width(); x++) { - for (int y = 0; y < map.height(); y++) { - map.write(x, y, DataPosition.floor, (byte)Blocks.stone.id); - } - } - renderer.resize(width, height); - } + void onWrite(int x, int y, TileDataMarker previous){ + if(previous == null){ + renderer.updatePoint(x, y); + return; + } + + TileDataMarker current = map.new TileDataMarker(); + map.position(x, y); + map.read(current); + + Vars.ui.editor.getView().addTileOp(new TileOperation((short) x, (short) y, previous, current)); + renderer.updatePoint(x, y); + } + + TileDataMarker getPrev(int x, int y, boolean checkDupes){ + if(checkDupes && checkDupes(x, y)){ + return null; + }else{ + TileDataMarker marker = map.newDataMarker(); + map.position(x, y); + map.read(marker); + return marker; + } + } + + public MapRenderer renderer(){ + return renderer; + } + + public void resize(int width, int height){ + map = new MapTileData(width, height); + for(int x = 0; x < map.width(); x++){ + for(int y = 0; y < map.height(); y++){ + map.write(x, y, DataPosition.floor, (byte) Blocks.stone.id); + } + } + renderer.resize(width, height); + } } diff --git a/core/src/io/anuke/mindustry/editor/MapEditorDialog.java b/core/src/io/anuke/mindustry/editor/MapEditorDialog.java index 25c3191b95..f004d59c63 100644 --- a/core/src/io/anuke/mindustry/editor/MapEditorDialog.java +++ b/core/src/io/anuke/mindustry/editor/MapEditorDialog.java @@ -48,72 +48,72 @@ import java.io.InputStream; import static io.anuke.mindustry.Vars.*; public class MapEditorDialog extends Dialog implements Disposable{ - private MapEditor editor; - private MapView view; - private MapInfoDialog infoDialog; - private MapLoadDialog loadDialog; - private MapResizeDialog resizeDialog; - private ScrollPane pane; - private FloatingDialog menu; - private boolean saved = false; - private boolean shownWithMap = false; - - private ButtonGroup blockgroup; - - public MapEditorDialog(){ - super("$text.mapeditor", "dialog"); + private MapEditor editor; + private MapView view; + private MapInfoDialog infoDialog; + private MapLoadDialog loadDialog; + private MapResizeDialog resizeDialog; + private ScrollPane pane; + private FloatingDialog menu; + private boolean saved = false; + private boolean shownWithMap = false; - editor = new MapEditor(); - view = new MapView(editor); + private ButtonGroup blockgroup; - infoDialog = new MapInfoDialog(editor); + public MapEditorDialog(){ + super("$text.mapeditor", "dialog"); - menu = new FloatingDialog("$text.menu"); - menu.addCloseButton(); + editor = new MapEditor(); + view = new MapView(editor); - float isize = 16*2f; - float swidth = 180f; + infoDialog = new MapInfoDialog(editor); - menu.content().table(t -> { - t.defaults().size(swidth, 60f).padBottom(5).padRight(5).padLeft(5); + menu = new FloatingDialog("$text.menu"); + menu.addCloseButton(); - t.addImageTextButton("$text.editor.savemap", "icon-floppy-16", isize, this::save).size(swidth*2f + 10, 60f).colspan(2); + float isize = 16 * 2f; + float swidth = 180f; - t.row(); + menu.content().table(t -> { + t.defaults().size(swidth, 60f).padBottom(5).padRight(5).padLeft(5); - t.addImageTextButton("$text.editor.mapinfo", "icon-pencil", isize, () -> { - infoDialog.show(); - menu.hide(); - }); + t.addImageTextButton("$text.editor.savemap", "icon-floppy-16", isize, this::save).size(swidth * 2f + 10, 60f).colspan(2); - t.addImageTextButton("$text.editor.resize", "icon-resize", isize, () -> { - resizeDialog.show(); - menu.hide(); - }); + t.row(); - t.row(); + t.addImageTextButton("$text.editor.mapinfo", "icon-pencil", isize, () -> { + infoDialog.show(); + menu.hide(); + }); - t.addImageTextButton("$text.editor.import", "icon-load-map", isize, () -> - createDialog("$text.editor.import", - "$text.editor.importmap", "$text.editor.importmap.description", "icon-load-map", (Listenable)loadDialog::show, - "$text.editor.importfile", "$text.editor.importfile.description", "icon-file", (Listenable)() -> { - Platform.instance.showFileChooser("$text.loadimage", "Map Files", file -> { - ui.loadAnd(() -> { - try{ - DataInputStream stream = new DataInputStream(file.read()); + t.addImageTextButton("$text.editor.resize", "icon-resize", isize, () -> { + resizeDialog.show(); + menu.hide(); + }); - MapMeta meta = MapIO.readMapMeta(stream); - MapTileData data = MapIO.readTileData(stream, meta, false); + t.row(); - editor.beginEdit(data, meta.tags, false); - view.clearStack(); - }catch (Exception e){ - ui.showError(Bundles.format("text.editor.errorimageload", Strings.parseException(e, false))); - Log.err(e); - } - }); - }, true, mapExtension); - }/*, + t.addImageTextButton("$text.editor.import", "icon-load-map", isize, () -> + createDialog("$text.editor.import", + "$text.editor.importmap", "$text.editor.importmap.description", "icon-load-map", (Listenable) loadDialog::show, + "$text.editor.importfile", "$text.editor.importfile.description", "icon-file", (Listenable) () -> { + Platform.instance.showFileChooser("$text.loadimage", "Map Files", file -> { + ui.loadAnd(() -> { + try{ + DataInputStream stream = new DataInputStream(file.read()); + + MapMeta meta = MapIO.readMapMeta(stream); + MapTileData data = MapIO.readTileData(stream, meta, false); + + editor.beginEdit(data, meta.tags, false); + view.clearStack(); + }catch(Exception e){ + ui.showError(Bundles.format("text.editor.errorimageload", Strings.parseException(e, false))); + Log.err(e); + } + }); + }, true, mapExtension); + }/*, "$text.editor.importimage", "$text.editor.importimage.description", "icon-file-image", (Listenable)() -> { if(gwt){ ui.showError("$text.web.unsupported"); @@ -134,36 +134,36 @@ public class MapEditorDialog extends Dialog implements Disposable{ } }*/)); - t.addImageTextButton("$text.editor.export", "icon-save-map", isize, () -> createDialog("$text.editor.export", - "$text.editor.exportfile", "$text.editor.exportfile.description", "icon-file", (Listenable)() -> { - if(!gwt) { - Platform.instance.showFileChooser("$text.saveimage", "Map Files", file -> { - file = file.parent().child(file.nameWithoutExtension() + "." + mapExtension); - FileHandle result = file; - ui.loadAnd(() -> { + t.addImageTextButton("$text.editor.export", "icon-save-map", isize, () -> createDialog("$text.editor.export", + "$text.editor.exportfile", "$text.editor.exportfile.description", "icon-file", (Listenable) () -> { + if(!gwt){ + Platform.instance.showFileChooser("$text.saveimage", "Map Files", file -> { + file = file.parent().child(file.nameWithoutExtension() + "." + mapExtension); + FileHandle result = file; + ui.loadAnd(() -> { - try { - if (!editor.getTags().containsKey("name")) { - editor.getTags().put("name", result.nameWithoutExtension()); - } - MapIO.writeMap(result.write(false), editor.getTags(), editor.getMap()); - } catch (Exception e) { - ui.showError(Bundles.format("text.editor.errorimagesave", Strings.parseException(e, false))); - Log.err(e); - } - }); - }, false, mapExtension); - }else{ - try { - ByteArrayOutputStream ba = new ByteArrayOutputStream(); - MapIO.writeMap(ba, editor.getTags(), editor.getMap()); - Platform.instance.downloadFile(editor.getTags().get("name", "unknown") + "." + mapExtension, ba.toByteArray()); - }catch (IOException e){ - ui.showError(Bundles.format("text.editor.errorimagesave", Strings.parseException(e, false))); - Log.err(e); - } - } - }/*, + try{ + if(!editor.getTags().containsKey("name")){ + editor.getTags().put("name", result.nameWithoutExtension()); + } + MapIO.writeMap(result.write(false), editor.getTags(), editor.getMap()); + }catch(Exception e){ + ui.showError(Bundles.format("text.editor.errorimagesave", Strings.parseException(e, false))); + Log.err(e); + } + }); + }, false, mapExtension); + }else{ + try{ + ByteArrayOutputStream ba = new ByteArrayOutputStream(); + MapIO.writeMap(ba, editor.getTags(), editor.getMap()); + Platform.instance.downloadFile(editor.getTags().get("name", "unknown") + "." + mapExtension, ba.toByteArray()); + }catch(IOException e){ + ui.showError(Bundles.format("text.editor.errorimagesave", Strings.parseException(e, false))); + Log.err(e); + } + } + }/*, "$text.editor.exportimage", "$text.editor.exportimage.description", "icon-file-image", (Listenable)() -> { if(gwt){ ui.showError("$text.web.unsupported"); @@ -183,438 +183,441 @@ public class MapEditorDialog extends Dialog implements Disposable{ } }*/)); - t.row(); - - t.row(); - }); - - menu.content().row(); - - menu.content().addImageTextButton("$text.quit", "icon-back", isize, () -> { - tryExit(); - menu.hide(); - }).padTop(-5).size(swidth*2f + 10, 60f); - - resizeDialog = new MapResizeDialog(editor, (x, y) -> { - if(!(editor.getMap().width() == x && editor.getMap().height() == y)){ - ui.loadAnd(() -> { - editor.resize(x, y); - view.clearStack(); - }); - } - }); - - loadDialog = new MapLoadDialog(map -> { - - ui.loadAnd(() -> { - try (DataInputStream stream = new DataInputStream(map.stream.get())){ - MapMeta meta = MapIO.readMapMeta(stream); - MapTileData data = MapIO.readTileData(stream, meta, false); - - editor.beginEdit(data, meta.tags, false); - view.clearStack(); - }catch (IOException e){ - ui.showError(Bundles.format("text.editor.errormapload", Strings.parseException(e, false))); - Log.err(e); - } - }); - }); - - setFillParent(true); - - clearChildren(); - margin(0); - build.begin(this); - build(); - build.end(); - - update(() -> { - if(Core.scene.getKeyboardFocus() instanceof Dialog && Core.scene.getKeyboardFocus() != this) { - return; - } - - Vector2 v = pane.stageToLocalCoordinates(Graphics.mouse()); - - if(v.x >= 0 && v.y >= 0 && v.x <= pane.getWidth() && v.y <= pane.getHeight()){ - Core.scene.setScrollFocus(pane); - }else{ - Core.scene.setScrollFocus(null); - } - - if(Core.scene != null && Core.scene.getKeyboardFocus() == this){ - doInput(); - } - }); - - shown(() -> { - saved = true; - Platform.instance.beginForceLandscape(); - view.clearStack(); - Core.scene.setScrollFocus(view); - if(!shownWithMap){ - editor.beginEdit(new MapTileData(256, 256), new ObjectMap<>(), true); - } - shownWithMap = false; - - Timers.runTask(10f, Platform.instance::updateRPC); - }); - - hidden(() -> { - Platform.instance.updateRPC(); - Platform.instance.endForceLandscape(); - }); - } - - private void save(){ - String name = editor.getTags().get("name", ""); - - if(name.isEmpty()){ - ui.showError("$text.editor.save.noname"); - }else{ - Map map = world.maps().getByName(name); - if(map != null && !map.custom){ - ui.showError("$text.editor.save.overwrite"); - }else{ - world.maps().saveMap(name, editor.getMap(), editor.getTags()); - ui.showInfoFade("$text.editor.saved"); - } - } - - menu.hide(); - saved = true; - } - - /**Argument format: - * 0) button name - * 1) description - * 2) icon name - * 3) listener */ - private FloatingDialog createDialog(String title, Object... arguments){ - FloatingDialog dialog = new FloatingDialog(title); - - float h = 90f; - - dialog.content().defaults().size(360f, h).padBottom(5).padRight(5).padLeft(5); - - for(int i = 0; i < arguments.length; i += 4){ - String name = (String)arguments[i]; - String description = (String)arguments[i + 1]; - String iconname = (String)arguments[i + 2]; - Listenable listenable = (Listenable)arguments[i + 3]; - - TextButton button = dialog.content().addButton(name, () -> { - listenable.listen(); - dialog.hide(); - menu.hide(); - }).left().get(); - - button.clearChildren(); - button.table("button", t -> { - t.addImage(iconname).size(16*3); - t.update(() -> t.background(button.getClickListener().isOver() ? "button-over" : "button")); - }).padLeft(-10).padBottom(-3).size(h); - button.table(t -> { - t.add(name).growX().wrap(); - t.row(); - t.add(description).color(Color.GRAY).growX().wrap(); - }).growX().padLeft(8); - - button.row(); - - dialog.content().row(); - } - - dialog.addCloseButton(); - dialog.show(); - - return dialog; - } - - @Override - public Dialog show(){ - return super.show(Core.scene, Actions.sequence(Actions.alpha(0f), Actions.scaleTo(1f, 1f), Actions.fadeIn(0.3f))); - } - - @Override - public void dispose(){ - editor.renderer().dispose(); - } - - public void beginEditMap(InputStream is){ - ui.loadAnd(() -> { - try { - shownWithMap = true; - DataInputStream stream = new DataInputStream(is); - MapMeta meta = MapIO.readMapMeta(stream); - editor.beginEdit(MapIO.readTileData(stream, meta, false), meta.tags, false); - is.close(); - show(); - }catch (Exception e){ - Log.err(e); - ui.showError(Bundles.format("text.editor.errorimageload", Strings.parseException(e, false))); - } - }); - } - - public MapView getView() { - return view; - } - - public void resetSaved(){ - saved = false; - } - - public void updateSelectedBlock(){ - Block block = editor.getDrawBlock(); - for(int j = 0; j < Block.all().size; j ++){ - if(block.id == j && j < blockgroup.getButtons().size){ - blockgroup.getButtons().get(j).setChecked(true); - break; - } - } - } - - public boolean hasPane(){ - return Core.scene.getScrollFocus() == pane || Core.scene.getKeyboardFocus() != this; - } - - public void build(){ - float amount = 10f, baseSize = 60f; - - float size = mobile ? (int)(Math.min(Gdx.graphics.getHeight(), Gdx.graphics.getWidth()) / amount / Unit.dp.scl(1f)) : - Math.min(Gdx.graphics.getDisplayMode().height / amount, baseSize); - - new table(){{ - aleft(); - - new table("button"){{ - margin(0); - Table tools = new Table(); - tools.top(); - atop(); - - ButtonGroup group = new ButtonGroup<>(); - - Consumer addTool = tool -> { - ImageButton button = new ImageButton("icon-" + tool.name(), "toggle"); - button.clicked(() -> view.setTool(tool)); - button.resizeImage(16*2f); - button.update(() -> button.setChecked(view.getTool() == tool)); - group.add(button); - if (tool == EditorTool.pencil) - button.setChecked(true); - - tools.add(button).padBottom(-5.1f); - }; - - tools.defaults().size(size, size + 4f).padBottom(-5.1f); - - //tools.addImageButton("icon-back", 16*2, () -> tryExit()); - - tools.addImageButton("icon-menu-large", 16*2f, menu::show); - - ImageButton grid = tools.addImageButton("icon-grid", "toggle", 16*2f, () -> view.setGrid(!view.isGrid())).get(); + t.row(); + + t.row(); + }); + + menu.content().row(); + + menu.content().addImageTextButton("$text.quit", "icon-back", isize, () -> { + tryExit(); + menu.hide(); + }).padTop(-5).size(swidth * 2f + 10, 60f); + + resizeDialog = new MapResizeDialog(editor, (x, y) -> { + if(!(editor.getMap().width() == x && editor.getMap().height() == y)){ + ui.loadAnd(() -> { + editor.resize(x, y); + view.clearStack(); + }); + } + }); + + loadDialog = new MapLoadDialog(map -> { + + ui.loadAnd(() -> { + try(DataInputStream stream = new DataInputStream(map.stream.get())){ + MapMeta meta = MapIO.readMapMeta(stream); + MapTileData data = MapIO.readTileData(stream, meta, false); + + editor.beginEdit(data, meta.tags, false); + view.clearStack(); + }catch(IOException e){ + ui.showError(Bundles.format("text.editor.errormapload", Strings.parseException(e, false))); + Log.err(e); + } + }); + }); + + setFillParent(true); + + clearChildren(); + margin(0); + build.begin(this); + build(); + build.end(); + + update(() -> { + if(Core.scene.getKeyboardFocus() instanceof Dialog && Core.scene.getKeyboardFocus() != this){ + return; + } + + Vector2 v = pane.stageToLocalCoordinates(Graphics.mouse()); + + if(v.x >= 0 && v.y >= 0 && v.x <= pane.getWidth() && v.y <= pane.getHeight()){ + Core.scene.setScrollFocus(pane); + }else{ + Core.scene.setScrollFocus(null); + } + + if(Core.scene != null && Core.scene.getKeyboardFocus() == this){ + doInput(); + } + }); + + shown(() -> { + saved = true; + Platform.instance.beginForceLandscape(); + view.clearStack(); + Core.scene.setScrollFocus(view); + if(!shownWithMap){ + editor.beginEdit(new MapTileData(256, 256), new ObjectMap<>(), true); + } + shownWithMap = false; + + Timers.runTask(10f, Platform.instance::updateRPC); + }); + + hidden(() -> { + Platform.instance.updateRPC(); + Platform.instance.endForceLandscape(); + }); + } + + private void save(){ + String name = editor.getTags().get("name", ""); + + if(name.isEmpty()){ + ui.showError("$text.editor.save.noname"); + }else{ + Map map = world.maps().getByName(name); + if(map != null && !map.custom){ + ui.showError("$text.editor.save.overwrite"); + }else{ + world.maps().saveMap(name, editor.getMap(), editor.getTags()); + ui.showInfoFade("$text.editor.saved"); + } + } + + menu.hide(); + saved = true; + } + + /** + * Argument format: + * 0) button name + * 1) description + * 2) icon name + * 3) listener + */ + private FloatingDialog createDialog(String title, Object... arguments){ + FloatingDialog dialog = new FloatingDialog(title); + + float h = 90f; + + dialog.content().defaults().size(360f, h).padBottom(5).padRight(5).padLeft(5); + + for(int i = 0; i < arguments.length; i += 4){ + String name = (String) arguments[i]; + String description = (String) arguments[i + 1]; + String iconname = (String) arguments[i + 2]; + Listenable listenable = (Listenable) arguments[i + 3]; + + TextButton button = dialog.content().addButton(name, () -> { + listenable.listen(); + dialog.hide(); + menu.hide(); + }).left().get(); + + button.clearChildren(); + button.table("button", t -> { + t.addImage(iconname).size(16 * 3); + t.update(() -> t.background(button.getClickListener().isOver() ? "button-over" : "button")); + }).padLeft(-10).padBottom(-3).size(h); + button.table(t -> { + t.add(name).growX().wrap(); + t.row(); + t.add(description).color(Color.GRAY).growX().wrap(); + }).growX().padLeft(8); + + button.row(); + + dialog.content().row(); + } + + dialog.addCloseButton(); + dialog.show(); + + return dialog; + } + + @Override + public Dialog show(){ + return super.show(Core.scene, Actions.sequence(Actions.alpha(0f), Actions.scaleTo(1f, 1f), Actions.fadeIn(0.3f))); + } + + @Override + public void dispose(){ + editor.renderer().dispose(); + } + + public void beginEditMap(InputStream is){ + ui.loadAnd(() -> { + try{ + shownWithMap = true; + DataInputStream stream = new DataInputStream(is); + MapMeta meta = MapIO.readMapMeta(stream); + editor.beginEdit(MapIO.readTileData(stream, meta, false), meta.tags, false); + is.close(); + show(); + }catch(Exception e){ + Log.err(e); + ui.showError(Bundles.format("text.editor.errorimageload", Strings.parseException(e, false))); + } + }); + } + + public MapView getView(){ + return view; + } + + public void resetSaved(){ + saved = false; + } + + public void updateSelectedBlock(){ + Block block = editor.getDrawBlock(); + for(int j = 0; j < Block.all().size; j++){ + if(block.id == j && j < blockgroup.getButtons().size){ + blockgroup.getButtons().get(j).setChecked(true); + break; + } + } + } + + public boolean hasPane(){ + return Core.scene.getScrollFocus() == pane || Core.scene.getKeyboardFocus() != this; + } - addTool.accept(EditorTool.zoom); + public void build(){ + float amount = 10f, baseSize = 60f; + + float size = mobile ? (int) (Math.min(Gdx.graphics.getHeight(), Gdx.graphics.getWidth()) / amount / Unit.dp.scl(1f)) : + Math.min(Gdx.graphics.getDisplayMode().height / amount, baseSize); + + new table(){{ + aleft(); + + new table("button"){{ + margin(0); + Table tools = new Table(); + tools.top(); + atop(); - tools.row(); + ButtonGroup group = new ButtonGroup<>(); - ImageButton undo = tools.addImageButton("icon-undo", 16*2f, () -> view.undo()).get(); - ImageButton redo = tools.addImageButton("icon-redo", 16*2f, () -> view.redo()).get(); - - addTool.accept(EditorTool.pick); - - tools.row(); - - undo.setDisabled(() -> !view.getStack().canUndo()); - redo.setDisabled(() -> !view.getStack().canRedo()); - - undo.update(() -> undo.getImage().setColor(undo.isDisabled() ? Color.GRAY : Color.WHITE)); - redo.update(() -> redo.getImage().setColor(redo.isDisabled() ? Color.GRAY : Color.WHITE)); - grid.update(() -> grid.setChecked(view.isGrid())); - - addTool.accept(EditorTool.line); - addTool.accept(EditorTool.pencil); - addTool.accept(EditorTool.eraser); - - tools.row(); - - addTool.accept(EditorTool.fill); - addTool.accept(EditorTool.elevation); - - ImageButton rotate = tools.addImageButton("icon-arrow-16", 16*2f, () -> editor.setDrawRotation((editor.getDrawRotation() + 1)%4)).get(); - rotate.getImage().update(() ->{ - rotate.getImage().setRotation(editor.getDrawRotation() * 90); - rotate.getImage().setOrigin(Align.center); - }); - - tools.row(); - - tools.table("button", t -> { - t.add("$text.editor.teams"); - }).colspan(3).height(40).width(size*3f); + Consumer addTool = tool -> { + ImageButton button = new ImageButton("icon-" + tool.name(), "toggle"); + button.clicked(() -> view.setTool(tool)); + button.resizeImage(16 * 2f); + button.update(() -> button.setChecked(view.getTool() == tool)); + group.add(button); + if(tool == EditorTool.pencil) + button.setChecked(true); - tools.row(); + tools.add(button).padBottom(-5.1f); + }; - ButtonGroup teamgroup = new ButtonGroup<>(); + tools.defaults().size(size, size + 4f).padBottom(-5.1f); - int i = 0; + //tools.addImageButton("icon-back", 16*2, () -> tryExit()); - for(Team team : Team.all){ - ImageButton button = new ImageButton("white", "toggle"); - button.margin(4f, 4f, 10f, 4f); - button.getImageCell().grow(); - button.getStyle().imageUpColor = team.color; - button.clicked(() -> editor.setDrawTeam(team)); - button.update(() -> button.setChecked(editor.getDrawTeam() == team)); - teamgroup.add(button); - tools.add(button).padBottom(-5.1f); + tools.addImageButton("icon-menu-large", 16 * 2f, menu::show); - if(i++ % 3 == 2) tools.row(); - } + ImageButton grid = tools.addImageButton("icon-grid", "toggle", 16 * 2f, () -> view.setGrid(!view.isGrid())).get(); - add(tools).top().padBottom(-6); + addTool.accept(EditorTool.zoom); - row(); + tools.row(); - new table("button"){{ - atop(); - Slider slider = new Slider(0, MapEditor.brushSizes.length-1, 1, false); - slider.moved(f -> editor.setBrushSize(MapEditor.brushSizes[(int)(float)f])); - new label("brush"); - row(); - add(slider).width(size*3f-20).padTop(4f); - }}.padTop(5).growX().growY().top().end(); - - row(); - - get().table("button", t -> { - t.add("$text.editor.elevation"); - }).colspan(3).height(40).width(size*3f); + ImageButton undo = tools.addImageButton("icon-undo", 16 * 2f, () -> view.undo()).get(); + ImageButton redo = tools.addImageButton("icon-redo", 16 * 2f, () -> view.redo()).get(); - row(); - - get().table("button", t -> { - t.margin(0); - t.addImageButton("icon-arrow-left", 16*2f, () -> editor.setDrawElevation(editor.getDrawElevation() - 1)) - .disabled(b -> editor.getDrawElevation() <= -1).size(size); - - t.label(() -> editor.getDrawElevation() == -1 ? "$text.editor.slope" : (editor.getDrawElevation() + "")) - .size(size).get().setAlignment(Align.center, Align.center); - - t.addImageButton("icon-arrow-right", 16*2f, () -> editor.setDrawElevation(editor.getDrawElevation() + 1)) - .disabled(b -> editor.getDrawElevation() >= 127).size(size); - }).colspan(3).height(size).padTop(-5).width(size*3f); - - }}.left().growY().end(); - - - new table("button"){{ - margin(5); - marginBottom(10); - add(view).grow(); - }}.grow().end(); - - new table(){{ - - row(); - - addBlockSelection(get()); - - row(); - - }}.right().growY().end(); - }}.grow().end(); - } - - private void doInput(){ - //tool select - for(int i = 0; i < EditorTool.values().length; i ++){ - if(Inputs.keyTap(Input.valueOf("NUM_" + (i+1)))){ - view.setTool(EditorTool.values()[i]); - break; - } - } - - if(Inputs.keyTap(Input.R)){ - editor.setDrawRotation((editor.getDrawRotation() + 1)%4); - } - - if(Inputs.keyTap(Input.E)){ - editor.setDrawRotation(Mathf.mod((editor.getDrawRotation() + 1), 4)); - } - - //ctrl keys (undo, redo, save) - if(UIUtils.ctrl()){ - if(Inputs.keyTap(Input.Z)){ - view.undo(); - } - - if(Inputs.keyTap(Input.Y)){ - view.redo(); - } - - if(Inputs.keyTap(Input.S)){ - save(); - } - - if(Inputs.keyTap(Input.G)){ - view.setGrid(!view.isGrid()); - } - } - } - - private void tryExit(){ - if(!saved){ - ui.showConfirm("$text.confirm", "$text.editor.unsaved", this::hide); - }else{ - hide(); - } - } - - private void addBlockSelection(Table table){ - Table content = new Table(); - pane = new ScrollPane(content, "volume"); - pane.setFadeScrollBars(false); - pane.setOverscroll(true, false); - ButtonGroup group = new ButtonGroup<>(); - blockgroup = group; - - int i = 0; - - for(Block block : Block.all()){ - TextureRegion[] regions = block.getCompactIcon(); - if((block.synthetic() && (Recipe.getByResult(block) == null || !control.database().isUnlocked(Recipe.getByResult(block)))) && !debug && block != StorageBlocks.core) continue; - - if(regions.length == 0 || regions[0] == Draw.region("jjfgj")) continue; - - Stack stack = new Stack(); - - for(TextureRegion region : regions){ - stack.add(new Image(region)); - } - - ImageButton button = new ImageButton("white", "toggle"); - button.clicked(() -> editor.setDrawBlock(block)); - button.resizeImage(8*4f); - button.getImageCell().setActor(stack); - button.addChild(stack); - button.getImage().remove(); - button.update(() -> button.setChecked(editor.getDrawBlock() == block)); - group.add(button); - content.add(button).pad(4f).size(53f, 58f); - - if(i++ % 3 == 2){ - content.row(); - } - } - - group.getButtons().get(2).setChecked(true); - - Table extra = new Table("button"); - extra.labelWrap(() -> editor.getDrawBlock().formalName).width(220f).center(); - table.add(extra).growX(); - table.row(); - table.add(pane).growY().fillX(); - } + addTool.accept(EditorTool.pick); + + tools.row(); + + undo.setDisabled(() -> !view.getStack().canUndo()); + redo.setDisabled(() -> !view.getStack().canRedo()); + + undo.update(() -> undo.getImage().setColor(undo.isDisabled() ? Color.GRAY : Color.WHITE)); + redo.update(() -> redo.getImage().setColor(redo.isDisabled() ? Color.GRAY : Color.WHITE)); + grid.update(() -> grid.setChecked(view.isGrid())); + + addTool.accept(EditorTool.line); + addTool.accept(EditorTool.pencil); + addTool.accept(EditorTool.eraser); + + tools.row(); + + addTool.accept(EditorTool.fill); + addTool.accept(EditorTool.elevation); + + ImageButton rotate = tools.addImageButton("icon-arrow-16", 16 * 2f, () -> editor.setDrawRotation((editor.getDrawRotation() + 1) % 4)).get(); + rotate.getImage().update(() -> { + rotate.getImage().setRotation(editor.getDrawRotation() * 90); + rotate.getImage().setOrigin(Align.center); + }); + + tools.row(); + + tools.table("button", t -> { + t.add("$text.editor.teams"); + }).colspan(3).height(40).width(size * 3f); + + tools.row(); + + ButtonGroup teamgroup = new ButtonGroup<>(); + + int i = 0; + + for(Team team : Team.all){ + ImageButton button = new ImageButton("white", "toggle"); + button.margin(4f, 4f, 10f, 4f); + button.getImageCell().grow(); + button.getStyle().imageUpColor = team.color; + button.clicked(() -> editor.setDrawTeam(team)); + button.update(() -> button.setChecked(editor.getDrawTeam() == team)); + teamgroup.add(button); + tools.add(button).padBottom(-5.1f); + + if(i++ % 3 == 2) tools.row(); + } + + add(tools).top().padBottom(-6); + + row(); + + new table("button"){{ + atop(); + Slider slider = new Slider(0, MapEditor.brushSizes.length - 1, 1, false); + slider.moved(f -> editor.setBrushSize(MapEditor.brushSizes[(int) (float) f])); + new label("brush"); + row(); + add(slider).width(size * 3f - 20).padTop(4f); + }}.padTop(5).growX().growY().top().end(); + + row(); + + get().table("button", t -> { + t.add("$text.editor.elevation"); + }).colspan(3).height(40).width(size * 3f); + + row(); + + get().table("button", t -> { + t.margin(0); + t.addImageButton("icon-arrow-left", 16 * 2f, () -> editor.setDrawElevation(editor.getDrawElevation() - 1)) + .disabled(b -> editor.getDrawElevation() <= -1).size(size); + + t.label(() -> editor.getDrawElevation() == -1 ? "$text.editor.slope" : (editor.getDrawElevation() + "")) + .size(size).get().setAlignment(Align.center, Align.center); + + t.addImageButton("icon-arrow-right", 16 * 2f, () -> editor.setDrawElevation(editor.getDrawElevation() + 1)) + .disabled(b -> editor.getDrawElevation() >= 127).size(size); + }).colspan(3).height(size).padTop(-5).width(size * 3f); + + }}.left().growY().end(); + + + new table("button"){{ + margin(5); + marginBottom(10); + add(view).grow(); + }}.grow().end(); + + new table(){{ + + row(); + + addBlockSelection(get()); + + row(); + + }}.right().growY().end(); + }}.grow().end(); + } + + private void doInput(){ + //tool select + for(int i = 0; i < EditorTool.values().length; i++){ + if(Inputs.keyTap(Input.valueOf("NUM_" + (i + 1)))){ + view.setTool(EditorTool.values()[i]); + break; + } + } + + if(Inputs.keyTap(Input.R)){ + editor.setDrawRotation((editor.getDrawRotation() + 1) % 4); + } + + if(Inputs.keyTap(Input.E)){ + editor.setDrawRotation(Mathf.mod((editor.getDrawRotation() + 1), 4)); + } + + //ctrl keys (undo, redo, save) + if(UIUtils.ctrl()){ + if(Inputs.keyTap(Input.Z)){ + view.undo(); + } + + if(Inputs.keyTap(Input.Y)){ + view.redo(); + } + + if(Inputs.keyTap(Input.S)){ + save(); + } + + if(Inputs.keyTap(Input.G)){ + view.setGrid(!view.isGrid()); + } + } + } + + private void tryExit(){ + if(!saved){ + ui.showConfirm("$text.confirm", "$text.editor.unsaved", this::hide); + }else{ + hide(); + } + } + + private void addBlockSelection(Table table){ + Table content = new Table(); + pane = new ScrollPane(content, "volume"); + pane.setFadeScrollBars(false); + pane.setOverscroll(true, false); + ButtonGroup group = new ButtonGroup<>(); + blockgroup = group; + + int i = 0; + + for(Block block : Block.all()){ + TextureRegion[] regions = block.getCompactIcon(); + if((block.synthetic() && (Recipe.getByResult(block) == null || !control.database().isUnlocked(Recipe.getByResult(block)))) && !debug && block != StorageBlocks.core) + continue; + + if(regions.length == 0 || regions[0] == Draw.region("jjfgj")) continue; + + Stack stack = new Stack(); + + for(TextureRegion region : regions){ + stack.add(new Image(region)); + } + + ImageButton button = new ImageButton("white", "toggle"); + button.clicked(() -> editor.setDrawBlock(block)); + button.resizeImage(8 * 4f); + button.getImageCell().setActor(stack); + button.addChild(stack); + button.getImage().remove(); + button.update(() -> button.setChecked(editor.getDrawBlock() == block)); + group.add(button); + content.add(button).pad(4f).size(53f, 58f); + + if(i++ % 3 == 2){ + content.row(); + } + } + + group.getButtons().get(2).setChecked(true); + + Table extra = new Table("button"); + extra.labelWrap(() -> editor.getDrawBlock().formalName).width(220f).center(); + table.add(extra).growX(); + table.row(); + table.add(pane).growY().fillX(); + } } diff --git a/core/src/io/anuke/mindustry/editor/MapLoadDialog.java b/core/src/io/anuke/mindustry/editor/MapLoadDialog.java index 52fd0eb2a3..c9c249636e 100644 --- a/core/src/io/anuke/mindustry/editor/MapLoadDialog.java +++ b/core/src/io/anuke/mindustry/editor/MapLoadDialog.java @@ -14,68 +14,68 @@ import io.anuke.ucore.scene.ui.layout.Table; import static io.anuke.mindustry.Vars.world; public class MapLoadDialog extends FloatingDialog{ - private Map selected = null; + private Map selected = null; - public MapLoadDialog(Consumer loader) { - super("$text.editor.loadmap"); + public MapLoadDialog(Consumer loader){ + super("$text.editor.loadmap"); - shown(this::rebuild); - rebuild(); + shown(this::rebuild); + rebuild(); - TextButton button = new TextButton("$text.load"); - button.setDisabled(() -> selected == null); - button.clicked(() -> { - if (selected != null) { - loader.accept(selected); - hide(); - } - }); + TextButton button = new TextButton("$text.load"); + button.setDisabled(() -> selected == null); + button.clicked(() -> { + if(selected != null){ + loader.accept(selected); + hide(); + } + }); - buttons().defaults().size(200f, 50f); - buttons().addButton("$text.cancel", this::hide); - buttons().add(button); - } + buttons().defaults().size(200f, 50f); + buttons().addButton("$text.cancel", this::hide); + buttons().add(button); + } - public void rebuild(){ - content().clear(); - if(world.maps().all().size > 0){ - selected = world.maps().all().first(); - } + public void rebuild(){ + content().clear(); + if(world.maps().all().size > 0){ + selected = world.maps().all().first(); + } - ButtonGroup group = new ButtonGroup<>(); + ButtonGroup group = new ButtonGroup<>(); - int maxcol = 3; + int maxcol = 3; - int i = 0; + int i = 0; - Table table = new Table(); - table.defaults().size(200f, 90f).pad(4f); - table.margin(10f); + Table table = new Table(); + table.defaults().size(200f, 90f).pad(4f); + table.margin(10f); - ScrollPane pane = new ScrollPane(table, "horizontal"); - pane.setFadeScrollBars(false); + ScrollPane pane = new ScrollPane(table, "horizontal"); + pane.setFadeScrollBars(false); - for (Map map : world.maps().all()) { + for(Map map : world.maps().all()){ - TextButton button = new TextButton(map.getDisplayName(), "toggle"); - button.add(new BorderImage(map.texture, 2f)).size(16 * 4f); - button.getCells().reverse(); - button.clicked(() -> selected = map); - button.getLabelCell().grow().left().padLeft(5f); - group.add(button); - table.add(button); - if (++i % maxcol == 0) table.row(); - } + TextButton button = new TextButton(map.getDisplayName(), "toggle"); + button.add(new BorderImage(map.texture, 2f)).size(16 * 4f); + button.getCells().reverse(); + button.clicked(() -> selected = map); + button.getLabelCell().grow().left().padLeft(5f); + group.add(button); + table.add(button); + if(++i % maxcol == 0) table.row(); + } - if(world.maps().all().size == 0){ - pane.setStyle(Core.skin.get("clear", ScrollPaneStyle.class)); - table.add("$text.maps.none").center(); - }else { - content().add("$text.editor.loadmap"); - } + if(world.maps().all().size == 0){ + pane.setStyle(Core.skin.get("clear", ScrollPaneStyle.class)); + table.add("$text.maps.none").center(); + }else{ + content().add("$text.editor.loadmap"); + } - content().row(); - content().add(pane); - } + content().row(); + content().add(pane); + } } diff --git a/core/src/io/anuke/mindustry/editor/MapRenderer.java b/core/src/io/anuke/mindustry/editor/MapRenderer.java index 16fc993438..b86c8bf7e1 100644 --- a/core/src/io/anuke/mindustry/editor/MapRenderer.java +++ b/core/src/io/anuke/mindustry/editor/MapRenderer.java @@ -34,18 +34,18 @@ public class MapRenderer implements Disposable{ public void resize(int width, int height){ if(chunks != null){ - for(int x = 0; x < chunks.length; x ++){ - for(int y = 0; y < chunks[0].length; y ++){ + for(int x = 0; x < chunks.length; x++){ + for(int y = 0; y < chunks[0].length; y++){ chunks[x][y].dispose(); } } } - chunks = new IndexedRenderer[(int)Math.ceil((float)width/chunksize)][(int)Math.ceil((float)height/chunksize )]; + chunks = new IndexedRenderer[(int) Math.ceil((float) width / chunksize)][(int) Math.ceil((float) height / chunksize)]; - for(int x = 0; x < chunks.length; x ++){ - for(int y = 0; y < chunks[0].length; y ++){ - chunks[x][y] = new IndexedRenderer(chunksize*chunksize*2); + for(int x = 0; x < chunks.length; x++){ + for(int y = 0; y < chunks[0].length; y++){ + chunks[x][y] = new IndexedRenderer(chunksize * chunksize * 2); } } this.width = width; @@ -69,8 +69,8 @@ public class MapRenderer implements Disposable{ updates.addAll(delayedUpdates); delayedUpdates.clear(); - for(int x = 0; x < chunks.length; x ++){ - for(int y = 0; y < chunks[0].length; y ++){ + for(int x = 0; x < chunks.length; x++){ + for(int y = 0; y < chunks[0].length; y++){ IndexedRenderer mesh = chunks[x][y]; mesh.getTransformMatrix().setToTranslation(tx, ty, 0).scl(tw / (width * tilesize), @@ -86,19 +86,19 @@ public class MapRenderer implements Disposable{ public void updatePoint(int x, int y){ //TODO spread out over multiple frames? - updates.add(x + y*width); + updates.add(x + y * width); } public void updateAll(){ - for(int x = 0; x < width; x ++){ - for(int y = 0; y < height; y ++){ + for(int x = 0; x < width; x++){ + for(int y = 0; y < height; y++){ render(x, y); } } } private void render(int wx, int wy){ - int x = wx/chunksize, y = wy/chunksize; + int x = wx / chunksize, y = wy / chunksize; IndexedRenderer mesh = chunks[x][y]; //TileDataMarker data = editor.getMap().readAt(wx, wy); byte bf = editor.getMap().read(wx, wy, DataPosition.floor); @@ -111,19 +111,19 @@ public class MapRenderer implements Disposable{ Block floor = Block.getByID(bf); Block wall = Block.getByID(bw); - int offsetx = -(wall.size-1)/2; - int offsety = -(wall.size-1)/2; + int offsetx = -(wall.size - 1) / 2; + int offsety = -(wall.size - 1) / 2; TextureRegion region; - if(bw != 0) { + if(bw != 0){ region = wall.getEditorIcon(); - if (wall.rotate) { + if(wall.rotate){ mesh.draw((wx % chunksize) + (wy % chunksize) * chunksize, region, wx * tilesize + offsetx * tilesize, wy * tilesize + offsety * tilesize, region.getRegionWidth(), region.getRegionHeight(), rotation * 90 - 90); - } else { + }else{ mesh.draw((wx % chunksize) + (wy % chunksize) * chunksize, region, wx * tilesize + offsetx * tilesize, wy * tilesize + offsety * tilesize, region.getRegionWidth(), region.getRegionHeight()); @@ -131,16 +131,16 @@ public class MapRenderer implements Disposable{ }else{ region = floor.getEditorIcon(); - mesh.draw((wx % chunksize) + (wy % chunksize)*chunksize, region, wx * tilesize, wy * tilesize, 8, 8); + mesh.draw((wx % chunksize) + (wy % chunksize) * chunksize, region, wx * tilesize, wy * tilesize, 8, 8); } boolean check = checkElevation(elev, wx, wy); - if(wall.update || wall.destructible) { + if(wall.update || wall.destructible){ mesh.setColor(team.color); region = Draw.region("block-border"); }else if(elev > 0 && check){ - mesh.setColor(tmpColor.fromHsv((360f * elev/127f * 4f) % 360f, 0.5f + (elev / 4f) % 0.5f, 1f)); + mesh.setColor(tmpColor.fromHsv((360f * elev / 127f * 4f) % 360f, 0.5f + (elev / 4f) % 0.5f, 1f)); region = Draw.region("block-elevation"); }else if(elev == -1){ region = Draw.region("block-slope"); @@ -148,8 +148,8 @@ public class MapRenderer implements Disposable{ region = Draw.region("clear"); } - mesh.draw((wx % chunksize) + (wy % chunksize)*chunksize + chunksize*chunksize, region, - wx * tilesize + offsetx*tilesize, wy * tilesize + offsety * tilesize, + mesh.draw((wx % chunksize) + (wy % chunksize) * chunksize + chunksize * chunksize, region, + wx * tilesize + offsetx * tilesize, wy * tilesize + offsety * tilesize, region.getRegionWidth(), region.getRegionHeight()); mesh.setColor(Color.WHITE); } @@ -165,19 +165,19 @@ public class MapRenderer implements Disposable{ if(value < elev){ return true; }else if(value > elev){ - delayedUpdates.add(wx + wy*width); + delayedUpdates.add(wx + wy * width); } } return false; } @Override - public void dispose() { + public void dispose(){ if(chunks == null){ return; } - for(int x = 0; x < chunks.length; x ++){ - for(int y = 0; y < chunks[0].length; y ++){ + for(int x = 0; x < chunks.length; x++){ + for(int y = 0; y < chunks[0].length; y++){ if(chunks[x][y] != null){ chunks[x][y].dispose(); } diff --git a/core/src/io/anuke/mindustry/editor/MapResizeDialog.java b/core/src/io/anuke/mindustry/editor/MapResizeDialog.java index 3daebbd825..a5ffc63835 100644 --- a/core/src/io/anuke/mindustry/editor/MapResizeDialog.java +++ b/core/src/io/anuke/mindustry/editor/MapResizeDialog.java @@ -9,55 +9,55 @@ import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.util.Mathf; public class MapResizeDialog extends FloatingDialog{ - int[] validMapSizes = {200, 300, 400, 500}; - int width, height; - - public MapResizeDialog(MapEditor editor, BiConsumer cons){ - super("$text.editor.resizemap"); - shown(() -> { - content().clear(); - MapTileData data = editor.getMap(); - width = data.width(); - height = data.height(); - - Table table = new Table(); - - for(boolean w : Mathf.booleans){ - int curr = w ? data.width() : data.height(); - int idx = 0; - for(int i = 0; i < validMapSizes.length; i ++) { - if (validMapSizes[i] == curr) idx = i; - } - - table.add(w ? "$text.width": "$text.height").padRight(8f); - ButtonGroup group = new ButtonGroup<>(); - for(int i = 0; i < validMapSizes.length; i ++){ - int size = validMapSizes[i]; - TextButton button = new TextButton(size + "", "toggle"); - button.clicked(() -> { - if(w) - width = size; - else - height = size; - }); - group.add(button); - if(i == idx) button.setChecked(true); - table.add(button).size(100f, 54f).pad(2f); - } - - table.row(); - } - content().row(); - content().add(table); - - }); - - buttons().defaults().size(200f, 50f); - buttons().addButton("$text.cancel", this::hide); - buttons().addButton("$text.editor.resize", () -> { - cons.accept(width, height); - hide(); - }); - - } + int[] validMapSizes = {200, 300, 400, 500}; + int width, height; + + public MapResizeDialog(MapEditor editor, BiConsumer cons){ + super("$text.editor.resizemap"); + shown(() -> { + content().clear(); + MapTileData data = editor.getMap(); + width = data.width(); + height = data.height(); + + Table table = new Table(); + + for(boolean w : Mathf.booleans){ + int curr = w ? data.width() : data.height(); + int idx = 0; + for(int i = 0; i < validMapSizes.length; i++){ + if(validMapSizes[i] == curr) idx = i; + } + + table.add(w ? "$text.width" : "$text.height").padRight(8f); + ButtonGroup group = new ButtonGroup<>(); + for(int i = 0; i < validMapSizes.length; i++){ + int size = validMapSizes[i]; + TextButton button = new TextButton(size + "", "toggle"); + button.clicked(() -> { + if(w) + width = size; + else + height = size; + }); + group.add(button); + if(i == idx) button.setChecked(true); + table.add(button).size(100f, 54f).pad(2f); + } + + table.row(); + } + content().row(); + content().add(table); + + }); + + buttons().defaults().size(200f, 50f); + buttons().addButton("$text.cancel", this::hide); + buttons().addButton("$text.editor.resize", () -> { + cons.accept(width, height); + hide(); + }); + + } } diff --git a/core/src/io/anuke/mindustry/editor/MapSaveDialog.java b/core/src/io/anuke/mindustry/editor/MapSaveDialog.java index cc4956ef5a..c11318298b 100644 --- a/core/src/io/anuke/mindustry/editor/MapSaveDialog.java +++ b/core/src/io/anuke/mindustry/editor/MapSaveDialog.java @@ -1,7 +1,7 @@ package io.anuke.mindustry.editor; -import io.anuke.mindustry.io.Map; import io.anuke.mindustry.core.Platform; +import io.anuke.mindustry.io.Map; import io.anuke.mindustry.ui.dialogs.FloatingDialog; import io.anuke.ucore.function.Consumer; import io.anuke.ucore.scene.ui.TextButton; @@ -11,65 +11,65 @@ import static io.anuke.mindustry.Vars.ui; import static io.anuke.mindustry.Vars.world; public class MapSaveDialog extends FloatingDialog{ - private TextField field; - private Consumer listener; - - public MapSaveDialog(Consumer cons){ - super("$text.editor.savemap"); - field = new TextField(); - listener = cons; - - Platform.instance.addDialog(field); - - shown(() -> { - content().clear(); - content().label(() ->{ - Map map = world.maps().getByName(field.getText()); - if(map != null){ - if(map.custom){ - return "$text.editor.overwrite"; - }else{ - return "$text.editor.failoverwrite"; - } - } - return ""; - }).colspan(2); - content().row(); - content().add("$text.editor.mapname").padRight(14f); - content().add(field).size(220f, 48f); - }); - - buttons().defaults().size(200f, 50f).pad(2f); - buttons().addButton("$text.cancel", this::hide); - - TextButton button = new TextButton("$text.save"); - button.clicked(() -> { - if(!invalid()){ - cons.accept(field.getText()); - hide(); - } - }); - button.setDisabled(this::invalid); - buttons().add(button); - } + private TextField field; + private Consumer listener; - public void save(){ - if(!invalid()){ - listener.accept(field.getText()); - }else{ - ui.showError("$text.editor.failoverwrite"); - } - } - - public void setFieldText(String text){ - field.setText(text); - } - - private boolean invalid(){ - if(field.getText().isEmpty()){ - return true; - } - Map map = world.maps().getByName(field.getText()); - return map != null && !map.custom; - } + public MapSaveDialog(Consumer cons){ + super("$text.editor.savemap"); + field = new TextField(); + listener = cons; + + Platform.instance.addDialog(field); + + shown(() -> { + content().clear(); + content().label(() -> { + Map map = world.maps().getByName(field.getText()); + if(map != null){ + if(map.custom){ + return "$text.editor.overwrite"; + }else{ + return "$text.editor.failoverwrite"; + } + } + return ""; + }).colspan(2); + content().row(); + content().add("$text.editor.mapname").padRight(14f); + content().add(field).size(220f, 48f); + }); + + buttons().defaults().size(200f, 50f).pad(2f); + buttons().addButton("$text.cancel", this::hide); + + TextButton button = new TextButton("$text.save"); + button.clicked(() -> { + if(!invalid()){ + cons.accept(field.getText()); + hide(); + } + }); + button.setDisabled(this::invalid); + buttons().add(button); + } + + public void save(){ + if(!invalid()){ + listener.accept(field.getText()); + }else{ + ui.showError("$text.editor.failoverwrite"); + } + } + + public void setFieldText(String text){ + field.setText(text); + } + + private boolean invalid(){ + if(field.getText().isEmpty()){ + return true; + } + Map map = world.maps().getByName(field.getText()); + return map != null && !map.custom; + } } diff --git a/core/src/io/anuke/mindustry/editor/MapView.java b/core/src/io/anuke/mindustry/editor/MapView.java index acab432e5b..e50885787a 100644 --- a/core/src/io/anuke/mindustry/editor/MapView.java +++ b/core/src/io/anuke/mindustry/editor/MapView.java @@ -33,261 +33,261 @@ import static io.anuke.mindustry.Vars.mobile; import static io.anuke.mindustry.Vars.ui; public class MapView extends Element implements GestureListener{ - private MapEditor editor; - private EditorTool tool = EditorTool.pencil; - private OperationStack stack = new OperationStack(); - private DrawOperation op; - private Bresenham2 br = new Bresenham2(); - private boolean updated = false; - private float offsetx, offsety; - private float zoom = 1f; - private boolean grid = false; - private GridImage image = new GridImage(0, 0); - private Vector2 vec = new Vector2(); - private Rectangle rect = new Rectangle(); - private Vector2[][] brushPolygons = new Vector2[MapEditor.brushSizes.length][0]; + private MapEditor editor; + private EditorTool tool = EditorTool.pencil; + private OperationStack stack = new OperationStack(); + private DrawOperation op; + private Bresenham2 br = new Bresenham2(); + private boolean updated = false; + private float offsetx, offsety; + private float zoom = 1f; + private boolean grid = false; + private GridImage image = new GridImage(0, 0); + private Vector2 vec = new Vector2(); + private Rectangle rect = new Rectangle(); + private Vector2[][] brushPolygons = new Vector2[MapEditor.brushSizes.length][0]; - private boolean drawing; - private int lastx, lasty; - private int startx, starty; - private float mousex, mousey; - private EditorTool lastTool; + private boolean drawing; + private int lastx, lasty; + private int startx, starty; + private float mousex, mousey; + private EditorTool lastTool; - public void setTool(EditorTool tool){ - this.tool = tool; - } + public MapView(MapEditor editor){ + this.editor = editor; - public EditorTool getTool() { - return tool; - } - - public void clearStack(){ - stack.clear(); - //TODO clear und obuffer - } - - public OperationStack getStack() { - return stack; - } - - public void setGrid(boolean grid) { - this.grid = grid; - } - - public boolean isGrid() { - return grid; - } - - public void undo(){ - if(stack.canUndo()){ - stack.undo(editor); - } - } - - public void redo(){ - if(stack.canRedo()){ - stack.redo(editor); - } - } - - public void addTileOp(TileOperation t){ - op.addOperation(t); - } - - public boolean checkForDuplicates(short x, short y){ - return op.checkDuplicate(x, y); - } - - public MapView(MapEditor editor){ - this.editor = editor; - - for(int i = 0; i < MapEditor.brushSizes.length; i ++){ + for(int i = 0; i < MapEditor.brushSizes.length; i++){ float size = MapEditor.brushSizes[i]; brushPolygons[i] = Geometry.pixelCircle(size, (index, x, y) -> Vector2.dst(x, y, index, index) <= index - 0.5f); } - - Inputs.addProcessor(0, new GestureDetector(20, 0.5f, 2, 0.15f, this)); - setTouchable(Touchable.enabled); - - addListener(new InputListener(){ - @Override - public boolean mouseMoved (InputEvent event, float x, float y) { - mousex = x; - mousey = y; + Inputs.addProcessor(0, new GestureDetector(20, 0.5f, 2, 0.15f, this)); + setTouchable(Touchable.enabled); - return false; + addListener(new InputListener(){ + + @Override + public boolean mouseMoved(InputEvent event, float x, float y){ + mousex = x; + mousey = y; + + return false; } - - @Override - public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) { - if(pointer != 0){ - return false; - } - if(!mobile && button != Buttons.LEFT && button != Buttons.MIDDLE){ - return true; - } + @Override + public boolean touchDown(InputEvent event, float x, float y, int pointer, int button){ + if(pointer != 0){ + return false; + } - if(button == Buttons.MIDDLE){ - lastTool = tool; - tool = EditorTool.zoom; - } + if(!mobile && button != Buttons.LEFT && button != Buttons.MIDDLE){ + return true; + } - mousex = x; - mousey = y; + if(button == Buttons.MIDDLE){ + lastTool = tool; + tool = EditorTool.zoom; + } - op = new DrawOperation(editor.getMap()); + mousex = x; + mousey = y; - updated = false; + op = new DrawOperation(editor.getMap()); - GridPoint2 p = project(x, y); - lastx = p.x; - lasty = p.y; - startx = p.x; - starty = p.y; - tool.touched(editor, p.x, p.y); - - if(tool.edit){ - updated = true; - ui.editor.resetSaved(); - } + updated = false; - drawing = true; - return true; - } - - @Override - public void touchUp (InputEvent event, float x, float y, int pointer, int button) { - if(!mobile && button != Buttons.LEFT && button != Buttons.MIDDLE){ - return; - } + GridPoint2 p = project(x, y); + lastx = p.x; + lasty = p.y; + startx = p.x; + starty = p.y; + tool.touched(editor, p.x, p.y); - drawing = false; + if(tool.edit){ + updated = true; + ui.editor.resetSaved(); + } - GridPoint2 p = project(x, y); + drawing = true; + return true; + } - if(tool == EditorTool.line){ - ui.editor.resetSaved(); - Array points = br.line(startx, starty, p.x, p.y); - for(GridPoint2 point : points){ - editor.draw(point.x, point.y); - } - updated = true; - } + @Override + public void touchUp(InputEvent event, float x, float y, int pointer, int button){ + if(!mobile && button != Buttons.LEFT && button != Buttons.MIDDLE){ + return; + } - if(op != null && updated){ - if(!op.isEmpty()){ - stack.add(op); - } - op = null; - } + drawing = false; - if(lastTool != null){ - tool = lastTool; - lastTool = null; - } + GridPoint2 p = project(x, y); - } - - @Override - public void touchDragged (InputEvent event, float x, float y, int pointer) { - mousex = x; - mousey = y; + if(tool == EditorTool.line){ + ui.editor.resetSaved(); + Array points = br.line(startx, starty, p.x, p.y); + for(GridPoint2 point : points){ + editor.draw(point.x, point.y); + } + updated = true; + } - GridPoint2 p = project(x, y); - - if(drawing && tool.draggable){ - ui.editor.resetSaved(); - Array points = br.line(lastx, lasty, p.x, p.y); - for(GridPoint2 point : points){ - tool.touched(editor, point.x, point.y); - } - updated = true; - } - lastx = p.x; - lasty = p.y; - } - }); - } - - @Override - public void act(float delta){ - super.act(delta); + if(op != null && updated){ + if(!op.isEmpty()){ + stack.add(op); + } + op = null; + } - if(Core.scene.getKeyboardFocus() == null || !(Core.scene.getKeyboardFocus() instanceof TextField) && - !Inputs.keyDown(io.anuke.ucore.input.Input.CONTROL_LEFT)) { - float ax = Inputs.getAxis("move_x"); - float ay = Inputs.getAxis("move_y"); - offsetx -= ax * 15f / zoom; - offsety -= ay * 15f / zoom; - } + if(lastTool != null){ + tool = lastTool; + lastTool = null; + } - if(ui.editor.hasPane()) return; - - zoom += Inputs.scroll()/10f * zoom; - clampZoom(); - } - - private void clampZoom(){ - zoom = Mathf.clamp(zoom, 0.2f, 12f); - } - - private GridPoint2 project(float x, float y){ - float ratio = 1f / ((float)editor.getMap().width() / editor.getMap().height()); - float size = Math.min(width, height); - float sclwidth = size * zoom; - float sclheight = size * zoom * ratio; - x = (x - getWidth()/2 + sclwidth/2 - offsetx*zoom) / sclwidth * editor.getMap().width(); - y = (y - getHeight()/2 + sclheight/2 - offsety*zoom) / sclheight * editor.getMap().height(); + } - if(editor.getDrawBlock().size % 2 == 0 && tool != EditorTool.eraser){ - return Tmp.g1.set((int)(x - 0.5f), (int)(y - 0.5f)); - }else{ - return Tmp.g1.set((int)x, (int)y); - } - } + @Override + public void touchDragged(InputEvent event, float x, float y, int pointer){ + mousex = x; + mousey = y; - private Vector2 unproject(int x, int y){ - float ratio = 1f / ((float)editor.getMap().width() / editor.getMap().height()); - float size = Math.min(width, height); - float sclwidth = size * zoom; - float sclheight = size * zoom * ratio; - float px = ((float)x / editor.getMap().width()) * sclwidth + offsetx*zoom - sclwidth/2 + getWidth()/2; - float py = ((float)(y) / editor.getMap().height()) * sclheight - + offsety*zoom - sclheight/2 + getHeight()/2; - return vec.set(px, py); - } + GridPoint2 p = project(x, y); - @Override - public void draw(Batch batch, float alpha){ - float ratio = 1f / ((float)editor.getMap().width() / editor.getMap().height()); - float size = Math.min(width, height); - float sclwidth = size * zoom; - float sclheight = size * zoom * ratio; - float centerx = x + width/2 + offsetx * zoom; - float centery = y + height/2 + offsety * zoom; + if(drawing && tool.draggable){ + ui.editor.resetSaved(); + Array points = br.line(lastx, lasty, p.x, p.y); + for(GridPoint2 point : points){ + tool.touched(editor, point.x, point.y); + } + updated = true; + } + lastx = p.x; + lasty = p.y; + } + }); + } - image.setImageSize(editor.getMap().width(), editor.getMap().height()); - - batch.flush(); - boolean pop = ScissorStack.pushScissors(rect.set(x, y, width, height)); + public EditorTool getTool(){ + return tool; + } - Draw.color(Color.LIGHT_GRAY); - Lines.stroke(-2f); - Lines.rect(centerx - sclwidth/2 - 1, centery - sclheight/2 - 1, sclwidth + 2, sclheight + 2); - editor.renderer().draw(centerx - sclwidth/2, centery - sclheight/2, sclwidth, sclheight); - Draw.reset(); + public void setTool(EditorTool tool){ + this.tool = tool; + } - if(grid){ - Draw.color(Color.GRAY); - image.setBounds(centerx - sclwidth/2, centery - sclheight/2, sclwidth, sclheight); - image.draw(batch, alpha); - Draw.color(); - } + public void clearStack(){ + stack.clear(); + //TODO clear und obuffer + } + + public OperationStack getStack(){ + return stack; + } + + public boolean isGrid(){ + return grid; + } + + public void setGrid(boolean grid){ + this.grid = grid; + } + + public void undo(){ + if(stack.canUndo()){ + stack.undo(editor); + } + } + + public void redo(){ + if(stack.canRedo()){ + stack.redo(editor); + } + } + + public void addTileOp(TileOperation t){ + op.addOperation(t); + } + + public boolean checkForDuplicates(short x, short y){ + return op.checkDuplicate(x, y); + } + + @Override + public void act(float delta){ + super.act(delta); + + if(Core.scene.getKeyboardFocus() == null || !(Core.scene.getKeyboardFocus() instanceof TextField) && + !Inputs.keyDown(io.anuke.ucore.input.Input.CONTROL_LEFT)){ + float ax = Inputs.getAxis("move_x"); + float ay = Inputs.getAxis("move_y"); + offsetx -= ax * 15f / zoom; + offsety -= ay * 15f / zoom; + } + + if(ui.editor.hasPane()) return; + + zoom += Inputs.scroll() / 10f * zoom; + clampZoom(); + } + + private void clampZoom(){ + zoom = Mathf.clamp(zoom, 0.2f, 12f); + } + + private GridPoint2 project(float x, float y){ + float ratio = 1f / ((float) editor.getMap().width() / editor.getMap().height()); + float size = Math.min(width, height); + float sclwidth = size * zoom; + float sclheight = size * zoom * ratio; + x = (x - getWidth() / 2 + sclwidth / 2 - offsetx * zoom) / sclwidth * editor.getMap().width(); + y = (y - getHeight() / 2 + sclheight / 2 - offsety * zoom) / sclheight * editor.getMap().height(); + + if(editor.getDrawBlock().size % 2 == 0 && tool != EditorTool.eraser){ + return Tmp.g1.set((int) (x - 0.5f), (int) (y - 0.5f)); + }else{ + return Tmp.g1.set((int) x, (int) y); + } + } + + private Vector2 unproject(int x, int y){ + float ratio = 1f / ((float) editor.getMap().width() / editor.getMap().height()); + float size = Math.min(width, height); + float sclwidth = size * zoom; + float sclheight = size * zoom * ratio; + float px = ((float) x / editor.getMap().width()) * sclwidth + offsetx * zoom - sclwidth / 2 + getWidth() / 2; + float py = ((float) (y) / editor.getMap().height()) * sclheight + + offsety * zoom - sclheight / 2 + getHeight() / 2; + return vec.set(px, py); + } + + @Override + public void draw(Batch batch, float alpha){ + float ratio = 1f / ((float) editor.getMap().width() / editor.getMap().height()); + float size = Math.min(width, height); + float sclwidth = size * zoom; + float sclheight = size * zoom * ratio; + float centerx = x + width / 2 + offsetx * zoom; + float centery = y + height / 2 + offsety * zoom; + + image.setImageSize(editor.getMap().width(), editor.getMap().height()); + + batch.flush(); + boolean pop = ScissorStack.pushScissors(rect.set(x, y, width, height)); + + Draw.color(Color.LIGHT_GRAY); + Lines.stroke(-2f); + Lines.rect(centerx - sclwidth / 2 - 1, centery - sclheight / 2 - 1, sclwidth + 2, sclheight + 2); + editor.renderer().draw(centerx - sclwidth / 2, centery - sclheight / 2, sclwidth, sclheight); + Draw.reset(); + + if(grid){ + Draw.color(Color.GRAY); + image.setBounds(centerx - sclwidth / 2, centery - sclheight / 2, sclwidth, sclheight); + image.draw(batch, alpha); + Draw.color(); + } int index = 0; - for(int i = 0; i < MapEditor.brushSizes.length; i ++){ + for(int i = 0; i < MapEditor.brushSizes.length; i++){ if(editor.getBrushSize() == MapEditor.brushSizes[i]){ index = i; break; @@ -297,102 +297,102 @@ public class MapView extends Element implements GestureListener{ //todo is it really math.max? float scaling = zoom * Math.min(width, height) / Math.max(editor.getMap().width(), editor.getMap().height()); - Draw.color(Palette.accent); - Lines.stroke(Unit.dp.scl(1f * zoom)); + Draw.color(Palette.accent); + Lines.stroke(Unit.dp.scl(1f * zoom)); - if(!editor.getDrawBlock().isMultiblock() || tool == EditorTool.eraser) { - if (tool == EditorTool.line && drawing) { - Vector2 v1 = unproject(startx, starty).add(x, y); - float sx = v1.x, sy = v1.y; - Vector2 v2 = unproject(lastx, lasty).add(x, y); + if(!editor.getDrawBlock().isMultiblock() || tool == EditorTool.eraser){ + if(tool == EditorTool.line && drawing){ + Vector2 v1 = unproject(startx, starty).add(x, y); + float sx = v1.x, sy = v1.y; + Vector2 v2 = unproject(lastx, lasty).add(x, y); - Lines.poly(brushPolygons[index], sx, sy, scaling); - Lines.poly(brushPolygons[index], v2.x, v2.y, scaling); - } + Lines.poly(brushPolygons[index], sx, sy, scaling); + Lines.poly(brushPolygons[index], v2.x, v2.y, scaling); + } - if (tool.edit && (!mobile || drawing)) { - GridPoint2 p = project(mousex, mousey); - Vector2 v = unproject(p.x, p.y).add(x, y); - Lines.poly(brushPolygons[index], v.x, v.y, scaling); - } - }else{ - if((tool.edit || tool == EditorTool.line) && (!mobile || drawing)){ - GridPoint2 p = project(mousex, mousey); - Vector2 v = unproject(p.x, p.y).add(x, y); - float offset = (editor.getDrawBlock().size % 2 == 0 ? scaling/2f : 0f); - Lines.square( - v.x + scaling/2f + offset, - v.y + scaling/2f + offset, - scaling * editor.getDrawBlock().size /2f); - } - } + if(tool.edit && (!mobile || drawing)){ + GridPoint2 p = project(mousex, mousey); + Vector2 v = unproject(p.x, p.y).add(x, y); + Lines.poly(brushPolygons[index], v.x, v.y, scaling); + } + }else{ + if((tool.edit || tool == EditorTool.line) && (!mobile || drawing)){ + GridPoint2 p = project(mousex, mousey); + Vector2 v = unproject(p.x, p.y).add(x, y); + float offset = (editor.getDrawBlock().size % 2 == 0 ? scaling / 2f : 0f); + Lines.square( + v.x + scaling / 2f + offset, + v.y + scaling / 2f + offset, + scaling * editor.getDrawBlock().size / 2f); + } + } - batch.flush(); - - if(pop) ScissorStack.popScissors(); - - Draw.color(Palette.accent); - Lines.stroke(Unit.dp.scl(3f)); - Lines.rect(x, y, width, height); - Draw.reset(); - } - - private boolean active(){ - return Core.scene.getKeyboardFocus() != null - && Core.scene.getKeyboardFocus().isDescendantOf(ui.editor) - && ui.editor.isShown() && tool == EditorTool.zoom && - Core.scene.hit(Graphics.mouse().x, Graphics.mouse().y, true) == this; - } + batch.flush(); - @Override - public boolean touchDown(float x, float y, int pointer, int button){ - return false; - } + if(pop) ScissorStack.popScissors(); - @Override - public boolean tap(float x, float y, int count, int button){ - return false; - } + Draw.color(Palette.accent); + Lines.stroke(Unit.dp.scl(3f)); + Lines.rect(x, y, width, height); + Draw.reset(); + } - @Override - public boolean longPress(float x, float y){ - return false; - } + private boolean active(){ + return Core.scene.getKeyboardFocus() != null + && Core.scene.getKeyboardFocus().isDescendantOf(ui.editor) + && ui.editor.isShown() && tool == EditorTool.zoom && + Core.scene.hit(Graphics.mouse().x, Graphics.mouse().y, true) == this; + } - @Override - public boolean fling(float velocityX, float velocityY, int button){ - return false; - } + @Override + public boolean touchDown(float x, float y, int pointer, int button){ + return false; + } - @Override - public boolean pan(float x, float y, float deltaX, float deltaY){ - if(!active()) return false; - offsetx += deltaX / zoom; - offsety -= deltaY / zoom; - return false; - } + @Override + public boolean tap(float x, float y, int count, int button){ + return false; + } - @Override - public boolean panStop(float x, float y, int pointer, int button){ - return false; - } + @Override + public boolean longPress(float x, float y){ + return false; + } - @Override - public boolean zoom(float initialDistance, float distance){ - if(!active()) return false; - float nzoom = distance - initialDistance; - zoom += nzoom / 10000f / Unit.dp.scl(1f) * zoom; - clampZoom(); - return false; - } + @Override + public boolean fling(float velocityX, float velocityY, int button){ + return false; + } - @Override - public boolean pinch(Vector2 initialPointer1, Vector2 initialPointer2, Vector2 pointer1, Vector2 pointer2){ - return false; - } + @Override + public boolean pan(float x, float y, float deltaX, float deltaY){ + if(!active()) return false; + offsetx += deltaX / zoom; + offsety -= deltaY / zoom; + return false; + } - @Override - public void pinchStop(){ + @Override + public boolean panStop(float x, float y, int pointer, int button){ + return false; + } - } + @Override + public boolean zoom(float initialDistance, float distance){ + if(!active()) return false; + float nzoom = distance - initialDistance; + zoom += nzoom / 10000f / Unit.dp.scl(1f) * zoom; + clampZoom(); + return false; + } + + @Override + public boolean pinch(Vector2 initialPointer1, Vector2 initialPointer2, Vector2 pointer1, Vector2 pointer2){ + return false; + } + + @Override + public void pinchStop(){ + + } } diff --git a/core/src/io/anuke/mindustry/editor/OperationStack.java b/core/src/io/anuke/mindustry/editor/OperationStack.java index 5c739608ee..402da3cf5e 100755 --- a/core/src/io/anuke/mindustry/editor/OperationStack.java +++ b/core/src/io/anuke/mindustry/editor/OperationStack.java @@ -3,49 +3,49 @@ package io.anuke.mindustry.editor; import com.badlogic.gdx.utils.Array; public class OperationStack{ - private final static int maxSize = 10; - private Array stack = new Array<>(); - private int index = 0; - - public OperationStack(){ - - } - - public void clear(){ - stack.clear(); - index = 0; - } - - public void add(DrawOperation action){ - stack.truncate(stack.size + index); - index = 0; - stack.add(action); + private final static int maxSize = 10; + private Array stack = new Array<>(); + private int index = 0; - if(stack.size > maxSize){ + public OperationStack(){ + + } + + public void clear(){ + stack.clear(); + index = 0; + } + + public void add(DrawOperation action){ + stack.truncate(stack.size + index); + index = 0; + stack.add(action); + + if(stack.size > maxSize){ stack.removeIndex(0); } - } - - public boolean canUndo(){ - return !(stack.size - 1 + index < 0); - } - - public boolean canRedo(){ - return !(index > -1 || stack.size + index < 0); - } + } - public void undo(MapEditor editor){ - if(!canUndo()) return; + public boolean canUndo(){ + return !(stack.size - 1 + index < 0); + } - stack.get(stack.size - 1 + index).undo(editor); - index --; - } + public boolean canRedo(){ + return !(index > -1 || stack.size + index < 0); + } - public void redo(MapEditor editor){ - if(!canRedo()) return; - - index ++; - stack.get(stack.size - 1 + index).redo(editor); - - } + public void undo(MapEditor editor){ + if(!canUndo()) return; + + stack.get(stack.size - 1 + index).undo(editor); + index--; + } + + public void redo(MapEditor editor){ + if(!canRedo()) return; + + index++; + stack.get(stack.size - 1 + index).redo(editor); + + } } diff --git a/core/src/io/anuke/mindustry/entities/Damage.java b/core/src/io/anuke/mindustry/entities/Damage.java index 6ba29a3de3..0c7ac56454 100644 --- a/core/src/io/anuke/mindustry/entities/Damage.java +++ b/core/src/io/anuke/mindustry/entities/Damage.java @@ -24,84 +24,90 @@ import io.anuke.ucore.util.Translator; import static io.anuke.mindustry.Vars.*; -/**Utility class for damaging in an area.*/ -public class Damage { - private static Rectangle rect = new Rectangle(); - private static Rectangle hitrect = new Rectangle(); - private static Translator tr = new Translator(); +/** + * Utility class for damaging in an area. + */ +public class Damage{ + private static Rectangle rect = new Rectangle(); + private static Rectangle hitrect = new Rectangle(); + private static Translator tr = new Translator(); - /**Creates a dynamic explosion based on specified parameters.*/ - public static void dynamicExplosion(float x, float y, float flammability, float explosiveness, float power, float radius, Color color){ - for(int i = 0; i < Mathf.clamp(power / 20, 0, 6); i ++){ - int branches = 5 + Mathf.clamp((int)(power/30), 1, 20); - Timers.run(i*2f + Mathf.random(4f), () -> Lightning.create(Team.none, Fx.none, Palette.power, 3, - x, y, Mathf.random(360f), branches + Mathf.range(2))); - } + /** + * Creates a dynamic explosion based on specified parameters. + */ + public static void dynamicExplosion(float x, float y, float flammability, float explosiveness, float power, float radius, Color color){ + for(int i = 0; i < Mathf.clamp(power / 20, 0, 6); i++){ + int branches = 5 + Mathf.clamp((int) (power / 30), 1, 20); + Timers.run(i * 2f + Mathf.random(4f), () -> Lightning.create(Team.none, Fx.none, Palette.power, 3, + x, y, Mathf.random(360f), branches + Mathf.range(2))); + } - for(int i = 0; i < Mathf.clamp(flammability / 4, 0, 30); i ++){ - Timers.run(i/2, () -> CallEntity.createBullet(TurretBullets.fireball, x, y, Mathf.random(360f))); - } + for(int i = 0; i < Mathf.clamp(flammability / 4, 0, 30); i++){ + Timers.run(i / 2, () -> CallEntity.createBullet(TurretBullets.fireball, x, y, Mathf.random(360f))); + } - int waves = Mathf.clamp((int)(explosiveness / 4), 0, 30); + int waves = Mathf.clamp((int) (explosiveness / 4), 0, 30); - for(int i = 0; i < waves; i ++){ - int f = i; - Timers.run(i*2f, () -> { - Damage.damage(x, y, Mathf.clamp(radius + explosiveness, 0, 50f) * ((f + 1f)/waves), explosiveness/2f); - Effects.effect(ExplosionFx.blockExplosionSmoke, x + Mathf.range(radius), y + Mathf.range(radius)); - }); - } + for(int i = 0; i < waves; i++){ + int f = i; + Timers.run(i * 2f, () -> { + Damage.damage(x, y, Mathf.clamp(radius + explosiveness, 0, 50f) * ((f + 1f) / waves), explosiveness / 2f); + Effects.effect(ExplosionFx.blockExplosionSmoke, x + Mathf.range(radius), y + Mathf.range(radius)); + }); + } - if(explosiveness > 15f){ - Effects.effect(ExplosionFx.shockwave, x, y); - } + if(explosiveness > 15f){ + Effects.effect(ExplosionFx.shockwave, x, y); + } - if(explosiveness > 30f){ - Effects.effect(ExplosionFx.bigShockwave, x, y); - } + if(explosiveness > 30f){ + Effects.effect(ExplosionFx.bigShockwave, x, y); + } - float shake = Math.min(explosiveness/4f + 3f, 9f); - Effects.shake(shake, shake, x, y); - Effects.effect(ExplosionFx.blockExplosion, x, y); - } + float shake = Math.min(explosiveness / 4f + 3f, 9f); + Effects.shake(shake, shake, x, y); + Effects.effect(ExplosionFx.blockExplosion, x, y); + } - public static void createIncend(float x, float y, float range, int amount){ - for (int i = 0; i < amount; i++) { - float cx = x + Mathf.range(range); - float cy = y + Mathf.range(range); - Tile tile = world.tileWorld(cx, cy); - if(tile != null){ - Fire.create(tile); - } - } - } + public static void createIncend(float x, float y, float range, int amount){ + for(int i = 0; i < amount; i++){ + float cx = x + Mathf.range(range); + float cy = y + Mathf.range(range); + Tile tile = world.tileWorld(cx, cy); + if(tile != null){ + Fire.create(tile); + } + } + } - /**Damages entities in a line. - * Only enemies of the specified team are damaged.*/ - public static void collideLine(SolidEntity hitter, Team team, Effect effect, float x, float y, float angle, float length){ - tr.trns(angle, length); - rect.setPosition(x, y).setSize(tr.x, tr.y); - float x2 = tr.x + x, y2 = tr.y + y; + /** + * Damages entities in a line. + * Only enemies of the specified team are damaged. + */ + public static void collideLine(SolidEntity hitter, Team team, Effect effect, float x, float y, float angle, float length){ + tr.trns(angle, length); + rect.setPosition(x, y).setSize(tr.x, tr.y); + float x2 = tr.x + x, y2 = tr.y + y; - if(rect.width < 0){ - rect.x += rect.width; - rect.width *= -1; - } + if(rect.width < 0){ + rect.x += rect.width; + rect.width *= -1; + } - if(rect.height < 0){ - rect.y += rect.height; - rect.height *= -1; - } + if(rect.height < 0){ + rect.y += rect.height; + rect.height *= -1; + } - float expand = 3f; + float expand = 3f; - rect.y -= expand; - rect.x -= expand; - rect.width += expand*2; - rect.height += expand*2; + rect.y -= expand; + rect.x -= expand; + rect.width += expand * 2; + rect.height += expand * 2; Consumer cons = e -> { - e.getHitbox(hitrect); + e.getHitbox(hitrect); Rectangle other = hitrect; other.y -= expand; other.x -= expand; @@ -110,79 +116,85 @@ public class Damage { Vector2 vec = Physics.raycastRect(x, y, x2, y2, other); - if (vec != null) { + if(vec != null){ Effects.effect(effect, vec.x, vec.y); e.collision(hitter, vec.x, vec.y); hitter.collision(e, vec.x, vec.y); } }; - Units.getNearbyEnemies(team, rect, cons); - } + Units.getNearbyEnemies(team, rect, cons); + } - /**Damages all entities and blocks in a radius that are enemies of the team.*/ - public static void damageUnits(Team team, float x, float y, float size, float damage, Predicate predicate, Consumer acceptor) { - Consumer cons = entity -> { - if(!predicate.test(entity)) return; + /** + * Damages all entities and blocks in a radius that are enemies of the team. + */ + public static void damageUnits(Team team, float x, float y, float size, float damage, Predicate predicate, Consumer acceptor){ + Consumer cons = entity -> { + if(!predicate.test(entity)) return; - entity.getHitbox(hitrect); - if (!hitrect.overlaps(rect)) { - return; - } - entity.damage(damage); - acceptor.accept(entity); - }; + entity.getHitbox(hitrect); + if(!hitrect.overlaps(rect)){ + return; + } + entity.damage(damage); + acceptor.accept(entity); + }; - rect.setSize(size * 2).setCenter(x, y); - if (team != null) { - Units.getNearbyEnemies(team, rect, cons); - } else { - Units.getNearby(rect, cons); - } - } + rect.setSize(size * 2).setCenter(x, y); + if(team != null){ + Units.getNearbyEnemies(team, rect, cons); + }else{ + Units.getNearby(rect, cons); + } + } - /**Damages everything in a radius.*/ - public static void damage(float x, float y, float radius, float damage){ - damage(null, x, y, radius, damage); - } + /** + * Damages everything in a radius. + */ + public static void damage(float x, float y, float radius, float damage){ + damage(null, x, y, radius, damage); + } - /**Damages all entities and blocks in a radius that are enemies of the team.*/ - public static void damage(Team team, float x, float y, float radius, float damage){ - Consumer cons = entity -> { - if(entity.team == team || entity.distanceTo(x, y) > radius){ - return; - } - float amount = calculateDamage(x, y, entity.x, entity.y, radius, damage); - entity.damage(amount); - //TODO better velocity displacement - float dst = tr.set(entity.x - x, entity.y - y).len(); - entity.getVelocity().add(tr.setLength((1f-dst/radius) * 2f)); - }; + /** + * Damages all entities and blocks in a radius that are enemies of the team. + */ + public static void damage(Team team, float x, float y, float radius, float damage){ + Consumer cons = entity -> { + if(entity.team == team || entity.distanceTo(x, y) > radius){ + return; + } + float amount = calculateDamage(x, y, entity.x, entity.y, radius, damage); + entity.damage(amount); + //TODO better velocity displacement + float dst = tr.set(entity.x - x, entity.y - y).len(); + entity.getVelocity().add(tr.setLength((1f - dst / radius) * 2f)); + }; - rect.setSize(radius *2).setCenter(x, y); - if(team != null) { - Units.getNearbyEnemies(team, rect, cons); - }else{ - Units.getNearby(rect, cons); - } + rect.setSize(radius * 2).setCenter(x, y); + if(team != null){ + Units.getNearbyEnemies(team, rect, cons); + }else{ + Units.getNearby(rect, cons); + } - int trad = (int)(radius / tilesize); - for(int dx = -trad; dx <= trad; dx ++){ - for(int dy= -trad; dy <= trad; dy ++){ - Tile tile = world.tile(Mathf.scl2(x, tilesize) + dx, Mathf.scl2(y, tilesize) + dy); - if(tile != null && tile.entity != null && (team == null || state.teams.areEnemies(team, tile.getTeam())) && Vector2.dst(dx, dy, 0, 0) <= trad){ - float amount = calculateDamage(x, y, tile.worldx(), tile.worldy(), radius, damage); - tile.entity.damage(amount); - } - } - } + int trad = (int) (radius / tilesize); + for(int dx = -trad; dx <= trad; dx++){ + for(int dy = -trad; dy <= trad; dy++){ + Tile tile = world.tile(Mathf.scl2(x, tilesize) + dx, Mathf.scl2(y, tilesize) + dy); + if(tile != null && tile.entity != null && (team == null || state.teams.areEnemies(team, tile.getTeam())) && Vector2.dst(dx, dy, 0, 0) <= trad){ + float amount = calculateDamage(x, y, tile.worldx(), tile.worldy(), radius, damage); + tile.entity.damage(amount); + } + } + } - } - - private static float calculateDamage(float x, float y, float tx, float ty, float radius, float damage){ - float dist = Vector2.dst(x, y, tx, ty); - float falloff = 0.4f; - float scaled = Mathf.lerp(1f - dist/radius, 1f, falloff); - return damage * scaled; - } + } + + private static float calculateDamage(float x, float y, float tx, float ty, float radius, float damage){ + float dist = Vector2.dst(x, y, tx, ty); + float falloff = 0.4f; + float scaled = Mathf.lerp(1f - dist / radius, 1f, falloff); + return damage * scaled; + } } diff --git a/core/src/io/anuke/mindustry/entities/Player.java b/core/src/io/anuke/mindustry/entities/Player.java index 064377e7d3..d5b3b34a05 100644 --- a/core/src/io/anuke/mindustry/entities/Player.java +++ b/core/src/io/anuke/mindustry/entities/Player.java @@ -26,7 +26,10 @@ import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.Floor; import io.anuke.mindustry.world.blocks.storage.CoreBlock.CoreEntity; import io.anuke.mindustry.world.blocks.units.MechFactory; -import io.anuke.ucore.core.*; +import io.anuke.ucore.core.Core; +import io.anuke.ucore.core.Graphics; +import io.anuke.ucore.core.Inputs; +import io.anuke.ucore.core.Timers; import io.anuke.ucore.entities.EntityGroup; import io.anuke.ucore.entities.trait.SolidTrait; import io.anuke.ucore.graphics.Draw; @@ -39,87 +42,109 @@ import java.io.IOException; import static io.anuke.mindustry.Vars.*; -public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTrait { - private static final int timerShootLeft = 0; - private static final int timerShootRight = 1; +public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTrait{ + public static final int timerSync = 2; + private static final int timerShootLeft = 0; + private static final int timerShootRight = 1; - public static final int timerSync = 2; + //region instance variables, constructor + public float baseRotation; - //region instance variables, constructor + public float pointerX, pointerY; + public String name = "name"; + public String uuid, usid; + public boolean isAdmin, isTransferring, isShooting, isBoosting, isMobile; + public float boostHeat; + public Color color = new Color(); + public Mech mech; + public int spawner; - public float baseRotation; + public NetConnection con; + public int playerIndex = 0; + public boolean isLocal = false; + public Timer timer = new Timer(4); + public TargetTrait target; + public TargetTrait moveTarget; - public float pointerX, pointerY; - public String name = "name"; - public String uuid, usid; - public boolean isAdmin, isTransferring, isShooting, isBoosting, isMobile; - public float boostHeat; - public Color color = new Color(); - public Mech mech; - public int spawner; + private float walktime; + private Queue placeQueue = new ThreadQueue<>(); + private Tile mining; + private CarriableTrait carrying; + private Trail trail = new Trail(12); + private Vector2 movement = new Vector2(); + private boolean moved; - public NetConnection con; - public int playerIndex = 0; - public boolean isLocal = false; - public Timer timer = new Timer(4); - public TargetTrait target; - public TargetTrait moveTarget; + public Player(){ + hitbox.setSize(5); + hitboxTile.setSize(4f); + } - private float walktime; - private Queue placeQueue = new ThreadQueue<>(); - private Tile mining; - private CarriableTrait carrying; - private Trail trail = new Trail(12); - private Vector2 movement = new Vector2(); - private boolean moved; - - public Player(){ - hitbox.setSize(5); - hitboxTile.setSize(4f); - } + //endregion - //endregion + //region unit and event overrides, utility methods - //region unit and event overrides, utility methods + @Remote(in = In.entities, targets = Loc.server, called = Loc.server) + public static void onPlayerDamage(Player player, float amount){ + if(player == null) return; + player.hitTime = hitDuration; + player.health -= amount; + } - @Override - public Timer getTimer() { - return timer; - } + @Remote(in = In.entities, targets = Loc.server, called = Loc.server) + public static void onPlayerDeath(Player player){ + if(player == null) return; - @Override - public int getShootTimer(boolean left) { - return left ? timerShootLeft : timerShootRight; - } + player.dead = true; + player.placeQueue.clear(); - @Override - public Weapon getWeapon() { - return mech.weapon; - } + player.dropCarry(); - @Override - public float getMinePower() { - return mech.mineSpeed; - } + float explosiveness = 2f + (player.inventory.hasItem() ? player.inventory.getItem().item.explosiveness * player.inventory.getItem().amount : 0f); + float flammability = (player.inventory.hasItem() ? player.inventory.getItem().item.flammability * player.inventory.getItem().amount : 0f); + Damage.dynamicExplosion(player.x, player.y, flammability, explosiveness, 0f, player.getSize() / 2f, Palette.darkFlame); - @Override - public TextureRegion getIconRegion() { - return mech.iconRegion; - } + ScorchDecal.create(player.x, player.y); + player.onDeath(); + } - @Override - public int getItemCapacity() { - return mech.itemCapacity; - } + @Override + public Timer getTimer(){ + return timer; + } - @Override - public int getAmmoCapacity() { - return mech.ammoCapacity; - } + @Override + public int getShootTimer(boolean left){ + return left ? timerShootLeft : timerShootRight; + } - @Override - public void interpolate() { + @Override + public Weapon getWeapon(){ + return mech.weapon; + } + + @Override + public float getMinePower(){ + return mech.mineSpeed; + } + + @Override + public TextureRegion getIconRegion(){ + return mech.iconRegion; + } + + @Override + public int getItemCapacity(){ + return mech.itemCapacity; + } + + @Override + public int getAmmoCapacity(){ + return mech.ammoCapacity; + } + + @Override + public void interpolate(){ super.interpolate(); if(interpolator.values.length > 1){ @@ -131,579 +156,558 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra } } - @Override - public CarriableTrait getCarry() { - return carrying; - } - - @Override - public void setCarry(CarriableTrait unit) { - this.carrying = unit; - } - - @Override - public float getCarryWeight() { - return mech.carryWeight; - } - - @Override - public float getBuildPower(Tile tile) { - return mech.buildPower; - } - - @Override - public float maxHealth() { - return 200; - } - - @Override - public Tile getMineTile() { - return mining; - } - - @Override - public void setMineTile(Tile tile) { - this.mining = tile; - } - - @Override - public float getArmor() { - return mech.armor; - } - - @Override - public boolean acceptsAmmo(Item item) { - return mech.weapon.getAmmoType(item) != null && inventory.canAcceptAmmo(mech.weapon.getAmmoType(item)); - } - - @Override - public void added() { - baseRotation = 90f; - } - - @Override - public void addAmmo(Item item) { - inventory.addAmmo(mech.weapon.getAmmoType(item)); - } - - @Override - public float getMass(){ - return mech.mass; + @Override + public CarriableTrait getCarry(){ + return carrying; } @Override - public boolean isFlying(){ - return mech.flying || noclip || isCarried(); - } + public void setCarry(CarriableTrait unit){ + this.carrying = unit; + } - @Override - public float getSize() { - return 8; - } + @Override + public float getCarryWeight(){ + return mech.carryWeight; + } - @Override - public void damage(float amount){ - CallEntity.onPlayerDamage(this, calculateDamage(amount)); + @Override + public float getBuildPower(Tile tile){ + return mech.buildPower; + } - if(health <= 0 && !dead){ - CallEntity.onPlayerDeath(this); - } - } + @Override + public float maxHealth(){ + return 200; + } - @Override - public boolean collides(SolidTrait other) { - return super.collides(other) || other instanceof ItemDrop; - } + @Override + public Tile getMineTile(){ + return mining; + } - @Remote(in = In.entities, targets = Loc.server, called = Loc.server) - public static void onPlayerDamage(Player player, float amount){ - if(player == null) return; + @Override + public void setMineTile(Tile tile){ + this.mining = tile; + } - player.hitTime = hitDuration; - player.health -= amount; - } + @Override + public float getArmor(){ + return mech.armor; + } - @Remote(in = In.entities, targets = Loc.server, called = Loc.server) - public static void onPlayerDeath(Player player){ - if(player == null) return; + @Override + public boolean acceptsAmmo(Item item){ + return mech.weapon.getAmmoType(item) != null && inventory.canAcceptAmmo(mech.weapon.getAmmoType(item)); + } - player.dead = true; - player.placeQueue.clear(); + @Override + public void added(){ + baseRotation = 90f; + } - player.dropCarry(); + @Override + public void addAmmo(Item item){ + inventory.addAmmo(mech.weapon.getAmmoType(item)); + } - float explosiveness = 2f + (player.inventory.hasItem() ? player.inventory.getItem().item.explosiveness * player.inventory.getItem().amount : 0f); - float flammability = (player.inventory.hasItem() ? player.inventory.getItem().item.flammability * player.inventory.getItem().amount : 0f); - Damage.dynamicExplosion(player.x, player.y, flammability, explosiveness, 0f, player.getSize()/2f, Palette.darkFlame); + @Override + public float getMass(){ + return mech.mass; + } - ScorchDecal.create(player.x, player.y); - player.onDeath(); - } + @Override + public boolean isFlying(){ + return mech.flying || noclip || isCarried(); + } - @Override - public void set(float x, float y){ - this.x = x; - this.y = y; + @Override + public float getSize(){ + return 8; + } - if(isFlying() && isLocal){ - Core.camera.position.set(x, y, 0f); - } - } + @Override + public void damage(float amount){ + CallEntity.onPlayerDamage(this, calculateDamage(amount)); - @Override - public void removed() { + if(health <= 0 && !dead){ + CallEntity.onPlayerDeath(this); + } + } + + @Override + public boolean collides(SolidTrait other){ + return super.collides(other) || other instanceof ItemDrop; + } + + @Override + public void set(float x, float y){ + this.x = x; + this.y = y; + + if(isFlying() && isLocal){ + Core.camera.position.set(x, y, 0f); + } + } + + @Override + public void removed(){ dropCarryLocal(); TileEntity core = getClosestCore(); - if(core != null && ((CoreEntity)core).currentUnit == this){ - ((CoreEntity)core).currentUnit = null; - } - } + if(core != null && ((CoreEntity) core).currentUnit == this){ + ((CoreEntity) core).currentUnit = null; + } + } - @Override - public EntityGroup targetGroup() { - return playerGroup; - } + @Override + public EntityGroup targetGroup(){ + return playerGroup; + } - //endregion + //endregion - //region draw methods + //region draw methods - @Override - public float drawSize() { - return isLocal ? Float.MAX_VALUE : 40; - } + @Override + public float drawSize(){ + return isLocal ? Float.MAX_VALUE : 40; + } - @Override - public void drawShadow(){ - Draw.rect(mech.iconRegion, x + elevation*elevationScale, y - elevation*elevationScale, rotation - 90); - } + @Override + public void drawShadow(){ + Draw.rect(mech.iconRegion, x + elevation * elevationScale, y - elevation * elevationScale, rotation - 90); + } - @Override - public void draw(){ - if((debug && (!showPlayer || !showUI)) || dead) return; + @Override + public void draw(){ + if((debug && (!showPlayer || !showUI)) || dead) return; - if(!movement.isZero() && moved){ - walktime += Timers.delta() * movement.len()/0.7f * getFloorOn().speedMultiplier; - baseRotation = Mathf.slerpDelta(baseRotation, movement.angle(), 0.13f); - } + if(!movement.isZero() && moved){ + walktime += Timers.delta() * movement.len() / 0.7f * getFloorOn().speedMultiplier; + baseRotation = Mathf.slerpDelta(baseRotation, movement.angle(), 0.13f); + } - boostHeat = Mathf.lerpDelta(boostHeat, isBoosting && ((!movement.isZero() && moved) || !isLocal) ? 1f : 0f, 0.08f); + boostHeat = Mathf.lerpDelta(boostHeat, isBoosting && ((!movement.isZero() && moved) || !isLocal) ? 1f : 0f, 0.08f); boolean snap = snapCamera && isLocal; - float px = x, py =y; + float px = x, py = y; - if(snap){ - x = (int)(x + 0.0001f); - y = (int)(y + 0.0001f); - } - - float ft = Mathf.sin(walktime, 6f, 2f) * (1f-boostHeat); - - Floor floor = getFloorOn(); - - Draw.color(); - Draw.alpha(hitTime / hitDuration); - - if(!mech.flying) { - if(floor.isLiquid){ - Draw.tint(Color.WHITE, floor.liquidColor, 0.5f); - } - - float boostTrnsY = -boostHeat * 3f; - float boostTrnsX = boostHeat * 3f; - float boostAng = boostHeat*40f; - - for (int i : Mathf.signs) { - Draw.rect(mech.legRegion, - x + Angles.trnsx(baseRotation, ft * i + boostTrnsY, -boostTrnsX*i), - y + Angles.trnsy(baseRotation, ft * i + boostTrnsY, -boostTrnsX*i), - 12f * i, 12f - Mathf.clamp(ft * i, 0, 2), baseRotation - 90 + boostAng*i); - } - - Draw.rect(mech.baseRegion, x, y, baseRotation- 90); - } - - if(floor.isLiquid) { - Draw.tint(Color.WHITE, floor.liquidColor, drownTime * 0.4f); - }else { - Draw.tint(Color.WHITE); - } - - Draw.rect(mech.region, x, y, rotation -90); - - for (int i : Mathf.signs) { - float tra = rotation - 90, trY = - mech.weapon.getRecoil(this, i > 0) + mech.weaponOffsetY; - float w = i > 0 ? -12 : 12; - Draw.rect(mech.weapon.equipRegion, - x + Angles.trnsx(tra, mech.weaponOffsetX * i, trY), - y + Angles.trnsy(tra, mech.weaponOffsetX * i, trY), w, 12, rotation - 90); - } - - float backTrns = 4f, itemSize = 5f; - if(inventory.hasItem()){ - ItemStack stack = inventory.getItem(); - int stored = Mathf.clamp(stack.amount / 6, 1, 8); - - for(int i = 0; i < stored; i ++) { - float angT = i == 0 ? 0 : Mathf.randomSeedRange(i + 1, 60f); - float lenT = i == 0 ? 0 : Mathf.randomSeedRange(i + 2, 1f) - 1f; - Draw.rect(stack.item.region, - x + Angles.trnsx(rotation + 180f + angT, backTrns + lenT), - y + Angles.trnsy(rotation + 180f + angT, backTrns + lenT), - itemSize, itemSize, rotation); - } - } - - Draw.alpha(1f); - - x = px; - y = py; - } - - @Override - public void drawOver(){ - if(dead) return; - - if(!isShooting()) { - drawBuilding(this); + if(snap){ + x = (int) (x + 0.0001f); + y = (int) (y + 0.0001f); } - if(mech.flying || boostHeat > 0.001f){ - float wobblyness = 0.6f; - trail.update(x + Angles.trnsx(rotation + 180f, 5f) + Mathf.range(wobblyness), - y + Angles.trnsy(rotation + 180f, 5f) + Mathf.range(wobblyness)); - trail.draw(mech.trailColor, 5f * (isFlying() ? 1f : boostHeat)); - }else{ - trail.clear(); - } + float ft = Mathf.sin(walktime, 6f, 2f) * (1f - boostHeat); + + Floor floor = getFloorOn(); + + Draw.color(); + Draw.alpha(hitTime / hitDuration); + + if(!mech.flying){ + if(floor.isLiquid){ + Draw.tint(Color.WHITE, floor.liquidColor, 0.5f); + } + + float boostTrnsY = -boostHeat * 3f; + float boostTrnsX = boostHeat * 3f; + float boostAng = boostHeat * 40f; + + for(int i : Mathf.signs){ + Draw.rect(mech.legRegion, + x + Angles.trnsx(baseRotation, ft * i + boostTrnsY, -boostTrnsX * i), + y + Angles.trnsy(baseRotation, ft * i + boostTrnsY, -boostTrnsX * i), + 12f * i, 12f - Mathf.clamp(ft * i, 0, 2), baseRotation - 90 + boostAng * i); + } + + Draw.rect(mech.baseRegion, x, y, baseRotation - 90); + } + + if(floor.isLiquid){ + Draw.tint(Color.WHITE, floor.liquidColor, drownTime * 0.4f); + }else{ + Draw.tint(Color.WHITE); + } + + Draw.rect(mech.region, x, y, rotation - 90); + + for(int i : Mathf.signs){ + float tra = rotation - 90, trY = -mech.weapon.getRecoil(this, i > 0) + mech.weaponOffsetY; + float w = i > 0 ? -12 : 12; + Draw.rect(mech.weapon.equipRegion, + x + Angles.trnsx(tra, mech.weaponOffsetX * i, trY), + y + Angles.trnsy(tra, mech.weaponOffsetX * i, trY), w, 12, rotation - 90); + } + + float backTrns = 4f, itemSize = 5f; + if(inventory.hasItem()){ + ItemStack stack = inventory.getItem(); + int stored = Mathf.clamp(stack.amount / 6, 1, 8); + + for(int i = 0; i < stored; i++){ + float angT = i == 0 ? 0 : Mathf.randomSeedRange(i + 1, 60f); + float lenT = i == 0 ? 0 : Mathf.randomSeedRange(i + 2, 1f) - 1f; + Draw.rect(stack.item.region, + x + Angles.trnsx(rotation + 180f + angT, backTrns + lenT), + y + Angles.trnsy(rotation + 180f + angT, backTrns + lenT), + itemSize, itemSize, rotation); + } + } + + Draw.alpha(1f); + + x = px; + y = py; + } + + @Override + public void drawOver(){ + if(dead) return; + + if(!isShooting()){ + drawBuilding(this); + } + + if(mech.flying || boostHeat > 0.001f){ + float wobblyness = 0.6f; + trail.update(x + Angles.trnsx(rotation + 180f, 5f) + Mathf.range(wobblyness), + y + Angles.trnsy(rotation + 180f, 5f) + Mathf.range(wobblyness)); + trail.draw(mech.trailColor, 5f * (isFlying() ? 1f : boostHeat)); + }else{ + trail.clear(); + } } public void drawName(){ - GlyphLayout layout = Pools.obtain(GlyphLayout.class); - - Draw.tscl(0.25f/2); - layout.setText(Core.font, name); - Draw.color(0f, 0f, 0f, 0.3f); - Draw.rect("blank", x, y + 8 - layout.height/2, layout.width + 2, layout.height + 2); - Draw.color(); - Draw.tcolor(color); - Draw.text(name, x, y + 8); - - if(isAdmin){ - Draw.color(color); - float s = 3f; - Draw.rect("icon-admin-small", x + layout.width/2f + 2 + 1, y + 7f, s, s); - } - - Draw.reset(); - Pools.free(layout); - Draw.tscl(fontScale); - } - - /**Draw all current build requests. Does not draw the beam effect, only the positions.*/ - public void drawBuildRequests(){ - synchronized (getPlaceQueue()) { - for (BuildRequest request : getPlaceQueue()) { - - if (request.remove) { - Block block = world.tile(request.x, request.y).target().block(); - - //draw removal request - Draw.color(Palette.remove); - - Lines.stroke((1f - request.progress)); - - Lines.poly(request.x * tilesize + block.offset(), - request.y * tilesize + block.offset(), - 4, block.size * tilesize / 2f, 45 + 15); - } else { - //draw place request - Draw.color(Palette.accent); - - Lines.stroke((1f - request.progress)); - - Lines.poly(request.x * tilesize + request.recipe.result.offset(), - request.y * tilesize + request.recipe.result.offset(), - 4, request.recipe.result.size * tilesize / 2f, 45 + 15); - } - } - - Draw.reset(); - } - } - - //endregion - - //region update methods - - @Override - public void update(){ - hitTime = Math.max(0f, hitTime - Timers.delta()); - - if(isDead()){ - isBoosting = false; - boostHeat = 0f; - updateRespawning(); - return; - }else{ - spawner = -1; - } - - if(!isLocal){ - interpolate(); - updateBuilding(this); //building happens even with non-locals - status.update(this); //status effect updating also happens with non locals for effect purposes - - if(getCarrier() != null){ - x = getCarrier().getX(); - y = getCarrier().getY(); - } - - if(Net.server()){ - updateShooting(); //server simulates player shooting - } - return; - } - - if(mobile){ - updateFlying(); - }else{ - updateMech(); - } - - if(isLocal) { - avoidOthers(8f); - } - - if(!isShooting()) { - updateBuilding(this); - } - - x = Mathf.clamp(x, 0, world.width() * tilesize); - y = Mathf.clamp(y, 0, world.height() * tilesize); - } - - protected void updateMech(){ - Tile tile = world.tileWorld(x, y); - - //if player is in solid block - if(!mech.flying && tile != null && tile.solid() && !noclip) { - damage(health + 1); //die instantly - } - - if(ui.chatfrag.chatOpen()) return; - - float speed = isBoosting && !mech.flying ? debug ? 5f : mech.boostSpeed : mech.speed; - //fraction of speed when at max load - float carrySlowdown = 0.7f; - - speed *= ((inventory.hasItem() ? Mathf.lerp(1f, carrySlowdown, (float)inventory.getItem().amount/inventory.capacity()) : 1f)); - - if(mech.flying){ - //prevent strafing backwards, have a penalty for doing so - float angDist = Angles.angleDist(rotation, velocity.angle()) / 180f; - float penalty = 0.2f; //when going 180 degrees backwards, reduce speed to 0.2x - speed *= Mathf.lerp(1f, penalty, angDist); - } - - //drop from carrier on key press - if(Inputs.keyTap("drop_unit")){ - if(!mech.flying) { - if (getCarrier() != null) { - CallEntity.dropSelf(this); - } - }else if(getCarry() != null){ - dropCarry(); - }else{ - Unit unit = Units.getClosest(team, x, y, 8f, - u -> !u.isFlying() && u.getMass() <= mech.carryWeight); - - if(unit != null){ - carry(unit); - } - } - } - - movement.setZero(); - - String section = control.input(playerIndex).section; - - float xa = Inputs.getAxis(section, "move_x"); - float ya = Inputs.getAxis(section, "move_y"); - - movement.y += ya*speed; - movement.x += xa*speed; - - Vector2 vec = Graphics.world(Vars.control.input(playerIndex).getMouseX(), - Vars.control.input(playerIndex).getMouseY()); - pointerX = vec.x; - pointerY = vec.y; - updateShooting(); - - movement.limit(speed * Timers.delta()); - - if(getCarrier() == null){ - velocity.add(movement); - float prex = x, prey = y; - updateVelocityStatus(mech.drag, 10f); - moved = distanceTo(prex, prey) > 0.01f; - }else{ - velocity.setZero(); - x = Mathf.lerpDelta(x, getCarrier().getX(), 0.1f); - y = Mathf.lerpDelta(y, getCarrier().getY(), 0.1f); - } - - if(!isShooting()){ - if(!movement.isZero()) { - rotation = Mathf.slerpDelta(rotation, movement.angle(), 0.13f); - } - }else{ - float angle = control.input(playerIndex).mouseAngle(x, y); - this.rotation = Mathf.slerpDelta(this.rotation, angle, 0.1f); - } - } - - protected void updateShooting(){ - if(isShooting()){ - mech.weapon.update(this, pointerX, pointerY); - } - } - - protected void updateFlying(){ - if(Units.invalidateTarget(target, this)){ - target = null; - } - - float targetX = Core.camera.position.x, targetY = Core.camera.position.y; - float attractDst = 15f; - - if(moveTarget != null && !moveTarget.isDead()){ - targetX = moveTarget.getX(); - targetY = moveTarget.getY(); - attractDst = 0f; - - if(distanceTo(moveTarget) < 2f){ - if(moveTarget instanceof CarriableTrait){ - carry((CarriableTrait) moveTarget); - }else if(moveTarget instanceof TileEntity && ((TileEntity) moveTarget).tile.block() instanceof MechFactory){ - Tile tile = ((TileEntity) moveTarget).tile; - tile.block().tapped(tile, this); - } - - moveTarget = null; - } - }else{ - moveTarget = null; - } - - movement.set(targetX - x, targetY - y).limit(mech.speed); - movement.setAngle(Mathf.slerp(movement.angle(), velocity.angle(), 0.05f)); - - if(distanceTo(targetX, targetY) < attractDst){ - movement.setZero(); - } - - velocity.add(movement); - - if(velocity.len() <= 0.2f){ - rotation += Mathf.sin(Timers.time() + id * 99, 10f, 1f); - }else{ - rotation = Mathf.slerpDelta(rotation, velocity.angle(), velocity.len()/10f); - } - - updateVelocityStatus(mech.drag, mech.maxSpeed); - - //hovering effect - x += Mathf.sin(Timers.time() + id * 999, 25f, 0.08f); - y += Mathf.cos(Timers.time() + id * 999, 25f, 0.08f); - - //update shooting if not building, not mining and there's ammo left - if(!isBuilding() && inventory.hasAmmo() && getMineTile() == null){ - - //autofire: mobile only! - if(mobile) { - - if (target == null) { - isShooting = false; - target = Units.getClosestTarget(team, x, y, inventory.getAmmoRange()); - } else if(target.isValid()){ - //rotate toward and shoot the target - rotation = Mathf.slerpDelta(rotation, angleTo(target), 0.2f); - - Vector2 intercept = - Predict.intercept(x, y, target.getX(), target.getY(), target.getVelocity().x - velocity.x, target.getVelocity().y - velocity.y, inventory.getAmmo().bullet.speed); - - pointerX = intercept.x; - pointerY = intercept.y; - - updateShooting(); - isShooting = true; - } - - }else if(isShooting()){ - Vector2 vec = Graphics.world(Vars.control.input(playerIndex).getMouseX(), - Vars.control.input(playerIndex).getMouseY()); - pointerX = vec.x; - pointerY = vec.y; - - updateShooting(); - } - } - } - - //endregion - - //region utility methods - - public void toggleTeam(){ - team = (team == Team.blue ? Team.red : Team.blue); - } - - /**Resets all values of the player.*/ - public void reset(){ - status.clear(); - team = Team.blue; - inventory.clear(); - placeQueue.clear(); - dead = true; - trail.clear(); - health = maxHealth(); - mech = (mobile ? Mechs.starterMobile : Mechs.starterDesktop); - placeQueue.clear(); - - add(); - } - - public boolean isShooting(){ - return isShooting && inventory.hasAmmo() && (!isBoosting || mech.flying); - } - - public void updateRespawning(){ - - if (spawner != -1 && world.tile(spawner) != null && world.tile(spawner).entity instanceof SpawnerTrait) { - ((SpawnerTrait) world.tile(spawner).entity).updateSpawning(this); - }else{ - CoreEntity entity = (CoreEntity)getClosestCore(); - if(entity != null){ - this.spawner = entity.tile.id(); - } - } - } - - public void beginRespawning(SpawnerTrait spawner){ - this.spawner = spawner.getTile().packedPosition(); - this.dead = true; - } - - @Override - public Queue getPlaceQueue(){ - return placeQueue; - } + GlyphLayout layout = Pools.obtain(GlyphLayout.class); + + Draw.tscl(0.25f / 2); + layout.setText(Core.font, name); + Draw.color(0f, 0f, 0f, 0.3f); + Draw.rect("blank", x, y + 8 - layout.height / 2, layout.width + 2, layout.height + 2); + Draw.color(); + Draw.tcolor(color); + Draw.text(name, x, y + 8); + + if(isAdmin){ + Draw.color(color); + float s = 3f; + Draw.rect("icon-admin-small", x + layout.width / 2f + 2 + 1, y + 7f, s, s); + } + + Draw.reset(); + Pools.free(layout); + Draw.tscl(fontScale); + } + + /** + * Draw all current build requests. Does not draw the beam effect, only the positions. + */ + public void drawBuildRequests(){ + synchronized(getPlaceQueue()){ + for(BuildRequest request : getPlaceQueue()){ + + if(request.remove){ + Block block = world.tile(request.x, request.y).target().block(); + + //draw removal request + Draw.color(Palette.remove); + + Lines.stroke((1f - request.progress)); + + Lines.poly(request.x * tilesize + block.offset(), + request.y * tilesize + block.offset(), + 4, block.size * tilesize / 2f, 45 + 15); + }else{ + //draw place request + Draw.color(Palette.accent); + + Lines.stroke((1f - request.progress)); + + Lines.poly(request.x * tilesize + request.recipe.result.offset(), + request.y * tilesize + request.recipe.result.offset(), + 4, request.recipe.result.size * tilesize / 2f, 45 + 15); + } + } + + Draw.reset(); + } + } + + //endregion + + //region update methods @Override - public String toString() { + public void update(){ + hitTime = Math.max(0f, hitTime - Timers.delta()); + + if(isDead()){ + isBoosting = false; + boostHeat = 0f; + updateRespawning(); + return; + }else{ + spawner = -1; + } + + if(!isLocal){ + interpolate(); + updateBuilding(this); //building happens even with non-locals + status.update(this); //status effect updating also happens with non locals for effect purposes + + if(getCarrier() != null){ + x = getCarrier().getX(); + y = getCarrier().getY(); + } + + if(Net.server()){ + updateShooting(); //server simulates player shooting + } + return; + } + + if(mobile){ + updateFlying(); + }else{ + updateMech(); + } + + if(isLocal){ + avoidOthers(8f); + } + + if(!isShooting()){ + updateBuilding(this); + } + + x = Mathf.clamp(x, 0, world.width() * tilesize); + y = Mathf.clamp(y, 0, world.height() * tilesize); + } + + protected void updateMech(){ + Tile tile = world.tileWorld(x, y); + + //if player is in solid block + if(!mech.flying && tile != null && tile.solid() && !noclip){ + damage(health + 1); //die instantly + } + + if(ui.chatfrag.chatOpen()) return; + + float speed = isBoosting && !mech.flying ? debug ? 5f : mech.boostSpeed : mech.speed; + //fraction of speed when at max load + float carrySlowdown = 0.7f; + + speed *= ((inventory.hasItem() ? Mathf.lerp(1f, carrySlowdown, (float) inventory.getItem().amount / inventory.capacity()) : 1f)); + + if(mech.flying){ + //prevent strafing backwards, have a penalty for doing so + float angDist = Angles.angleDist(rotation, velocity.angle()) / 180f; + float penalty = 0.2f; //when going 180 degrees backwards, reduce speed to 0.2x + speed *= Mathf.lerp(1f, penalty, angDist); + } + + //drop from carrier on key press + if(Inputs.keyTap("drop_unit")){ + if(!mech.flying){ + if(getCarrier() != null){ + CallEntity.dropSelf(this); + } + }else if(getCarry() != null){ + dropCarry(); + }else{ + Unit unit = Units.getClosest(team, x, y, 8f, + u -> !u.isFlying() && u.getMass() <= mech.carryWeight); + + if(unit != null){ + carry(unit); + } + } + } + + movement.setZero(); + + String section = control.input(playerIndex).section; + + float xa = Inputs.getAxis(section, "move_x"); + float ya = Inputs.getAxis(section, "move_y"); + + movement.y += ya * speed; + movement.x += xa * speed; + + Vector2 vec = Graphics.world(Vars.control.input(playerIndex).getMouseX(), + Vars.control.input(playerIndex).getMouseY()); + pointerX = vec.x; + pointerY = vec.y; + updateShooting(); + + movement.limit(speed * Timers.delta()); + + if(getCarrier() == null){ + velocity.add(movement); + float prex = x, prey = y; + updateVelocityStatus(mech.drag, 10f); + moved = distanceTo(prex, prey) > 0.01f; + }else{ + velocity.setZero(); + x = Mathf.lerpDelta(x, getCarrier().getX(), 0.1f); + y = Mathf.lerpDelta(y, getCarrier().getY(), 0.1f); + } + + if(!isShooting()){ + if(!movement.isZero()){ + rotation = Mathf.slerpDelta(rotation, movement.angle(), 0.13f); + } + }else{ + float angle = control.input(playerIndex).mouseAngle(x, y); + this.rotation = Mathf.slerpDelta(this.rotation, angle, 0.1f); + } + } + + protected void updateShooting(){ + if(isShooting()){ + mech.weapon.update(this, pointerX, pointerY); + } + } + + protected void updateFlying(){ + if(Units.invalidateTarget(target, this)){ + target = null; + } + + float targetX = Core.camera.position.x, targetY = Core.camera.position.y; + float attractDst = 15f; + + if(moveTarget != null && !moveTarget.isDead()){ + targetX = moveTarget.getX(); + targetY = moveTarget.getY(); + attractDst = 0f; + + if(distanceTo(moveTarget) < 2f){ + if(moveTarget instanceof CarriableTrait){ + carry((CarriableTrait) moveTarget); + }else if(moveTarget instanceof TileEntity && ((TileEntity) moveTarget).tile.block() instanceof MechFactory){ + Tile tile = ((TileEntity) moveTarget).tile; + tile.block().tapped(tile, this); + } + + moveTarget = null; + } + }else{ + moveTarget = null; + } + + movement.set(targetX - x, targetY - y).limit(mech.speed); + movement.setAngle(Mathf.slerp(movement.angle(), velocity.angle(), 0.05f)); + + if(distanceTo(targetX, targetY) < attractDst){ + movement.setZero(); + } + + velocity.add(movement); + + if(velocity.len() <= 0.2f){ + rotation += Mathf.sin(Timers.time() + id * 99, 10f, 1f); + }else{ + rotation = Mathf.slerpDelta(rotation, velocity.angle(), velocity.len() / 10f); + } + + updateVelocityStatus(mech.drag, mech.maxSpeed); + + //hovering effect + x += Mathf.sin(Timers.time() + id * 999, 25f, 0.08f); + y += Mathf.cos(Timers.time() + id * 999, 25f, 0.08f); + + //update shooting if not building, not mining and there's ammo left + if(!isBuilding() && inventory.hasAmmo() && getMineTile() == null){ + + //autofire: mobile only! + if(mobile){ + + if(target == null){ + isShooting = false; + target = Units.getClosestTarget(team, x, y, inventory.getAmmoRange()); + }else if(target.isValid()){ + //rotate toward and shoot the target + rotation = Mathf.slerpDelta(rotation, angleTo(target), 0.2f); + + Vector2 intercept = + Predict.intercept(x, y, target.getX(), target.getY(), target.getVelocity().x - velocity.x, target.getVelocity().y - velocity.y, inventory.getAmmo().bullet.speed); + + pointerX = intercept.x; + pointerY = intercept.y; + + updateShooting(); + isShooting = true; + } + + }else if(isShooting()){ + Vector2 vec = Graphics.world(Vars.control.input(playerIndex).getMouseX(), + Vars.control.input(playerIndex).getMouseY()); + pointerX = vec.x; + pointerY = vec.y; + + updateShooting(); + } + } + } + + //endregion + + //region utility methods + + public void toggleTeam(){ + team = (team == Team.blue ? Team.red : Team.blue); + } + + /** + * Resets all values of the player. + */ + public void reset(){ + status.clear(); + team = Team.blue; + inventory.clear(); + placeQueue.clear(); + dead = true; + trail.clear(); + health = maxHealth(); + mech = (mobile ? Mechs.starterMobile : Mechs.starterDesktop); + placeQueue.clear(); + + add(); + } + + public boolean isShooting(){ + return isShooting && inventory.hasAmmo() && (!isBoosting || mech.flying); + } + + public void updateRespawning(){ + + if(spawner != -1 && world.tile(spawner) != null && world.tile(spawner).entity instanceof SpawnerTrait){ + ((SpawnerTrait) world.tile(spawner).entity).updateSpawning(this); + }else{ + CoreEntity entity = (CoreEntity) getClosestCore(); + if(entity != null){ + this.spawner = entity.tile.id(); + } + } + } + + public void beginRespawning(SpawnerTrait spawner){ + this.spawner = spawner.getTile().packedPosition(); + this.dead = true; + } + + @Override + public Queue getPlaceQueue(){ + return placeQueue; + } + + @Override + public String toString(){ return "Player{" + id + ", mech=" + mech.name + ", local=" + isLocal + ", " + x + ", " + y + "}\n"; } @@ -711,84 +715,84 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra //region read and write methods - @Override - public void writeSave(DataOutput stream) throws IOException { - stream.writeBoolean(isLocal); + @Override + public void writeSave(DataOutput stream) throws IOException{ + stream.writeBoolean(isLocal); - if(isLocal){ - stream.writeByte(mech.id); - stream.writeByte(playerIndex); - super.writeSave(stream, false); - } - } + if(isLocal){ + stream.writeByte(mech.id); + stream.writeByte(playerIndex); + super.writeSave(stream, false); + } + } - @Override - public void readSave(DataInput stream) throws IOException { - boolean local = stream.readBoolean(); + @Override + public void readSave(DataInput stream) throws IOException{ + boolean local = stream.readBoolean(); - if(local && !headless){ - byte mechid = stream.readByte(); - int index = stream.readByte(); - players[index].readSaveSuper(stream); - players[index].mech = Upgrade.getByID(mechid); - players[index].dead = false; - }else if(local){ - byte mechid = stream.readByte(); - stream.readByte(); - readSaveSuper(stream); - mech = Upgrade.getByID(mechid); - dead = false; - } - } + if(local && !headless){ + byte mechid = stream.readByte(); + int index = stream.readByte(); + players[index].readSaveSuper(stream); + players[index].mech = Upgrade.getByID(mechid); + players[index].dead = false; + }else if(local){ + byte mechid = stream.readByte(); + stream.readByte(); + readSaveSuper(stream); + mech = Upgrade.getByID(mechid); + dead = false; + } + } - private void readSaveSuper(DataInput stream) throws IOException { - super.readSave(stream); + private void readSaveSuper(DataInput stream) throws IOException{ + super.readSave(stream); - add(); - } + add(); + } - @Override - public void write(DataOutput buffer) throws IOException { - super.writeSave(buffer, !isLocal); - buffer.writeUTF(name); //TODO writing strings is very inefficient - buffer.writeByte(Bits.toByte(isAdmin) | (Bits.toByte(dead) << 1) | (Bits.toByte(isBoosting) << 2)); - buffer.writeInt(Color.rgba8888(color)); - buffer.writeByte(mech.id); - buffer.writeInt(mining == null ? -1 : mining.packedPosition()); - buffer.writeInt(spawner); - buffer.writeShort((short)(baseRotation * 2)); + @Override + public void write(DataOutput buffer) throws IOException{ + super.writeSave(buffer, !isLocal); + buffer.writeUTF(name); //TODO writing strings is very inefficient + buffer.writeByte(Bits.toByte(isAdmin) | (Bits.toByte(dead) << 1) | (Bits.toByte(isBoosting) << 2)); + buffer.writeInt(Color.rgba8888(color)); + buffer.writeByte(mech.id); + buffer.writeInt(mining == null ? -1 : mining.packedPosition()); + buffer.writeInt(spawner); + buffer.writeShort((short) (baseRotation * 2)); - writeBuilding(buffer); - } + writeBuilding(buffer); + } - @Override - public void read(DataInput buffer, long time) throws IOException { - float lastx = x, lasty = y, lastrot = rotation; - super.readSave(buffer); - name = buffer.readUTF(); - byte bools = buffer.readByte(); - isAdmin = (bools & 1) != 0; - dead = (bools & 2) != 0; - boolean boosting = (bools & 4) != 0; - color.set(buffer.readInt()); - mech = Upgrade.getByID(buffer.readByte()); - int mine = buffer.readInt(); - spawner = buffer.readInt(); - float baseRotation = buffer.readShort()/2f; + @Override + public void read(DataInput buffer, long time) throws IOException{ + float lastx = x, lasty = y, lastrot = rotation; + super.readSave(buffer); + name = buffer.readUTF(); + byte bools = buffer.readByte(); + isAdmin = (bools & 1) != 0; + dead = (bools & 2) != 0; + boolean boosting = (bools & 4) != 0; + color.set(buffer.readInt()); + mech = Upgrade.getByID(buffer.readByte()); + int mine = buffer.readInt(); + spawner = buffer.readInt(); + float baseRotation = buffer.readShort() / 2f; - readBuilding(buffer, !isLocal); + readBuilding(buffer, !isLocal); - interpolator.read(lastx, lasty, x, y, time, rotation, baseRotation); - rotation = lastrot; + interpolator.read(lastx, lasty, x, y, time, rotation, baseRotation); + rotation = lastrot; - if(isLocal){ - x = lastx; - y = lasty; - }else{ - mining = world.tile(mine); - isBoosting = boosting; - } - } + if(isLocal){ + x = lastx; + y = lasty; + }else{ + mining = world.tile(mine); + isBoosting = boosting; + } + } - //endregion + //endregion } diff --git a/core/src/io/anuke/mindustry/entities/Predict.java b/core/src/io/anuke/mindustry/entities/Predict.java index ba27f50426..06f86b540c 100644 --- a/core/src/io/anuke/mindustry/entities/Predict.java +++ b/core/src/io/anuke/mindustry/entities/Predict.java @@ -4,12 +4,16 @@ import com.badlogic.gdx.math.Vector2; import io.anuke.mindustry.entities.traits.TargetTrait; import io.anuke.ucore.util.Mathf; -/**Class for predicting shoot angles based on velocities of targets.*/ -public class Predict { +/** + * Class for predicting shoot angles based on velocities of targets. + */ +public class Predict{ private static Vector2 vec = new Vector2(); private static Vector2 vresult = new Vector2(); - /**Calculates of intercept of a stationary and moving target. Do not call from multiple threads! + /** + * Calculates of intercept of a stationary and moving target. Do not call from multiple threads! + * * @param srcx X of shooter * @param srcy Y of shooter * @param dstx X of target @@ -17,52 +21,55 @@ public class Predict { * @param dstvx X velocity of target (subtract shooter X velocity if needed) * @param dstvy Y velocity of target (subtract shooter Y velocity if needed) * @param v speed of bullet - * @return the intercept location*/ - public static Vector2 intercept(float srcx, float srcy, float dstx, float dsty, float dstvx, float dstvy, float v) { + * @return the intercept location + */ + public static Vector2 intercept(float srcx, float srcy, float dstx, float dsty, float dstvx, float dstvy, float v){ float tx = dstx - srcx, ty = dsty - srcy; // Get quadratic equation components - float a = dstvx * dstvx + dstvy * dstvy - v*v; + float a = dstvx * dstvx + dstvy * dstvy - v * v; float b = 2 * (dstvx * tx + dstvy * ty); - float c = tx*tx + ty*ty; + float c = tx * tx + ty * ty; // Solve quadratic Vector2 ts = quad(a, b, c); // Find smallest positive solution Vector2 sol = vresult.set(0, 0); - if (ts != null) { + if(ts != null){ float t0 = ts.x, t1 = ts.y; float t = Math.min(t0, t1); - if (t < 0) t = Math.max(t0, t1); - if (t > 0) { - sol.set(dstx + dstvx*t, dsty + dstvy*t); + if(t < 0) t = Math.max(t0, t1); + if(t > 0){ + sol.set(dstx + dstvx * t, dsty + dstvy * t); } } return sol; } - /**See {@link #intercept(float, float, float, float, float, float, float)}.*/ - public static Vector2 intercept(TargetTrait src, TargetTrait dst, float v) { + /** + * See {@link #intercept(float, float, float, float, float, float, float)}. + */ + public static Vector2 intercept(TargetTrait src, TargetTrait dst, float v){ return intercept(src.getX(), src.getY(), dst.getX(), dst.getY(), dst.getVelocity().x - src.getVelocity().x, dst.getVelocity().x - src.getVelocity().y, v); } - private static Vector2 quad(float a, float b, float c) { + private static Vector2 quad(float a, float b, float c){ Vector2 sol = null; - if (Math.abs(a) < 1e-6) { - if (Math.abs(b) < 1e-6) { - sol = Math.abs(c) < 1e-6 ? vec.set(0,0) : null; - } else { - vec.set(-c/b, -c/b); + if(Math.abs(a) < 1e-6){ + if(Math.abs(b) < 1e-6){ + sol = Math.abs(c) < 1e-6 ? vec.set(0, 0) : null; + }else{ + vec.set(-c / b, -c / b); } - } else { - float disc = b*b - 4*a*c; - if (disc >= 0) { + }else{ + float disc = b * b - 4 * a * c; + if(disc >= 0){ disc = Mathf.sqrt(disc); - a = 2*a; - sol = vec.set((-b-disc)/a, (-b+disc)/a); + a = 2 * a; + sol = vec.set((-b - disc) / a, (-b + disc) / a); } } return sol; diff --git a/core/src/io/anuke/mindustry/entities/StatusController.java b/core/src/io/anuke/mindustry/entities/StatusController.java index 374c009258..fe2e9e6248 100644 --- a/core/src/io/anuke/mindustry/entities/StatusController.java +++ b/core/src/io/anuke/mindustry/entities/StatusController.java @@ -12,7 +12,9 @@ import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; -/**Class for controlling status effects on an entity.*/ +/** + * Class for controlling status effects on an entity. + */ public class StatusController implements Saveable{ private static final StatusEntry globalResult = new StatusEntry(); private static final Array removals = new ThreadArray<>(); @@ -26,20 +28,20 @@ public class StatusController implements Saveable{ public void handleApply(Unit unit, StatusEffect effect, float intensity){ if(effect == StatusEffects.none) return; //don't apply empty effects - float newTime = effect.baseDuration*intensity; + float newTime = effect.baseDuration * intensity; if(statuses.size > 0){ //check for opposite effects for(StatusEntry entry : statuses){ //extend effect - if(entry.effect == effect) { + if(entry.effect == effect){ entry.time = Math.max(entry.time, newTime); return; }else if(entry.effect.isOpposite(effect)){ //find opposite entry.effect.getTransition(unit, effect, entry.time, newTime, globalResult); entry.time = globalResult.time; - if (globalResult.effect != entry.effect) { + if(globalResult.effect != entry.effect){ entry.effect.onTransition(unit, globalResult.effect); entry.effect = globalResult.effect; } @@ -94,7 +96,7 @@ public class StatusController implements Saveable{ return damageMultiplier; } - public float getArmorMultiplier() { + public float getArmorMultiplier(){ return armorMultiplier; } @@ -106,24 +108,24 @@ public class StatusController implements Saveable{ } @Override - public void writeSave(DataOutput stream) throws IOException { + public void writeSave(DataOutput stream) throws IOException{ stream.writeByte(statuses.size); for(StatusEntry entry : statuses){ stream.writeByte(entry.effect.id); - stream.writeShort((short)(entry.time * 2)); + stream.writeShort((short) (entry.time * 2)); } } @Override - public void readSave(DataInput stream) throws IOException { - for (StatusEntry effect : statuses){ + public void readSave(DataInput stream) throws IOException{ + for(StatusEntry effect : statuses){ Pooling.free(effect); } statuses.clear(); byte amount = stream.readByte(); - for (int i = 0; i < amount; i++) { + for(int i = 0; i < amount; i++){ byte id = stream.readByte(); float time = stream.readShort() / 2f; StatusEntry entry = Pooling.obtain(StatusEntry.class); @@ -132,7 +134,7 @@ public class StatusController implements Saveable{ } } - public static class StatusEntry { + public static class StatusEntry{ public StatusEffect effect; public float time; diff --git a/core/src/io/anuke/mindustry/entities/TileEntity.java b/core/src/io/anuke/mindustry/entities/TileEntity.java index 4c784bebd5..d4695604dc 100644 --- a/core/src/io/anuke/mindustry/entities/TileEntity.java +++ b/core/src/io/anuke/mindustry/entities/TileEntity.java @@ -35,213 +35,219 @@ import java.io.IOException; import static io.anuke.mindustry.Vars.tileGroup; import static io.anuke.mindustry.Vars.world; -public class TileEntity extends BaseEntity implements TargetTrait { - public static final float timeToSleep = 60f*4; //4 seconds to fall asleep - /**This value is only used for debugging.*/ - public static int sleepingEntities = 0; +public class TileEntity extends BaseEntity implements TargetTrait{ + public static final float timeToSleep = 60f * 4; //4 seconds to fall asleep + private static final ObjectSet tmpTiles = new ObjectSet<>(); + /** + * This value is only used for debugging. + */ + public static int sleepingEntities = 0; + public Tile tile; + public Timer timer; + public float health; - private static final ObjectSet tmpTiles = new ObjectSet<>(); + public PowerModule power; + public InventoryModule items; + public LiquidModule liquids; + public ConsumeModule cons; - public Tile tile; - public Timer timer; - public float health; + /**List of (cached) tiles with entities in proximity, used for outputting to*/ + private Array proximity = new Array<>(8); + private boolean dead = false; + private boolean sleeping; + private float sleepTime; - public PowerModule power; - public InventoryModule items; - public LiquidModule liquids; - public ConsumeModule cons; + @Remote(called = Loc.server, in = In.blocks) + public static void onTileDamage(Tile tile, float health){ + if(tile.entity != null){ + tile.entity.health = health; + } + } - //list of (cached) tiles with entities in proximity, used for outputting to - //TODO implement - private Array proximity = new Array<>(8); - private boolean dead = false; - private boolean sleeping; - private float sleepTime; - - /**Sets this tile entity data to this tile, and adds it if necessary.*/ - public TileEntity init(Tile tile, boolean added){ - this.tile = tile; - x = tile.drawx(); - y = tile.drawy(); + @Remote(called = Loc.server, in = In.blocks) + public static void onTileDestroyed(Tile tile){ + if(tile.entity == null) return; + tile.entity.onDeath(); + } - health = tile.block().health; - - timer = new Timer(tile.block().timers); - - if(added){ - add(); - } - - return this; - } + /**Sets this tile entity data to this tile, and adds it if necessary.*/ + public TileEntity init(Tile tile, boolean added){ + this.tile = tile; + x = tile.drawx(); + y = tile.drawy(); - /**Call when nothing is happening to the entity. - * This increments the internal sleep timer.*/ - public void sleep(){ - sleepTime += Timers.delta(); - if(!sleeping && sleepTime >= timeToSleep){ - remove(); - sleeping = true; - sleepingEntities ++; - } - } + health = tile.block().health; - /**Call when something just happened to the entity. - * If the entity was sleeping, this enables it. This also resets the sleep timer.*/ - public void wakeUp(){ - sleepTime = 0f; - if(sleeping){ - add(); - sleeping = false; - sleepingEntities --; - } - } + timer = new Timer(tile.block().timers); - public boolean isSleeping(){ - return sleeping; - } + if(added){ + add(); + } - public boolean isDead() { - return dead; - } + return this; + } - public void write(DataOutputStream stream) throws IOException{} - public void read(DataInputStream stream) throws IOException{} + /** + * Call when nothing is happening to the entity. + * This increments the internal sleep timer. + */ + public void sleep(){ + sleepTime += Timers.delta(); + if(!sleeping && sleepTime >= timeToSleep){ + remove(); + sleeping = true; + sleepingEntities++; + } + } - private void onDeath(){ - if(!dead) { - dead = true; - Block block = tile.block(); + /** + * Call when something just happened to the entity. + * If the entity was sleeping, this enables it. This also resets the sleep timer. + */ + public void wakeUp(){ + sleepTime = 0f; + if(sleeping){ + add(); + sleeping = false; + sleepingEntities--; + } + } - block.onDestroyed(tile); - world.removeBlock(tile); - block.afterDestroyed(tile, this); - remove(); - } - } + public boolean isSleeping(){ + return sleeping; + } - public boolean collide(Bullet other){ - return true; - } - - public void collision(Bullet other){ - tile.block().handleBulletHit(this, other); - } - - public void damage(float damage){ - if(dead) return; + public boolean isDead(){ + return dead; + } - CallBlocks.onTileDamage(tile, health - tile.block().handleDamage(tile, damage)); + public void write(DataOutputStream stream) throws IOException{ + } - if(health <= 0){ - CallBlocks.onTileDestroyed(tile); - } - } + public void read(DataInputStream stream) throws IOException{ + } - public Tile getTile(){ - return tile; - } + private void onDeath(){ + if(!dead){ + dead = true; + Block block = tile.block(); - public boolean consumed(Class type){ - return tile.block().consumes.get(type).valid(tile.block(), this); - } + block.onDestroyed(tile); + world.removeBlock(tile); + block.afterDestroyed(tile, this); + remove(); + } + } - public void removeFromProximity(){ - GridPoint2[] nearby = Edges.getEdges(tile.block().size); - for (GridPoint2 point : nearby) { - Tile other = world.tile(tile.x + point.x, tile.y + point.y); - //remove this tile from all nearby tile's proximities - if(other != null){ - other = other.target(); + public boolean collide(Bullet other){ + return true; + } + + public void collision(Bullet other){ + tile.block().handleBulletHit(this, other); + } + + public void damage(float damage){ + if(dead) return; + + CallBlocks.onTileDamage(tile, health - tile.block().handleDamage(tile, damage)); + + if(health <= 0){ + CallBlocks.onTileDestroyed(tile); + } + } + + public Tile getTile(){ + return tile; + } + + public boolean consumed(Class type){ + return tile.block().consumes.get(type).valid(tile.block(), this); + } + + public void removeFromProximity(){ + GridPoint2[] nearby = Edges.getEdges(tile.block().size); + for(GridPoint2 point : nearby){ + Tile other = world.tile(tile.x + point.x, tile.y + point.y); + //remove this tile from all nearby tile's proximities + if(other != null){ + other = other.target(); other.block().onProximityUpdate(other); } - if(other != null && other.entity != null){ - other.entity.proximity.removeValue(tile, true); - } - } - } + if(other != null && other.entity != null){ + other.entity.proximity.removeValue(tile, true); + } + } + } - public void updateProximity(){ - tmpTiles.clear(); - proximity.clear(); + public void updateProximity(){ + tmpTiles.clear(); + proximity.clear(); - GridPoint2[] nearby = Edges.getEdges(tile.block().size); - for (GridPoint2 point : nearby) { - Tile other = world.tile(tile.x + point.x, tile.y + point.y); + GridPoint2[] nearby = Edges.getEdges(tile.block().size); + for(GridPoint2 point : nearby){ + Tile other = world.tile(tile.x + point.x, tile.y + point.y); - if(other != null){ + if(other != null){ other.block().onProximityUpdate(other); - other = other.target(); + other = other.target(); } - if(other != null && other.entity != null){ - tmpTiles.add(other); + if(other != null && other.entity != null){ + tmpTiles.add(other); - //add this tile to proximity of nearby tiles - if(!other.entity.proximity.contains(tile, true)){ - other.entity.proximity.add(tile); - } - } - } + //add this tile to proximity of nearby tiles + if(!other.entity.proximity.contains(tile, true)){ + other.entity.proximity.add(tile); + } + } + } - //using a set to prevent duplicates - for(Tile tile : tmpTiles){ - proximity.add(tile); - } + //using a set to prevent duplicates + for(Tile tile : tmpTiles){ + proximity.add(tile); + } - tile.block().onProximityUpdate(tile); - } + tile.block().onProximityUpdate(tile); + } - public Array proximity(){ - return proximity; - } + public Array proximity(){ + return proximity; + } - @Override - public Team getTeam() { - return tile.getTeam(); - } + @Override + public Team getTeam(){ + return tile.getTeam(); + } - @Override - public Vector2 getVelocity() { - return Vector2.Zero; - } + @Override + public Vector2 getVelocity(){ + return Vector2.Zero; + } - @Override - public void update(){ - synchronized (Tile.tileSetLock) { - //TODO better smoke effect, this one is awful - if (health != 0 && health < tile.block().health && !(tile.block() instanceof Wall) && - Mathf.chance(0.009f * Timers.delta() * (1f - health / tile.block().health))) { + @Override + public void update(){ + synchronized(Tile.tileSetLock){ + //TODO better smoke effect, this one is awful + if(health != 0 && health < tile.block().health && !(tile.block() instanceof Wall) && + Mathf.chance(0.009f * Timers.delta() * (1f - health / tile.block().health))){ - Effects.effect(Fx.smoke, x + Mathf.range(4), y + Mathf.range(4)); - } + Effects.effect(Fx.smoke, x + Mathf.range(4), y + Mathf.range(4)); + } - if (health <= 0) { - onDeath(); - } + if(health <= 0){ + onDeath(); + } - tile.block().update(tile); - if(cons != null){ - cons.update(this); - } - } - } + tile.block().update(tile); + if(cons != null){ + cons.update(this); + } + } + } - @Override - public EntityGroup targetGroup() { - return tileGroup; - } - - @Remote(called = Loc.server, in = In.blocks) - public static void onTileDamage(Tile tile, float health){ - if(tile.entity != null){ - tile.entity.health = health; - } - } - - @Remote(called = Loc.server, in = In.blocks) - public static void onTileDestroyed(Tile tile){ - if(tile.entity == null) return; - tile.entity.onDeath(); - } + @Override + public EntityGroup targetGroup(){ + return tileGroup; + } } diff --git a/core/src/io/anuke/mindustry/entities/Unit.java b/core/src/io/anuke/mindustry/entities/Unit.java index 60beccd8e8..8ad6360042 100644 --- a/core/src/io/anuke/mindustry/entities/Unit.java +++ b/core/src/io/anuke/mindustry/entities/Unit.java @@ -31,13 +31,19 @@ import java.io.IOException; import static io.anuke.mindustry.Vars.state; import static io.anuke.mindustry.Vars.world; -public abstract class Unit extends DestructibleEntity implements SaveTrait, TargetTrait, SyncTrait, DrawTrait, TeamTrait, CarriableTrait, InventoryTrait { - /**total duration of hit flash effect*/ +public abstract class Unit extends DestructibleEntity implements SaveTrait, TargetTrait, SyncTrait, DrawTrait, TeamTrait, CarriableTrait, InventoryTrait{ + /** + * total duration of hit flash effect + */ public static final float hitDuration = 9f; - /**Percision divisor of velocity, used when writing. For example a value of '2' would mean the percision is 1/2 = 0.5-size chunks.*/ + /** + * Percision divisor of velocity, used when writing. For example a value of '2' would mean the percision is 1/2 = 0.5-size chunks. + */ public static final float velocityPercision = 8f; - /**Maximum absolute value of a velocity vector component.*/ - public static final float maxAbsVelocity = 127f/velocityPercision; + /** + * Maximum absolute value of a velocity vector component. + */ + public static final float maxAbsVelocity = 127f / velocityPercision; public static final float elevationScale = 4f; private static final Vector2 moveVector = new Vector2(); @@ -56,28 +62,28 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ protected float elevation; @Override - public UnitInventory getInventory() { + public UnitInventory getInventory(){ return inventory; } @Override - public float getRotation() { + public float getRotation(){ return rotation; } @Override - public void setRotation(float rotation) { + public void setRotation(float rotation){ this.rotation = rotation; } @Override - public void setCarrier(CarryTrait carrier) { - this.carrier = carrier; + public CarryTrait getCarrier(){ + return carrier; } @Override - public CarryTrait getCarrier() { - return carrier; + public void setCarrier(CarryTrait carrier){ + this.carrier = carrier; } @Override @@ -86,7 +92,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ } @Override - public void interpolate() { + public void interpolate(){ interpolator.update(); x = interpolator.pos.x; @@ -98,7 +104,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ } @Override - public Interpolator getInterpolator() { + public Interpolator getInterpolator(){ return interpolator; } @@ -115,31 +121,31 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ } @Override - public void onDeath() { + public void onDeath(){ inventory.clear(); drownTime = 0f; status.clear(); } @Override - public Vector2 getVelocity() { + public Vector2 getVelocity(){ return velocity; } @Override - public void writeSave(DataOutput stream) throws IOException { + public void writeSave(DataOutput stream) throws IOException{ writeSave(stream, false); } @Override - public void readSave(DataInput stream) throws IOException { + public void readSave(DataInput stream) throws IOException{ byte team = stream.readByte(); boolean dead = stream.readBoolean(); float x = stream.readFloat(); float y = stream.readFloat(); byte xv = stream.readByte(); byte yv = stream.readByte(); - float rotation = stream.readShort()/2f; + float rotation = stream.readShort() / 2f; int health = stream.readShort(); this.status.readSave(stream); @@ -153,21 +159,21 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ this.rotation = rotation; } - public void writeSave(DataOutput stream, boolean net) throws IOException { + public void writeSave(DataOutput stream, boolean net) throws IOException{ stream.writeByte(team.ordinal()); stream.writeBoolean(isDead()); stream.writeFloat(net ? interpolator.target.x : x); stream.writeFloat(net ? interpolator.target.y : y); - stream.writeByte((byte)(Mathf.clamp(velocity.x, -maxAbsVelocity, maxAbsVelocity) * velocityPercision)); - stream.writeByte((byte)(Mathf.clamp(velocity.y, -maxAbsVelocity, maxAbsVelocity) * velocityPercision)); - stream.writeShort((short)(rotation*2)); - stream.writeShort((short)health); + stream.writeByte((byte) (Mathf.clamp(velocity.x, -maxAbsVelocity, maxAbsVelocity) * velocityPercision)); + stream.writeByte((byte) (Mathf.clamp(velocity.y, -maxAbsVelocity, maxAbsVelocity) * velocityPercision)); + stream.writeShort((short) (rotation * 2)); + stream.writeShort((short) health); status.writeSave(stream); inventory.writeSave(stream); } public float calculateDamage(float amount){ - return amount * Mathf.clamp(1f-getArmor()/100f*status.getArmorMultiplier()); + return amount * Mathf.clamp(1f - getArmor() / 100f * status.getArmorMultiplier()); } public float getDamageMultipler(){ @@ -182,7 +188,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ if(state.teams.has(team)){ TeamData data = state.teams.get(team); - Tile tile = Geometry.findClosest(x, y, data.cores); + Tile tile = Geometry.findClosest(x, y, data.cores); if(tile == null){ return null; }else{ @@ -200,15 +206,18 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ public void avoidOthers(float avoidRange){ - EntityPhysics.getNearby(getGroup(), x, y, avoidRange*2f, t -> { - if(t == this || (t instanceof Unit && (((Unit) t).isDead() || (((Unit) t).isFlying() != isFlying()) || ((Unit) t).getCarrier() == this) || getCarrier() == t)) return; + EntityPhysics.getNearby(getGroup(), x, y, avoidRange * 2f, t -> { + if(t == this || (t instanceof Unit && (((Unit) t).isDead() || (((Unit) t).isFlying() != isFlying()) || ((Unit) t).getCarrier() == this) || getCarrier() == t)) + return; float dst = distanceTo(t); if(dst > avoidRange) return; velocity.add(moveVector.set(x, y).sub(t.getX(), t.getY()).setLength(1f * (1f - (dst / avoidRange)))); }); } - /**Updates velocity and status effects.*/ + /** + * Updates velocity and status effects. + */ public void updateVelocityStatus(float drag, float maxVelocity){ if(isCarried()){ //carried units do not take into account velocity normally set(carrier.getX(), carrier.getY()); @@ -223,7 +232,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ velocity.limit(maxVelocity).scl(status.getSpeedMultiplier()); - if(isFlying()) { + if(isFlying()){ x += velocity.x / getMass() * Timers.delta(); y += velocity.y / getMass() * Timers.delta(); @@ -245,7 +254,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ } } - if(onLiquid && velocity.len() > 0.4f && Timers.get(this, "flooreffect", 14 - (velocity.len() * floor.speedMultiplier)*2f)){ + if(onLiquid && velocity.len() > 0.4f && Timers.get(this, "flooreffect", 14 - (velocity.len() * floor.speedMultiplier) * 2f)){ Effects.effect(floor.walkEffect, floor.liquidColor, x, y); } @@ -256,7 +265,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ } if(onLiquid && floor.drownTime > 0){ - drownTime += Timers.delta() * 1f/floor.drownTime; + drownTime += Timers.delta() * 1f / floor.drownTime; if(Timers.get(this, "drowneffect", 15)){ Effects.effect(floor.drownUpdateEffect, floor.liquidColor, x, y); } @@ -276,7 +285,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ if(Math.abs(py - y) <= 0.0001f) velocity.y = 0f; } - velocity.scl(Mathf.clamp(1f-drag* floor.dragMultiplier* Timers.delta())); + velocity.scl(Mathf.clamp(1f - drag * floor.dragMultiplier * Timers.delta())); } public void applyEffect(StatusEffect effect, float intensity){ @@ -299,12 +308,17 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ } public float getAmmoFraction(){ - return inventory.totalAmmo() / (float)inventory.ammoCapacity(); + return inventory.totalAmmo() / (float) inventory.ammoCapacity(); } - public void drawUnder(){} - public void drawOver(){} - public void drawShadow(){} + public void drawUnder(){ + } + + public void drawOver(){ + } + + public void drawShadow(){ + } public void drawView(){ Fill.circle(x, y, getViewDistance()); @@ -319,12 +333,20 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ } public abstract TextureRegion getIconRegion(); + public abstract int getItemCapacity(); + public abstract int getAmmoCapacity(); + public abstract float getArmor(); + public abstract boolean acceptsAmmo(Item item); + public abstract void addAmmo(Item item); + public abstract float getMass(); + public abstract boolean isFlying(); + public abstract float getSize(); } diff --git a/core/src/io/anuke/mindustry/entities/UnitInventory.java b/core/src/io/anuke/mindustry/entities/UnitInventory.java index b72543bf74..53fd627f88 100644 --- a/core/src/io/anuke/mindustry/entities/UnitInventory.java +++ b/core/src/io/anuke/mindustry/entities/UnitInventory.java @@ -8,16 +8,17 @@ import io.anuke.mindustry.type.AmmoType; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemStack; -import java.io.*; +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; public class UnitInventory implements Saveable{ + private final Unit unit; private Array ammos = new Array<>(); private int totalAmmo; private ItemStack item = new ItemStack(Items.stone, 0); - private final Unit unit; - - public UnitInventory(Unit unit) { + public UnitInventory(Unit unit){ this.unit = unit; } @@ -26,24 +27,24 @@ public class UnitInventory implements Saveable{ } @Override - public void writeSave(DataOutput stream) throws IOException { + public void writeSave(DataOutput stream) throws IOException{ stream.writeShort(item.amount); stream.writeByte(item.item.id); stream.writeShort(totalAmmo); stream.writeByte(ammos.size); - for(int i = 0; i < ammos.size; i ++){ + for(int i = 0; i < ammos.size; i++){ stream.writeByte(ammos.get(i).type.id); stream.writeShort(ammos.get(i).amount); } } @Override - public void readSave(DataInput stream) throws IOException { + public void readSave(DataInput stream) throws IOException{ short iamount = stream.readShort(); byte iid = stream.readByte(); this.totalAmmo = stream.readShort(); byte ammoa = stream.readByte(); - for(int i = 0; i < ammoa; i ++){ + for(int i = 0; i < ammoa; i++){ byte aid = stream.readByte(); int am = stream.readShort(); ammos.add(new AmmoEntry(AmmoType.getByID(aid), am)); @@ -53,12 +54,14 @@ public class UnitInventory implements Saveable{ item.amount = iamount; } - /**Returns ammo range, or MAX_VALUE if this inventory has no ammo.*/ + /** + * Returns ammo range, or MAX_VALUE if this inventory has no ammo. + */ public float getAmmoRange(){ return hasAmmo() ? getAmmo().getRange() : Float.MAX_VALUE; } - public AmmoType getAmmo() { + public AmmoType getAmmo(){ return ammos.size == 0 ? null : ammos.peek().type; } @@ -69,9 +72,9 @@ public class UnitInventory implements Saveable{ public void useAmmo(){ if(unit.isInfiniteAmmo()) return; AmmoEntry entry = ammos.peek(); - entry.amount --; + entry.amount--; if(entry.amount == 0) ammos.pop(); - totalAmmo --; + totalAmmo--; } public int totalAmmo(){ @@ -91,19 +94,19 @@ public class UnitInventory implements Saveable{ totalAmmo += type.quantityMultiplier; //find ammo entry by type - for(int i = ammos.size - 1; i >= 0; i --){ + for(int i = ammos.size - 1; i >= 0; i--){ AmmoEntry entry = ammos.get(i); //if found, put it to the right if(entry.type == type){ entry.amount += type.quantityMultiplier; - ammos.swap(i, ammos.size-1); + ammos.swap(i, ammos.size - 1); return; } } //must not be found - AmmoEntry entry = new AmmoEntry(type, (int)type.quantityMultiplier); + AmmoEntry entry = new AmmoEntry(type, (int) type.quantityMultiplier); ammos.add(entry); } diff --git a/core/src/io/anuke/mindustry/entities/Units.java b/core/src/io/anuke/mindustry/entities/Units.java index 291b80ca8c..1b9fcb27f2 100644 --- a/core/src/io/anuke/mindustry/entities/Units.java +++ b/core/src/io/anuke/mindustry/entities/Units.java @@ -15,15 +15,19 @@ import io.anuke.ucore.function.Predicate; import static io.anuke.mindustry.Vars.*; -/**Utility class for unit and team interactions.*/ -public class Units { +/** + * Utility class for unit and team interactions. + */ +public class Units{ private static Rectangle rect = new Rectangle(); private static Rectangle hitrect = new Rectangle(); private static Unit result; private static float cdist; private static boolean boolResult; - /**Validates a target. + /** + * Validates a target. + * * @param target The target to validate * @param team The team of the thing doing tha targeting * @param x The X position of the thing doign the targeting @@ -31,22 +35,28 @@ public class Units { * @param range The maximum distance from the target X/Y the targeter can be for it to be valid * @return whether the target is invalid */ - public static boolean invalidateTarget(TargetTrait target, Team team, float x, float y, float range) { + public static boolean invalidateTarget(TargetTrait target, Team team, float x, float y, float range){ return target == null || (range != Float.MAX_VALUE && target.distanceTo(x, y) > range) || target.getTeam() == team || !target.isValid(); } - /**See {@link #invalidateTarget(TargetTrait, Team, float, float, float)}*/ + /** + * See {@link #invalidateTarget(TargetTrait, Team, float, float, float)} + */ public static boolean invalidateTarget(TargetTrait target, Team team, float x, float y){ return invalidateTarget(target, team, x, y, Float.MAX_VALUE); } - /**See {@link #invalidateTarget(TargetTrait, Team, float, float, float)}*/ + /** + * See {@link #invalidateTarget(TargetTrait, Team, float, float, float)} + */ public static boolean invalidateTarget(TargetTrait target, Unit targeter){ return invalidateTarget(target, targeter.team, targeter.x, targeter.y, targeter.inventory.getAmmoRange()); } - /**Returns whether there are any entities on this tile.*/ + /** + * Returns whether there are any entities on this tile. + */ public static boolean anyEntities(Tile tile){ Block type = tile.block(); rect.setSize(type.size * tilesize, type.size * tilesize); @@ -55,11 +65,11 @@ public class Units { boolResult = false; Units.getNearby(rect, unit -> { - if (boolResult) return; - if (!unit.isFlying()) { + if(boolResult) return; + if(!unit.isFlying()){ unit.getHitbox(hitrect); - if (hitrect.overlaps(rect)) { + if(hitrect.overlaps(rect)){ boolResult = true; } } @@ -68,7 +78,9 @@ public class Units { return boolResult; } - /**Returns whether there are any entities on this tile, with the hitbox expanded.*/ + /** + * Returns whether there are any entities on this tile, with the hitbox expanded. + */ public static boolean anyEntities(Tile tile, float expansion, Predicate pred){ Block type = tile.block(); rect.setSize(type.size * tilesize + expansion, type.size * tilesize + expansion); @@ -81,7 +93,7 @@ public class Units { if(!unit.isFlying()){ unit.getHitbox(hitrect); - if(hitrect.overlaps(rect)) { + if(hitrect.overlaps(rect)){ value[0] = true; } } @@ -90,7 +102,9 @@ public class Units { return value[0]; } - /**Returns the neareset ally tile in a range.*/ + /** + * Returns the neareset ally tile in a range. + */ public static TileEntity findAllyTile(Team team, float x, float y, float range, Predicate pred){ for(Team enemy : state.teams.alliesOf(team)){ TileEntity entity = world.indexer().findTile(enemy, x, y, range, pred); @@ -101,7 +115,9 @@ public class Units { return null; } - /**Returns the neareset enemy tile in a range.*/ + /** + * Returns the neareset enemy tile in a range. + */ public static TileEntity findEnemyTile(Team team, float x, float y, float range, Predicate pred){ for(Team enemy : state.teams.enemiesOf(team)){ TileEntity entity = world.indexer().findTile(enemy, x, y, range, pred); @@ -112,7 +128,9 @@ public class Units { return null; } - /**Iterates over all units on all teams, including players.*/ + /** + * Iterates over all units on all teams, including players. + */ public static void allUnits(Consumer cons){ //check all unit groups first for(EntityGroup group : unitGroups){ @@ -129,7 +147,9 @@ public class Units { } } - /**Returns the closest target enemy. First, units are checked, then tile entities.*/ + /** + * Returns the closest target enemy. First, units are checked, then tile entities. + */ public static TargetTrait getClosestTarget(Team team, float x, float y, float range){ Unit unit = getClosestEnemy(team, x, y, range, u -> true); if(unit != null){ @@ -139,20 +159,22 @@ public class Units { } } - /**Returns the closest enemy of this team. Filter by predicate.*/ + /** + * Returns the closest enemy of this team. Filter by predicate. + */ public static Unit getClosestEnemy(Team team, float x, float y, float range, Predicate predicate){ result = null; cdist = 0f; - rect.setSize(range*2f).setCenter(x, y); + rect.setSize(range * 2f).setCenter(x, y); getNearbyEnemies(team, rect, e -> { - if (e.isDead() || !predicate.test(e)) + if(e.isDead() || !predicate.test(e)) return; float dist = Vector2.dst(e.x, e.y, x, y); - if (dist < range) { - if (result == null || dist < cdist) { + if(dist < range){ + if(result == null || dist < cdist){ result = e; cdist = dist; } @@ -162,20 +184,22 @@ public class Units { return result; } - /**Returns the closest ally of this team. Filter by predicate.*/ + /** + * Returns the closest ally of this team. Filter by predicate. + */ public static Unit getClosest(Team team, float x, float y, float range, Predicate predicate){ result = null; cdist = 0f; - rect.setSize(range*2f).setCenter(x, y); + rect.setSize(range * 2f).setCenter(x, y); getNearby(team, rect, e -> { - if (!predicate.test(e)) + if(!predicate.test(e)) return; float dist = Vector2.dst(e.x, e.y, x, y); - if (dist < range) { - if (result == null || dist < cdist) { + if(dist < range){ + if(result == null || dist < cdist){ result = e; cdist = dist; } @@ -185,28 +209,32 @@ public class Units { return result; } - /**Iterates over all units in a rectangle.*/ + /** + * Iterates over all units in a rectangle. + */ public static void getNearby(Team team, Rectangle rect, Consumer cons){ EntityGroup group = unitGroups[team.ordinal()]; if(!group.isEmpty()){ - EntityPhysics.getNearby(group, rect, entity -> cons.accept((Unit)entity)); + EntityPhysics.getNearby(group, rect, entity -> cons.accept((Unit) entity)); } //now check all players EntityPhysics.getNearby(playerGroup, rect, player -> { - if(((Unit)player).team == team) cons.accept((Unit)player); + if(((Unit) player).team == team) cons.accept((Unit) player); }); } - /**Iterates over all units in a circle around this position.*/ + /** + * Iterates over all units in a circle around this position. + */ public static void getNearby(Team team, float x, float y, float radius, Consumer cons){ rect.setSize(radius * 2).setCenter(x, y); EntityGroup group = unitGroups[team.ordinal()]; if(!group.isEmpty()){ EntityPhysics.getNearby(group, rect, entity -> { - if(entity.distanceTo(x, y) <= radius) { + if(entity.distanceTo(x, y) <= radius){ cons.accept((Unit) entity); } }); @@ -214,46 +242,52 @@ public class Units { //now check all players EntityPhysics.getNearby(playerGroup, rect, player -> { - if(((Unit)player).team == team && player.distanceTo(x, y) <= radius){ - cons.accept((Unit)player); + if(((Unit) player).team == team && player.distanceTo(x, y) <= radius){ + cons.accept((Unit) player); } }); } - /**Iterates over all units in a rectangle.*/ + /** + * Iterates over all units in a rectangle. + */ public static void getNearby(Rectangle rect, Consumer cons){ for(Team team : Team.all){ EntityGroup group = unitGroups[team.ordinal()]; if(!group.isEmpty()){ - EntityPhysics.getNearby(group, rect, entity -> cons.accept((Unit)entity)); + EntityPhysics.getNearby(group, rect, entity -> cons.accept((Unit) entity)); } } //now check all enemy players - EntityPhysics.getNearby(playerGroup, rect, player -> cons.accept((Unit)player)); + EntityPhysics.getNearby(playerGroup, rect, player -> cons.accept((Unit) player)); } - /**Iterates over all units that are enemies of this team.*/ + /** + * Iterates over all units that are enemies of this team. + */ public static void getNearbyEnemies(Team team, Rectangle rect, Consumer cons){ ObjectSet targets = state.teams.enemiesOf(team); for(Team other : targets){ EntityGroup group = unitGroups[other.ordinal()]; if(!group.isEmpty()){ - EntityPhysics.getNearby(group, rect, entity -> cons.accept((Unit)entity)); + EntityPhysics.getNearby(group, rect, entity -> cons.accept((Unit) entity)); } } //now check all enemy players EntityPhysics.getNearby(playerGroup, rect, player -> { - if(targets.contains(((Player)player).team)){ - cons.accept((Unit)player); + if(targets.contains(((Player) player).team)){ + cons.accept((Unit) player); } }); } - /**Iterates over all units.*/ + /** + * Iterates over all units. + */ public static void getAllUnits(Consumer cons){ for(Team team : Team.all){ diff --git a/core/src/io/anuke/mindustry/entities/bullet/ArtilleryBulletType.java b/core/src/io/anuke/mindustry/entities/bullet/ArtilleryBulletType.java index f298ab6ab4..52a1594c96 100644 --- a/core/src/io/anuke/mindustry/entities/bullet/ArtilleryBulletType.java +++ b/core/src/io/anuke/mindustry/entities/bullet/ArtilleryBulletType.java @@ -6,10 +6,10 @@ import io.anuke.ucore.core.Effects.Effect; import io.anuke.ucore.graphics.Draw; //TODO scale velocity depending on fslope() -public class ArtilleryBulletType extends BasicBulletType { +public class ArtilleryBulletType extends BasicBulletType{ protected Effect trailEffect = BulletFx.artilleryTrail; - public ArtilleryBulletType(float speed, float damage, String bulletSprite) { + public ArtilleryBulletType(float speed, float damage, String bulletSprite){ super(speed, damage, bulletSprite); collidesTiles = false; collides = false; @@ -17,18 +17,18 @@ public class ArtilleryBulletType extends BasicBulletType { } @Override - public void update(Bullet b) { + public void update(Bullet b){ super.update(b); - if(b.timer.get(0, 3 + b.fslope()*2f)){ + if(b.timer.get(0, 3 + b.fslope() * 2f)){ Effects.effect(trailEffect, backColor, b.x, b.y, b.fslope() * 4f); } } @Override - public void draw(Bullet b) { + public void draw(Bullet b){ float baseScale = 0.7f; - float scale = (baseScale + b.fslope()*(1f-baseScale)); + float scale = (baseScale + b.fslope() * (1f - baseScale)); float height = bulletHeight * ((1f - bulletShrink) + bulletShrink * b.fout()); diff --git a/core/src/io/anuke/mindustry/entities/bullet/BasicBulletType.java b/core/src/io/anuke/mindustry/entities/bullet/BasicBulletType.java index 3822ea7f52..d5d1455eb0 100644 --- a/core/src/io/anuke/mindustry/entities/bullet/BasicBulletType.java +++ b/core/src/io/anuke/mindustry/entities/bullet/BasicBulletType.java @@ -12,8 +12,10 @@ import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.util.Angles; import io.anuke.ucore.util.Mathf; -/**A BulletType for most ammo-based bullets shot from turrets and units.*/ -public class BasicBulletType extends BulletType { +/** + * A BulletType for most ammo-based bullets shot from turrets and units. + */ +public class BasicBulletType extends BulletType{ public Color backColor = Palette.bulletYellowBack, frontColor = Palette.bulletYellow; public float bulletWidth = 5f, bulletHeight = 7f; public float bulletShrink = 0.5f; @@ -23,7 +25,9 @@ public class BasicBulletType extends BulletType { public float fragVelocityMin = 0.2f, fragVelocityMax = 1f; public BulletType fragBullet = null; - /**Use a negative value to disable splash damage.*/ + /** + * Use a negative value to disable splash damage. + */ public float splashDamageRadius = -1f; public float splashDamage = 6f; @@ -39,19 +43,19 @@ public class BasicBulletType extends BulletType { public float hitShake = 0f; - public BasicBulletType(float speed, float damage, String bulletSprite) { + public BasicBulletType(float speed, float damage, String bulletSprite){ super(speed, damage); this.bulletSprite = bulletSprite; } @Override - public void load() { + public void load(){ backRegion = Draw.region(bulletSprite + "-back"); frontRegion = Draw.region(bulletSprite); } @Override - public void draw(Bullet b) { + public void draw(Bullet b){ float height = bulletHeight * ((1f - bulletShrink) + bulletShrink * b.fout()); Draw.color(backColor); @@ -62,7 +66,7 @@ public class BasicBulletType extends BulletType { } @Override - public void update(Bullet b) { + public void update(Bullet b){ super.update(b); if(homingPower > 0.0001f){ @@ -74,20 +78,20 @@ public class BasicBulletType extends BulletType { } @Override - public void hit(Bullet b, float x, float y) { + public void hit(Bullet b, float x, float y){ super.hit(b, x, y); Effects.shake(hitShake, hitShake, b); - if(fragBullet != null) { - for (int i = 0; i < fragBullets; i++) { + if(fragBullet != null){ + for(int i = 0; i < fragBullets; i++){ float len = Mathf.random(1f, 7f); float a = Mathf.random(360f); Bullet.create(fragBullet, b, x + Angles.trnsx(a, len), y + Angles.trnsy(a, len), a, Mathf.random(fragVelocityMin, fragVelocityMax)); } } - if(Mathf.chance(incendChance)) { + if(Mathf.chance(incendChance)){ Damage.createIncend(x, y, incendSpread, incendAmount); } @@ -97,7 +101,7 @@ public class BasicBulletType extends BulletType { } @Override - public void despawned(Bullet b) { + public void despawned(Bullet b){ if(fragBullet != null || splashDamageRadius > 0){ hit(b); } diff --git a/core/src/io/anuke/mindustry/entities/bullet/BombBulletType.java b/core/src/io/anuke/mindustry/entities/bullet/BombBulletType.java index 5682477e49..cdca80de79 100644 --- a/core/src/io/anuke/mindustry/entities/bullet/BombBulletType.java +++ b/core/src/io/anuke/mindustry/entities/bullet/BombBulletType.java @@ -1,8 +1,8 @@ package io.anuke.mindustry.entities.bullet; -public class BombBulletType extends BasicBulletType { +public class BombBulletType extends BasicBulletType{ - public BombBulletType(float damage, float radius, String sprite) { + public BombBulletType(float damage, float radius, String sprite){ super(0.7f, 0, sprite); splashDamageRadius = radius; splashDamage = damage; diff --git a/core/src/io/anuke/mindustry/entities/bullet/Bullet.java b/core/src/io/anuke/mindustry/entities/bullet/Bullet.java index 7f218d4524..0e9322928f 100644 --- a/core/src/io/anuke/mindustry/entities/bullet/Bullet.java +++ b/core/src/io/anuke/mindustry/entities/bullet/Bullet.java @@ -27,198 +27,199 @@ import static io.anuke.mindustry.Vars.bulletGroup; import static io.anuke.mindustry.Vars.world; public class Bullet extends BulletEntity implements TeamTrait, SyncTrait{ - private static Vector2 vector = new Vector2(); + private static Vector2 vector = new Vector2(); + public Timer timer = new Timer(3); + private Team team; + private Object data; + private boolean supressCollision; - private Team team; - private Object data; - private boolean supressCollision; + /** + * Internal use only! + */ + public Bullet(){ + } - public Timer timer = new Timer(3); + public static void create(BulletType type, TeamTrait owner, float x, float y, float angle){ + create(type, owner, owner.getTeam(), x, y, angle); + } - public static void create (BulletType type, TeamTrait owner, float x, float y, float angle){ - create(type, owner, owner.getTeam(), x, y, angle); - } + public static void create(BulletType type, Entity owner, Team team, float x, float y, float angle){ + create(type, owner, team, x, y, angle, 1f); + } - public static void create (BulletType type, Entity owner, Team team, float x, float y, float angle){ - create(type, owner, team, x, y, angle, 1f); - } + public static void create(BulletType type, Entity owner, Team team, float x, float y, float angle, float velocityScl){ + create(type, owner, team, x, y, angle, velocityScl, null); + } - public static void create (BulletType type, Entity owner, Team team, float x, float y, float angle, float velocityScl){ - create(type, owner, team, x, y, angle, velocityScl, null); - } + public static void create(BulletType type, Entity owner, Team team, float x, float y, float angle, float velocityScl, Object data){ + Bullet bullet = Pooling.obtain(Bullet.class); + bullet.type = type; + bullet.owner = owner; + bullet.data = data; - public static void create (BulletType type, Entity owner, Team team, float x, float y, float angle, float velocityScl, Object data){ - Bullet bullet = Pooling.obtain(Bullet.class); - bullet.type = type; - bullet.owner = owner; - bullet.data = data; + bullet.velocity.set(0, type.speed).setAngle(angle).scl(velocityScl); + if(type.keepVelocity){ + bullet.velocity.add(owner instanceof VelocityTrait ? ((VelocityTrait) owner).getVelocity() : Vector2.Zero); + } + bullet.hitbox.setSize(type.hitsize); - bullet.velocity.set(0, type.speed).setAngle(angle).scl(velocityScl); - if(type.keepVelocity){ - bullet.velocity.add(owner instanceof VelocityTrait ? ((VelocityTrait)owner).getVelocity() : Vector2.Zero); - } - bullet.hitbox.setSize(type.hitsize); + bullet.team = team; + bullet.type = type; - bullet.team = team; - bullet.type = type; + //translate bullets backwards, purely for visual reasons + float backDelta = Timers.delta(); - //translate bullets backwards, purely for visual reasons - float backDelta = Timers.delta(); + bullet.lastPosition().set(x - bullet.velocity.x * backDelta, y - bullet.velocity.y * backDelta, bullet.angle()); + bullet.setLastUpdated(TimeUtils.millis()); + bullet.setUpdateSpacing((long) ((Timers.delta() / 60f) * 1000)); + bullet.set(x - bullet.velocity.x * backDelta, y - bullet.velocity.y * backDelta); - bullet.lastPosition().set(x-bullet.velocity.x * backDelta, y-bullet.velocity.y * backDelta, bullet.angle()); - bullet.setLastUpdated(TimeUtils.millis()); - bullet.setUpdateSpacing((long)((Timers.delta() / 60f) * 1000)); - bullet.set(x-bullet.velocity.x * backDelta, y-bullet.velocity.y * backDelta); + bullet.add(); + } - bullet.add(); - } + public static void create(BulletType type, Bullet parent, float x, float y, float angle){ + create(type, parent.owner, parent.team, x, y, angle); + } - public static void create(BulletType type, Bullet parent, float x, float y, float angle){ - create(type, parent.owner, parent.team, x, y, angle); - } + public static void create(BulletType type, Bullet parent, float x, float y, float angle, float velocityScl){ + create(type, parent.owner, parent.team, x, y, angle, velocityScl); + } - public static void create(BulletType type, Bullet parent, float x, float y, float angle, float velocityScl){ - create(type, parent.owner, parent.team, x, y, angle, velocityScl); - } + @Remote(called = Loc.server, in = In.entities) + public static void createBullet(BulletType type, float x, float y, float angle){ + create(type, null, Team.none, x, y, angle); + } - @Remote(called = Loc.server, in = In.entities) - public static void createBullet(BulletType type, float x, float y, float angle){ - create(type, null, Team.none, x, y, angle); - } + public boolean collidesTiles(){ + return type.collidesTiles; + } - /**Internal use only!*/ - public Bullet(){} + public void supressCollision(){ + supressCollision = true; + } - public boolean collidesTiles(){ - return type.collidesTiles; - } + public void resetOwner(Entity entity, Team team){ + this.owner = entity; + this.team = team; + } - public void supressCollision(){ - supressCollision = true; - } + public void scaleTime(float add){ + time += add; + } - public void resetOwner(Entity entity, Team team){ - this.owner = entity; - this.team = team; - } + public Object getData(){ + return data; + } - public void scaleTime(float add){ - time += add; - } + @Override + public float getDamage(){ + if(owner instanceof Unit){ + return super.getDamage() * ((Unit) owner).getDamageMultipler(); + } - public Object getData() { - return data; - } + return super.getDamage(); + } - @Override - public float getDamage(){ - if(owner instanceof Unit){ - return super.getDamage() * ((Unit) owner).getDamageMultipler(); - } + @Override + public boolean isSyncing(){ + return type.syncable; + } - return super.getDamage(); - } + @Override + public void write(DataOutput data) throws IOException{ + data.writeFloat(x); + data.writeFloat(y); + data.writeFloat(velocity.x); + data.writeFloat(velocity.y); + data.writeByte(team.ordinal()); + data.writeByte(type.id); + } - @Override - public boolean isSyncing(){ - return type.syncable; - } + @Override + public void read(DataInput data, long time) throws IOException{ + x = data.readFloat(); + y = data.readFloat(); + velocity.x = data.readFloat(); + velocity.y = data.readFloat(); + team = Team.all[data.readByte()]; + type = BulletType.getByID(data.readByte()); + } - @Override - public void write(DataOutput data) throws IOException { - data.writeFloat(x); - data.writeFloat(y); - data.writeFloat(velocity.x); - data.writeFloat(velocity.y); - data.writeByte(team.ordinal()); - data.writeByte(type.id); - } + @Override + public Team getTeam(){ + return team; + } - @Override - public void read(DataInput data, long time) throws IOException{ - x = data.readFloat(); - y = data.readFloat(); - velocity.x = data.readFloat(); - velocity.y = data.readFloat(); - team = Team.all[data.readByte()]; - type = BulletType.getByID(data.readByte()); - } + @Override + public void draw(){ + type.draw(this); + } - @Override - public Team getTeam() { - return team; - } + @Override + public float drawSize(){ + return 8; + } - @Override - public void draw(){ - type.draw(this); - } + @Override + public boolean collides(SolidTrait other){ + return type.collides && super.collides(other); + } - @Override - public float drawSize(){ - return 8; - } + @Override + public void collision(SolidTrait other, float x, float y){ + super.collision(other, x, y); - @Override - public boolean collides(SolidTrait other){ - return type.collides && super.collides(other); - } + if(other instanceof Unit){ + Unit unit = (Unit) other; + unit.getVelocity().add(vector.set(other.getX(), other.getY()).sub(x, y).setLength(type.knockback / unit.getMass())); + unit.applyEffect(type.status, type.statusIntensity); + } + } - @Override - public void collision(SolidTrait other, float x, float y){ - super.collision(other, x, y); + @Override + public void update(){ + super.update(); - if(other instanceof Unit){ - Unit unit = (Unit)other; - unit.getVelocity().add(vector.set(other.getX(), other.getY()).sub(x, y).setLength(type.knockback / unit.getMass())); - unit.applyEffect(type.status, type.statusIntensity); - } - } + if(type.hitTiles && collidesTiles() && !supressCollision){ + world.raycastEach(world.toTile(lastPosition().x), world.toTile(lastPosition().y), world.toTile(x), world.toTile(y), (x, y) -> { - @Override - public void update(){ - super.update(); + Tile tile = world.tile(x, y); + if(tile == null) return false; + tile = tile.target(); - if (type.hitTiles && collidesTiles() && !supressCollision) { - world.raycastEach(world.toTile(lastPosition().x), world.toTile(lastPosition().y), world.toTile(x), world.toTile(y), (x, y) -> { + if(tile.entity != null && tile.entity.collide(this) && !tile.entity.isDead() && tile.entity.tile.getTeam() != team){ + tile.entity.collision(this); - Tile tile = world.tile(x, y); - if (tile == null) return false; - tile = tile.target(); + if(!supressCollision){ + type.hit(this); + remove(); + } - if (tile.entity != null && tile.entity.collide(this) && !tile.entity.isDead() && tile.entity.tile.getTeam() != team) { - tile.entity.collision(this); + return true; + } - if(!supressCollision){ - type.hit(this); - remove(); - } + return false; + }); + } - return true; - } + supressCollision = false; + } - return false; - }); - } + @Override + public void reset(){ + super.reset(); + timer.clear(); + team = null; + data = null; + } - supressCollision = false; - } + @Override + public void removed(){ + Pooling.free(this); + } - @Override - public void reset() { - super.reset(); - timer.clear(); - team = null; - data = null; - } - - @Override - public void removed() { - Pooling.free(this); - } - - @Override - public EntityGroup targetGroup() { - return bulletGroup; - } + @Override + public EntityGroup targetGroup(){ + return bulletGroup; + } } diff --git a/core/src/io/anuke/mindustry/entities/bullet/BulletType.java b/core/src/io/anuke/mindustry/entities/bullet/BulletType.java index e402ab00a1..d4d750035d 100644 --- a/core/src/io/anuke/mindustry/entities/bullet/BulletType.java +++ b/core/src/io/anuke/mindustry/entities/bullet/BulletType.java @@ -9,65 +9,83 @@ import io.anuke.ucore.core.Effects; import io.anuke.ucore.entities.impl.BaseBulletType; public abstract class BulletType extends BaseBulletType implements Content{ - private static int lastid = 0; - private static Array types = new Array<>(); + private static int lastid = 0; + private static Array types = new Array<>(); - public final int id; - /**Knockback in velocity.*/ - public float knockback; - /**Whether this bullet hits tiles.*/ - public boolean hitTiles = true; - /**Status effect applied on hit.*/ - public StatusEffect status = StatusEffects.none; - /**Intensity of applied status effect in terms of duration.*/ - public float statusIntensity = 0.5f; - /**What fraction of armor is pierced, 0-1*/ - public float armorPierce = 0f; - /**Whether to sync this bullet to clients.*/ - public boolean syncable; - /**Whether this bullet type collides with tiles.*/ - public boolean collidesTiles = true; - /**Whether this bullet types collides with anything at all.*/ - public boolean collides = true; - /**Whether velocity is inherited from the shooter.*/ - public boolean keepVelocity = true; + public final int id; + /** + * Knockback in velocity. + */ + public float knockback; + /** + * Whether this bullet hits tiles. + */ + public boolean hitTiles = true; + /** + * Status effect applied on hit. + */ + public StatusEffect status = StatusEffects.none; + /** + * Intensity of applied status effect in terms of duration. + */ + public float statusIntensity = 0.5f; + /** + * What fraction of armor is pierced, 0-1 + */ + public float armorPierce = 0f; + /** + * Whether to sync this bullet to clients. + */ + public boolean syncable; + /** + * Whether this bullet type collides with tiles. + */ + public boolean collidesTiles = true; + /** + * Whether this bullet types collides with anything at all. + */ + public boolean collides = true; + /** + * Whether velocity is inherited from the shooter. + */ + public boolean keepVelocity = true; - public BulletType(float speed, float damage){ - this.id = lastid ++; - this.speed = speed; - this.damage = damage; - lifetime = 40f; - hiteffect = BulletFx.hitBulletSmall; - despawneffect = BulletFx.despawn; + public BulletType(float speed, float damage){ + this.id = lastid++; + this.speed = speed; + this.damage = damage; + lifetime = 40f; + hiteffect = BulletFx.hitBulletSmall; + despawneffect = BulletFx.despawn; - types.add(this); - } - - @Override - public void hit(Bullet b, float hitx, float hity){ - Effects.effect(hiteffect, hitx, hity, b.angle()); - } + types.add(this); + } - @Override - public void despawned(Bullet b){ - Effects.effect(despawneffect, b.x, b.y, b.angle()); - } + public static BulletType getByID(int id){ + return types.get(id); + } - @Override - public String getContentTypeName() { - return "bullettype"; - } + public static Array all(){ + return types; + } - @Override - public Array getAll() { - return types; - } + @Override + public void hit(Bullet b, float hitx, float hity){ + Effects.effect(hiteffect, hitx, hity, b.angle()); + } - public static BulletType getByID(int id){ - return types.get(id); - } + @Override + public void despawned(Bullet b){ + Effects.effect(despawneffect, b.x, b.y, b.angle()); + } - public static Array all(){ - return types; - } + @Override + public String getContentTypeName(){ + return "bullettype"; + } + + @Override + public Array getAll(){ + return types; + } } diff --git a/core/src/io/anuke/mindustry/entities/bullet/LiquidBulletType.java b/core/src/io/anuke/mindustry/entities/bullet/LiquidBulletType.java index df36debba3..3b034962d8 100644 --- a/core/src/io/anuke/mindustry/entities/bullet/LiquidBulletType.java +++ b/core/src/io/anuke/mindustry/entities/bullet/LiquidBulletType.java @@ -16,10 +16,10 @@ import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.tilesize; import static io.anuke.mindustry.Vars.world; -public class LiquidBulletType extends BulletType { +public class LiquidBulletType extends BulletType{ Liquid liquid; - public LiquidBulletType(Liquid liquid) { + public LiquidBulletType(Liquid liquid){ super(2.5f, 0); this.liquid = liquid; @@ -31,14 +31,14 @@ public class LiquidBulletType extends BulletType { } @Override - public void draw(Bullet b) { + public void draw(Bullet b){ Draw.color(liquid.color, Color.WHITE, b.fout() / 100f + Mathf.randomSeedRange(b.id, 0.1f)); - Fill.circle(b.x, b.y, 0.5f + b.fout()*2.5f); + Fill.circle(b.x, b.y, 0.5f + b.fout() * 2.5f); } @Override - public void hit(Bullet b, float hitx, float hity) { + public void hit(Bullet b, float hitx, float hity){ Effects.effect(hiteffect, liquid.color, hitx, hity); Puddle.deposit(world.tileWorld(hitx, hity), liquid, 5f); @@ -46,7 +46,7 @@ public class LiquidBulletType extends BulletType { float intensity = 400f; Fire.extinguish(world.tileWorld(hitx, hity), intensity); for(GridPoint2 p : Geometry.d4){ - Fire.extinguish(world.tileWorld(hitx + p.x*tilesize, hity + p.y*tilesize), intensity); + Fire.extinguish(world.tileWorld(hitx + p.x * tilesize, hity + p.y * tilesize), intensity); } } } diff --git a/core/src/io/anuke/mindustry/entities/bullet/MissileBulletType.java b/core/src/io/anuke/mindustry/entities/bullet/MissileBulletType.java index 20747c7fa4..6179d2e6a3 100644 --- a/core/src/io/anuke/mindustry/entities/bullet/MissileBulletType.java +++ b/core/src/io/anuke/mindustry/entities/bullet/MissileBulletType.java @@ -4,9 +4,9 @@ import io.anuke.mindustry.content.fx.BulletFx; import io.anuke.mindustry.graphics.Palette; import io.anuke.ucore.core.Effects; -public class MissileBulletType extends BasicBulletType { +public class MissileBulletType extends BasicBulletType{ - public MissileBulletType(float speed, float damage, String bulletSprite) { + public MissileBulletType(float speed, float damage, String bulletSprite){ super(speed, damage, bulletSprite); backColor = Palette.missileYellowBack; frontColor = Palette.missileYellow; @@ -14,7 +14,7 @@ public class MissileBulletType extends BasicBulletType { } @Override - public void update(Bullet b) { + public void update(Bullet b){ super.update(b); if(b.timer.get(0, 4f)){ diff --git a/core/src/io/anuke/mindustry/entities/effect/Decal.java b/core/src/io/anuke/mindustry/entities/effect/Decal.java index 762cc480e6..64c9facba6 100644 --- a/core/src/io/anuke/mindustry/entities/effect/Decal.java +++ b/core/src/io/anuke/mindustry/entities/effect/Decal.java @@ -10,24 +10,26 @@ import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.groundEffectGroup; -/**Class for creating block rubble on the ground.*/ -public abstract class Decal extends TimedEntity implements BelowLiquidTrait, DrawTrait { +/** + * Class for creating block rubble on the ground. + */ +public abstract class Decal extends TimedEntity implements BelowLiquidTrait, DrawTrait{ private static final Color color = Color.valueOf("52504e"); @Override - public float lifetime() { + public float lifetime(){ return 8200f; } @Override public void draw(){ - Draw.color(color.r, color.g, color.b, 1f-Mathf.curve(fin(), 0.98f)); + Draw.color(color.r, color.g, color.b, 1f - Mathf.curve(fin(), 0.98f)); drawDecal(); Draw.color(); } @Override - public EntityGroup targetGroup() { + public EntityGroup targetGroup(){ return groundEffectGroup; } diff --git a/core/src/io/anuke/mindustry/entities/effect/Fire.java b/core/src/io/anuke/mindustry/entities/effect/Fire.java index bd2c0f0333..e933e5dfbf 100644 --- a/core/src/io/anuke/mindustry/entities/effect/Fire.java +++ b/core/src/io/anuke/mindustry/entities/effect/Fire.java @@ -31,7 +31,7 @@ import java.io.IOException; import static io.anuke.mindustry.Vars.*; -public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable { +public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable{ private static final IntMap map = new IntMap<>(); private static final float baseLifetime = 1000f; @@ -41,7 +41,15 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable private float baseFlammability = -1, puddleFlammability; private float lifetime; - /**Start a fire on the tile. If there already is a file there, refreshes its lifetime.*/ + /** + * Deserialization use only! + */ + public Fire(){ + } + + /** + * Start a fire on the tile. If there already is a file there, refreshes its lifetime. + */ public static void create(Tile tile){ if(Net.client() || tile == null) return; //not clientside. @@ -60,24 +68,28 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable } } - /**Attempts to extinguish a fire by shortening its life. If there is no fire here, does nothing.*/ - public static void extinguish(Tile tile, float intensity) { - if (tile != null && map.containsKey(tile.packedPosition())) { + /** + * Attempts to extinguish a fire by shortening its life. If there is no fire here, does nothing. + */ + public static void extinguish(Tile tile, float intensity){ + if(tile != null && map.containsKey(tile.packedPosition())){ map.get(tile.packedPosition()).time += intensity * Timers.delta(); } } - /**Deserialization use only!*/ - public Fire(){} + @Remote(called = Loc.server, in = In.entities) + public static void onFireRemoved(int fireid){ + fireGroup.removeByID(fireid); + } @Override - public float lifetime() { + public float lifetime(){ return lifetime; } @Override - public void update() { - if(Mathf.chance(0.1 * Timers.delta())) { + public void update(){ + if(Mathf.chance(0.1 * Timers.delta())){ Effects.effect(EnvironmentFx.fire, x + Mathf.range(4f), y + Mathf.range(4f)); } @@ -103,19 +115,19 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable float flammability = baseFlammability + puddleFlammability; if(!damage && flammability <= 0){ - time += Timers.delta()*8; + time += Timers.delta() * 8; } - if (baseFlammability < 0 || block != tile.block()){ + if(baseFlammability < 0 || block != tile.block()){ baseFlammability = tile.block().getFlammability(tile); block = tile.block(); } - if(damage) { + if(damage){ lifetime += Mathf.clamp(flammability / 8f, 0f, 0.6f) * Timers.delta(); } - if (flammability > 1f && Mathf.chance(0.03 * Timers.delta() * Mathf.clamp(flammability/5f, 0.3f, 2f))) { + if(flammability > 1f && Mathf.chance(0.03 * Timers.delta() * Mathf.clamp(flammability / 5f, 0.3f, 2f))){ GridPoint2 p = Mathf.select(Geometry.d4); Tile other = world.tile(tile.x + p.x, tile.y + p.y); create(other); @@ -128,7 +140,7 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable if(Mathf.chance(0.1 * Timers.delta())){ Puddle p = Puddle.getPuddle(tile); if(p != null){ - puddleFlammability = p.getFlammability()/3f; + puddleFlammability = p.getFlammability() / 3f; }else{ puddleFlammability = 0; } @@ -141,14 +153,14 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable } @Override - public void writeSave(DataOutput stream) throws IOException { + public void writeSave(DataOutput stream) throws IOException{ stream.writeInt(tile.packedPosition()); stream.writeFloat(lifetime); stream.writeFloat(time); } @Override - public void readSave(DataInput stream) throws IOException { + public void readSave(DataInput stream) throws IOException{ this.loadedPosition = stream.readInt(); this.lifetime = stream.readFloat(); this.time = stream.readFloat(); @@ -156,19 +168,19 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable } @Override - public void write(DataOutput data) throws IOException { + public void write(DataOutput data) throws IOException{ data.writeFloat(x); data.writeFloat(y); } @Override - public void read(DataInput data, long time) throws IOException { + public void read(DataInput data, long time) throws IOException{ x = data.readFloat(); y = data.readFloat(); } @Override - public void reset() { + public void reset(){ loadedPosition = -1; tile = null; baseFlammability = -1; @@ -176,7 +188,7 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable } @Override - public void added() { + public void added(){ if(loadedPosition != -1){ map.put(loadedPosition, this); tile = world.tile(loadedPosition); @@ -185,7 +197,7 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable } @Override - public void removed() { + public void removed(){ if(tile != null){ map.remove(tile.packedPosition()); } @@ -193,12 +205,7 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable } @Override - public EntityGroup targetGroup() { + public EntityGroup targetGroup(){ return fireGroup; } - - @Remote(called = Loc.server, in = In.entities) - public static void onFireRemoved(int fireid){ - fireGroup.removeByID(fireid); - } } diff --git a/core/src/io/anuke/mindustry/entities/effect/GroundEffectEntity.java b/core/src/io/anuke/mindustry/entities/effect/GroundEffectEntity.java index 99187ee60a..889c04a7ce 100644 --- a/core/src/io/anuke/mindustry/entities/effect/GroundEffectEntity.java +++ b/core/src/io/anuke/mindustry/entities/effect/GroundEffectEntity.java @@ -9,27 +9,29 @@ import io.anuke.ucore.entities.impl.EffectEntity; import io.anuke.ucore.function.EffectRenderer; import io.anuke.ucore.util.Mathf; -/**A ground effect contains an effect that is rendered on the ground layer as opposed to the top layer.*/ -public class GroundEffectEntity extends EffectEntity { +/** + * A ground effect contains an effect that is rendered on the ground layer as opposed to the top layer. + */ +public class GroundEffectEntity extends EffectEntity{ private boolean once; @Override public void update(){ - GroundEffect effect = (GroundEffect)this.effect; + GroundEffect effect = (GroundEffect) this.effect; - if(effect.isStatic) { + if(effect.isStatic){ time += Timers.delta(); time = Mathf.clamp(time, 0, effect.staticLife); - if (!once && time >= lifetime()) { + if(!once && time >= lifetime()){ once = true; time = 0f; Tile tile = Vars.world.tileWorld(x, y); if(tile != null && tile.floor().isLiquid){ remove(); } - } else if (once && time >= effect.staticLife) { + }else if(once && time >= effect.staticLife){ remove(); } }else{ @@ -39,7 +41,7 @@ public class GroundEffectEntity extends EffectEntity { @Override public void draw(){ - GroundEffect effect = (GroundEffect)this.effect; + GroundEffect effect = (GroundEffect) this.effect; if(once && effect.isStatic) Effects.renderEffect(id, effect, color, lifetime(), rotation, x, y, data); @@ -48,32 +50,38 @@ public class GroundEffectEntity extends EffectEntity { } @Override - public void reset() { + public void reset(){ super.reset(); once = false; } - /**An effect that is rendered on the ground layer as opposed to the top layer.*/ + /** + * An effect that is rendered on the ground layer as opposed to the top layer. + */ public static class GroundEffect extends Effect{ - /**How long this effect stays on the ground when static.*/ + /** + * How long this effect stays on the ground when static. + */ public final float staticLife; - /**If true, this effect will stop and lie on the ground for a specific duration, - * after its initial lifetime is over.*/ + /** + * If true, this effect will stop and lie on the ground for a specific duration, + * after its initial lifetime is over. + */ public final boolean isStatic; - public GroundEffect(float life, float staticLife, EffectRenderer draw) { + public GroundEffect(float life, float staticLife, EffectRenderer draw){ super(life, draw); this.staticLife = staticLife; this.isStatic = true; } - public GroundEffect(boolean isStatic, float life, EffectRenderer draw) { + public GroundEffect(boolean isStatic, float life, EffectRenderer draw){ super(life, draw); this.staticLife = 0f; this.isStatic = isStatic; } - public GroundEffect(float life, EffectRenderer draw) { + public GroundEffect(float life, EffectRenderer draw){ super(life, draw); this.staticLife = 0f; this.isStatic = false; diff --git a/core/src/io/anuke/mindustry/entities/effect/ItemDrop.java b/core/src/io/anuke/mindustry/entities/effect/ItemDrop.java index 2e4063ef8b..284b66420d 100644 --- a/core/src/io/anuke/mindustry/entities/effect/ItemDrop.java +++ b/core/src/io/anuke/mindustry/entities/effect/ItemDrop.java @@ -35,7 +35,7 @@ import java.io.IOException; import static io.anuke.mindustry.Vars.*; -public class ItemDrop extends SolidEntity implements SaveTrait, SyncTrait, DrawTrait, VelocityTrait, TimeTrait, TargetTrait, Poolable { +public class ItemDrop extends SolidEntity implements SaveTrait, SyncTrait, DrawTrait, VelocityTrait, TimeTrait, TargetTrait, Poolable{ private static final float sinkLifetime = 80f; private Interpolator interpolator = new Interpolator(); @@ -46,6 +46,14 @@ public class ItemDrop extends SolidEntity implements SaveTrait, SyncTrait, DrawT private float time; private float sinktime; + /** + * Internal use only! + */ + public ItemDrop(){ + hitbox.setSize(5f); + hitboxTile.setSize(5f); + } + public static ItemDrop create(Item item, int amount, float x, float y, float angle){ ItemDrop drop = new ItemDrop(); drop.item = item; @@ -73,13 +81,7 @@ public class ItemDrop extends SolidEntity implements SaveTrait, SyncTrait, DrawT } } - /**Internal use only!*/ - public ItemDrop(){ - hitbox.setSize(5f); - hitboxTile.setSize(5f); - } - - public Item getItem() { + public Item getItem(){ return item; } @@ -88,66 +90,66 @@ public class ItemDrop extends SolidEntity implements SaveTrait, SyncTrait, DrawT } @Override - public boolean isDead() { + public boolean isDead(){ return !isAdded(); } @Override - public Team getTeam() { + public Team getTeam(){ return Team.none; } @Override - public float lifetime() { - return 60*60; + public float lifetime(){ + return 60 * 60; } @Override - public void time(float time) { + public void time(float time){ this.time = time; } @Override - public float time() { + public float time(){ return time; } @Override - public Vector2 getVelocity() { + public Vector2 getVelocity(){ return velocity; } @Override - public boolean collides(SolidTrait other) { + public boolean collides(SolidTrait other){ return other instanceof Player && time > 20f; } @Override - public void collision(SolidTrait other, float x, float y) { - Unit player = (Unit)other; + public void collision(SolidTrait other, float x, float y){ + Unit player = (Unit) other; if(player.inventory.canAcceptItem(item, 1)){ int used = Math.min(amount, player.inventory.capacity() - player.inventory.getItem().amount); player.inventory.addItem(item, used); amount -= used; - if(amount <= 0) { + if(amount <= 0){ CallEntity.onPickup(getID()); } } } @Override - public void draw() { - float size = itemSize * (1f - sinktime/sinkLifetime) * (1f-Mathf.curve(fin(), 0.98f)); + public void draw(){ + float size = itemSize * (1f - sinktime / sinkLifetime) * (1f - Mathf.curve(fin(), 0.98f)); Tile tile = world.tileWorld(x, y); - Draw.color(Color.WHITE, tile == null || !tile.floor().isLiquid ? Color.WHITE : tile.floor().liquidColor, sinktime/sinkLifetime); + Draw.color(Color.WHITE, tile == null || !tile.floor().isLiquid ? Color.WHITE : tile.floor().liquidColor, sinktime / sinkLifetime); Draw.rect(item.region, x, y, size, size); int stored = Mathf.clamp(amount / 6, 1, 8); - for(int i = 0; i < stored; i ++) { + for(int i = 0; i < stored; i++){ float px = stored == 1 ? 0 : Mathf.randomSeedRange(i + 1, 4f); float py = stored == 1 ? 0 : Mathf.randomSeedRange(i + 2, 4f); Draw.rect(item.region, x + px, y + py, size, size); @@ -157,8 +159,8 @@ public class ItemDrop extends SolidEntity implements SaveTrait, SyncTrait, DrawT } @Override - public void update() { - if(Net.client()) { + public void update(){ + if(Net.client()){ interpolate(); }else{ updateVelocity(0.2f); @@ -190,28 +192,28 @@ public class ItemDrop extends SolidEntity implements SaveTrait, SyncTrait, DrawT } @Override - public void reset() { + public void reset(){ time = 0f; interpolator.reset(); } @Override - public Interpolator getInterpolator() { + public Interpolator getInterpolator(){ return interpolator; } @Override - public float drawSize() { + public float drawSize(){ return 10; } @Override - public EntityGroup targetGroup() { + public EntityGroup targetGroup(){ return itemGroup; } @Override - public void writeSave(DataOutput data) throws IOException { + public void writeSave(DataOutput data) throws IOException{ data.writeFloat(x); data.writeFloat(y); data.writeByte(item.id); @@ -219,7 +221,7 @@ public class ItemDrop extends SolidEntity implements SaveTrait, SyncTrait, DrawT } @Override - public void readSave(DataInput data) throws IOException { + public void readSave(DataInput data) throws IOException{ x = data.readFloat(); y = data.readFloat(); item = Item.getByID(data.readByte()); diff --git a/core/src/io/anuke/mindustry/entities/effect/ItemTransfer.java b/core/src/io/anuke/mindustry/entities/effect/ItemTransfer.java index 2e119b99ea..b27b8abbd5 100644 --- a/core/src/io/anuke/mindustry/entities/effect/ItemTransfer.java +++ b/core/src/io/anuke/mindustry/entities/effect/ItemTransfer.java @@ -32,17 +32,22 @@ public class ItemTransfer extends TimedEntity implements DrawTrait{ private PosTrait to; private Runnable done; + public ItemTransfer(){ + } + @Remote(in = In.entities, called = Loc.server, unreliable = true) public static void transferAmmo(Item item, float x, float y, Unit to){ if(to == null) return; to.addAmmo(item); - create(item, x, y, to, () -> {}); + create(item, x, y, to, () -> { + }); } @Remote(in = In.entities, called = Loc.server, unreliable = true) public static void transferItemEffect(Item item, float x, float y, Unit to){ if(to == null) return; - create(item, x, y, to, () -> {}); + create(item, x, y, to, () -> { + }); } @Remote(in = In.entities, called = Loc.server, unreliable = true) @@ -54,8 +59,9 @@ public class ItemTransfer extends TimedEntity implements DrawTrait{ @Remote(in = In.entities, called = Loc.server) public static void transferItemTo(Item item, int amount, float x, float y, Tile tile){ if(tile == null) return; - for (int i = 0; i < Mathf.clamp(amount/3, 1, 8); i++) { - Timers.run(i*3, () -> create(item, x, y, tile, () -> {})); + for(int i = 0; i < Mathf.clamp(amount / 3, 1, 8); i++){ + Timers.run(i * 3, () -> create(item, x, y, tile, () -> { + })); } tile.entity.items.add(item, amount); } @@ -70,15 +76,13 @@ public class ItemTransfer extends TimedEntity implements DrawTrait{ tr.add(); } - public ItemTransfer(){} - @Override - public float lifetime() { + public float lifetime(){ return 60; } @Override - public void reset() { + public void reset(){ super.reset(); item = null; to = null; @@ -89,7 +93,7 @@ public class ItemTransfer extends TimedEntity implements DrawTrait{ } @Override - public void removed() { + public void removed(){ if(done != null){ threads.run(done); } @@ -97,7 +101,7 @@ public class ItemTransfer extends TimedEntity implements DrawTrait{ } @Override - public void update() { + public void update(){ if(to == null){ remove(); return; @@ -110,24 +114,24 @@ public class ItemTransfer extends TimedEntity implements DrawTrait{ } @Override - public void draw() { - float length = fslope()*6f; + public void draw(){ + float length = fslope() * 6f; float angle = current.set(x, y).sub(from).angle(); Draw.color(Palette.accent); - Lines.stroke(fslope()*2f); + Lines.stroke(fslope() * 2f); - Lines.circle(x, y, fslope()*2f); + Lines.circle(x, y, fslope() * 2f); Lines.lineAngleCenter(x, y, angle, length); - Lines.lineAngle(x, y, angle, fout()*6f); + Lines.lineAngle(x, y, angle, fout() * 6f); Draw.color(item.color); - Fill.circle(x, y, fslope()*1.5f); + Fill.circle(x, y, fslope() * 1.5f); Draw.reset(); } @Override - public EntityGroup targetGroup() { + public EntityGroup targetGroup(){ return effectGroup; } } diff --git a/core/src/io/anuke/mindustry/entities/effect/Lightning.java b/core/src/io/anuke/mindustry/entities/effect/Lightning.java index 37cd52523c..2ab599b003 100644 --- a/core/src/io/anuke/mindustry/entities/effect/Lightning.java +++ b/core/src/io/anuke/mindustry/entities/effect/Lightning.java @@ -46,7 +46,15 @@ public class Lightning extends TimedEntity implements Poolable, DrawTrait, SyncT private Color color = Palette.lancerLaser; private SeedRandom random = new SeedRandom(); - /**Create a lighting branch at a location. Use Team.none to damage everyone.*/ + /** + * For pooling use only. Do not call directly! + */ + public Lightning(){ + } + + /** + * Create a lighting branch at a location. Use Team.none to damage everyone. + */ public static void create(Team team, Effect effect, Color color, float damage, float x, float y, float targetAngle, int length){ CallEntity.createLighting(lastSeed++, team, effect, color, damage, x, y, targetAngle, length); } @@ -69,7 +77,7 @@ public class Lightning extends TimedEntity implements Poolable, DrawTrait, SyncT Units.getNearbyEnemies(team, rect, entities::add); - for(int i = 0; i < length; i ++){ + for(int i = 0; i < length; i++){ l.lines.add(new Vector2(x, y)); float fx = x, fy = y; @@ -82,15 +90,15 @@ public class Lightning extends TimedEntity implements Poolable, DrawTrait, SyncT Units.getNearbyEnemies(team, rect, entity -> { float dst = entity.distanceTo(x2, y2); - if(dst < attractRange) { + if(dst < attractRange){ angle = Mathf.slerp(angle, Angles.angle(x2, y2, entity.x, entity.y), (attractRange - dst) / attractRange / 4f); } entity.getHitbox(hitrect); - hitrect.x -= range/2f; - hitrect.y -= range/2f; - hitrect.width += range/2f; - hitrect.height += range/2f; + hitrect.x -= range / 2f; + hitrect.y -= range / 2f; + hitrect.width += range / 2f; + hitrect.height += range / 2f; if(hitrect.contains(x2, y2) || hitrect.contains(fx, fy)){ float result = damage; @@ -104,7 +112,7 @@ public class Lightning extends TimedEntity implements Poolable, DrawTrait, SyncT }); if(l.random.chance(0.1f)){ - createLighting(l.random.nextInt(), team, effect, color, damage, x2, y2, angle + l.random.range(100f), length/3); + createLighting(l.random.nextInt(), team, effect, color, damage, x2, y2, angle + l.random.range(100f), length / 3); } x = x2; @@ -115,47 +123,44 @@ public class Lightning extends TimedEntity implements Poolable, DrawTrait, SyncT l.add(); } - /**For pooling use only. Do not call directly!*/ - public Lightning(){} - @Override - public boolean isSyncing() { + public boolean isSyncing(){ return false; } @Override - public void write(DataOutput data) throws IOException { + public void write(DataOutput data) throws IOException{ } @Override - public void read(DataInput data, long time) throws IOException { + public void read(DataInput data, long time) throws IOException{ } @Override - public float lifetime() { + public float lifetime(){ return 10; } @Override - public void reset() { + public void reset(){ color = Palette.lancerLaser; lines.clear(); } @Override - public void removed() { + public void removed(){ Pooling.free(this); } @Override - public void draw() { + public void draw(){ float lx = x, ly = y; Draw.color(color, Color.WHITE, fin()); - for(int i = 0; i < lines.size; i ++){ + for(int i = 0; i < lines.size; i++){ Vector2 v = lines.get(i); - Lines.stroke(fout() * 3f + 1f-(float)i/lines.size); + Lines.stroke(fout() * 3f + 1f - (float) i / lines.size); Lines.line(lx, ly, v.x, v.y); lx = v.x; ly = v.y; @@ -164,7 +169,7 @@ public class Lightning extends TimedEntity implements Poolable, DrawTrait, SyncT } @Override - public EntityGroup targetGroup() { + public EntityGroup targetGroup(){ return bulletGroup; } } diff --git a/core/src/io/anuke/mindustry/entities/effect/Puddle.java b/core/src/io/anuke/mindustry/entities/effect/Puddle.java index 0aa7032348..1fa0cd8a0b 100644 --- a/core/src/io/anuke/mindustry/entities/effect/Puddle.java +++ b/core/src/io/anuke/mindustry/entities/effect/Puddle.java @@ -40,7 +40,7 @@ import java.io.IOException; import static io.anuke.mindustry.Vars.puddleGroup; import static io.anuke.mindustry.Vars.world; -public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait, SyncTrait { +public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait, SyncTrait{ private static final IntMap map = new IntMap<>(); private static final float maxLiquid = 70f; private static final int maxGeneration = 2; @@ -58,17 +58,29 @@ public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait private float accepting; private byte generation; - /**Deposists a puddle between tile and source.*/ + /** + * Deserialization use only! + */ + public Puddle(){ + } + + /** + * Deposists a puddle between tile and source. + */ public static void deposit(Tile tile, Tile source, Liquid liquid, float amount){ deposit(tile, source, liquid, amount, 0); } - /**Deposists a puddle at a tile.*/ + /** + * Deposists a puddle at a tile. + */ public static void deposit(Tile tile, Liquid liquid, float amount){ deposit(tile, tile, liquid, amount, 0); } - /**Returns the puddle on the specified tile. May return null.*/ + /** + * Returns the puddle on the specified tile. May return null. + */ public static Puddle getPuddle(Tile tile){ return map.get(tile.packedPosition()); } @@ -76,11 +88,11 @@ public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait private static void deposit(Tile tile, Tile source, Liquid liquid, float amount, int generation){ if(tile.floor().isLiquid && !canStayOn(liquid, tile.floor().liquidDrop)){ reactPuddle(tile.floor().liquidDrop, liquid, amount, tile, - (tile.worldx() + source.worldx())/2f, (tile.worldy() + source.worldy())/2f); + (tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f); if(generation == 0 && Timers.get(tile, "ripple", 50)){ Effects.effect(BlockFx.ripple, tile.floor().liquidDrop.color, - (tile.worldx() + source.worldx())/2f, (tile.worldy() + source.worldy())/2f); + (tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f); } return; } @@ -93,28 +105,32 @@ public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait puddle.tile = tile; puddle.liquid = liquid; puddle.amount = amount; - puddle.generation = (byte)generation; - puddle.set((tile.worldx() + source.worldx())/2f, (tile.worldy() + source.worldy())/2f); + puddle.generation = (byte) generation; + puddle.set((tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f); puddle.add(); map.put(tile.packedPosition(), puddle); }else if(p.liquid == liquid){ p.accepting = Math.max(amount, p.accepting); - if(generation == 0 && Timers.get(p, "ripple2", 50) && p.amount >= maxLiquid/2f){ - Effects.effect(BlockFx.ripple, p.liquid.color, (tile.worldx() + source.worldx())/2f, (tile.worldy() + source.worldy())/2f); + if(generation == 0 && Timers.get(p, "ripple2", 50) && p.amount >= maxLiquid / 2f){ + Effects.effect(BlockFx.ripple, p.liquid.color, (tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f); } }else{ p.amount -= reactPuddle(p.liquid, liquid, amount, p.tile, p.x, p.y); } } - /**Returns whether the first liquid can 'stay' on the second one. - * Currently, the only place where this can happen is oil on water.*/ + /** + * Returns whether the first liquid can 'stay' on the second one. + * Currently, the only place where this can happen is oil on water. + */ private static boolean canStayOn(Liquid liquid, Liquid other){ return liquid == Liquids.oil && other == Liquids.water; } - /**Reacts two liquids together at a location.*/ + /** + * Reacts two liquids together at a location. + */ private static float reactPuddle(Liquid dest, Liquid liquid, float amount, Tile tile, float x, float y){ if((dest.flammability > 0.3f && liquid.temperature > 0.7f) || (liquid.flammability > 0.3f && dest.temperature > 0.7f)){ //flammable liquid + hot liquid @@ -126,25 +142,27 @@ public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait if(Mathf.chance(0.5f * amount)){ Effects.effect(EnvironmentFx.steam, x, y); } - return - 0.1f * amount; + return -0.1f * amount; }else if(liquid.temperature > 0.7f && dest.temperature < 0.55f){ //hot liquid poured onto cold puddle if(Mathf.chance(0.8f * amount)){ Effects.effect(EnvironmentFx.steam, x, y); } - return - 0.4f * amount; + return -0.4f * amount; } return 0f; } - /**Deserialization use only!*/ - public Puddle(){} + @Remote(called = Loc.server, in = In.entities) + public static void onPuddleRemoved(int puddleid){ + puddleGroup.removeByID(puddleid); + } public float getFlammability(){ return liquid.flammability * amount; } @Override - public void update() { + public void update(){ //no updating happens clientside if(Net.client()){ @@ -158,11 +176,11 @@ public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait amount += accepting; accepting = 0f; - if (amount >= maxLiquid / 1.5f && generation < maxGeneration) { + if(amount >= maxLiquid / 1.5f && generation < maxGeneration){ float deposited = Math.min((amount - maxLiquid / 1.5f) / 4f, 0.3f) * Timers.delta(); - for (GridPoint2 point : Geometry.d4) { + for(GridPoint2 point : Geometry.d4){ Tile other = world.tile(tile.x + point.x, tile.y + point.y); - if (other.block() == Blocks.air && other.cliffs == 0) { + if(other.block() == Blocks.air && other.cliffs == 0){ deposit(other, tile, liquid, deposited, generation + 1); amount -= deposited / 2f; //tweak to speed up/slow down puddle propagation } @@ -171,14 +189,14 @@ public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait amount = Mathf.clamp(amount, 0, maxLiquid); - if (amount <= 0f) { + if(amount <= 0f){ CallEntity.onPuddleRemoved(getID()); } } //effects-only code - if(amount >= maxLiquid/2f && updateTime <= 0f){ - Units.getNearby(rect.setSize(Mathf.clamp(amount/(maxLiquid/1.5f))*10f).setCenter(x, y), unit -> { + if(amount >= maxLiquid / 2f && updateTime <= 0f){ + Units.getNearby(rect.setSize(Mathf.clamp(amount / (maxLiquid / 1.5f)) * 10f).setCenter(x, y), unit -> { if(unit.isFlying()) return; unit.getHitbox(rect2); @@ -186,7 +204,7 @@ public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait unit.applyEffect(liquid.effect, 0.5f); - if(unit.getVelocity().len() > 0.1) { + if(unit.getVelocity().len() > 0.1){ Effects.effect(BlockFx.ripple, liquid.color, unit.x, unit.y); } }); @@ -202,30 +220,30 @@ public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait } @Override - public void draw() { + public void draw(){ seeds = id; boolean onLiquid = tile.floor().isLiquid; - float f = Mathf.clamp(amount/(maxLiquid/1.5f)); + float f = Mathf.clamp(amount / (maxLiquid / 1.5f)); float smag = onLiquid ? 0.8f : 0f; float sscl = 20f; Draw.color(Hue.shift(tmp.set(liquid.color), 2, -0.05f)); - Fill.circle(x + Mathf.sin(Timers.time() + seeds*532, sscl, smag), y + Mathf.sin(Timers.time() + seeds*53, sscl, smag), f * 8f); + Fill.circle(x + Mathf.sin(Timers.time() + seeds * 532, sscl, smag), y + Mathf.sin(Timers.time() + seeds * 53, sscl, smag), f * 8f); Angles.randLenVectors(id, 3, f * 6f, (ex, ey) -> { - Fill.circle(x + ex + Mathf.sin(Timers.time() + seeds*532, sscl, smag), - y + ey + Mathf.sin(Timers.time() + seeds*53, sscl, smag), f * 5f); - seeds ++; + Fill.circle(x + ex + Mathf.sin(Timers.time() + seeds * 532, sscl, smag), + y + ey + Mathf.sin(Timers.time() + seeds * 53, sscl, smag), f * 5f); + seeds++; }); Draw.color(); } @Override - public float drawSize() { + public float drawSize(){ return 20; } @Override - public void writeSave(DataOutput stream) throws IOException { + public void writeSave(DataOutput stream) throws IOException{ stream.writeInt(tile.packedPosition()); stream.writeFloat(x); stream.writeFloat(y); @@ -235,7 +253,7 @@ public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait } @Override - public void readSave(DataInput stream) throws IOException { + public void readSave(DataInput stream) throws IOException{ this.loadedPosition = stream.readInt(); this.x = stream.readFloat(); this.y = stream.readFloat(); @@ -246,7 +264,7 @@ public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait } @Override - public void reset() { + public void reset(){ loadedPosition = -1; tile = null; liquid = null; @@ -256,7 +274,7 @@ public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait } @Override - public void added() { + public void added(){ if(loadedPosition != -1){ map.put(loadedPosition, this); tile = world.tile(loadedPosition); @@ -264,38 +282,33 @@ public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait } @Override - public void removed() { + public void removed(){ map.remove(tile.packedPosition()); reset(); } @Override - public void write(DataOutput data) throws IOException { + public void write(DataOutput data) throws IOException{ data.writeFloat(x); data.writeFloat(y); data.writeByte(liquid.id); - data.writeShort((short)(amount * 4)); + data.writeShort((short) (amount * 4)); data.writeInt(tile.packedPosition()); } @Override - public void read(DataInput data, long time) throws IOException { + public void read(DataInput data, long time) throws IOException{ x = data.readFloat(); y = data.readFloat(); liquid = Liquid.getByID(data.readByte()); - targetAmount = data.readShort()/4f; + targetAmount = data.readShort() / 4f; tile = world.tile(data.readInt()); map.put(tile.packedPosition(), this); } @Override - public EntityGroup targetGroup() { + public EntityGroup targetGroup(){ return puddleGroup; } - - @Remote(called = Loc.server, in = In.entities) - public static void onPuddleRemoved(int puddleid){ - puddleGroup.removeByID(puddleid); - } } diff --git a/core/src/io/anuke/mindustry/entities/effect/RubbleDecal.java b/core/src/io/anuke/mindustry/entities/effect/RubbleDecal.java index 217dc9e62a..8fb5dedf98 100644 --- a/core/src/io/anuke/mindustry/entities/effect/RubbleDecal.java +++ b/core/src/io/anuke/mindustry/entities/effect/RubbleDecal.java @@ -3,10 +3,12 @@ package io.anuke.mindustry.entities.effect; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.util.Mathf; -public class RubbleDecal extends Decal { +public class RubbleDecal extends Decal{ private int size; - /**Creates a rubble effect at a position. Provide a block size to use.*/ + /** + * Creates a rubble effect at a position. Provide a block size to use. + */ public static void create(float x, float y, int size){ RubbleDecal decal = new RubbleDecal(); decal.size = size; diff --git a/core/src/io/anuke/mindustry/entities/effect/ScorchDecal.java b/core/src/io/anuke/mindustry/entities/effect/ScorchDecal.java index 1ef31e49fc..7bfc3e369e 100644 --- a/core/src/io/anuke/mindustry/entities/effect/ScorchDecal.java +++ b/core/src/io/anuke/mindustry/entities/effect/ScorchDecal.java @@ -8,21 +8,21 @@ import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.world; -public class ScorchDecal extends Decal { +public class ScorchDecal extends Decal{ private static final int scorches = 5; private static final TextureRegion[] regions = new TextureRegion[scorches]; public static void create(float x, float y){ if(regions[0] == null){ - for (int i = 0; i < regions.length; i++) { - regions[i] = Draw.region("scorch" + (i+1)); + for(int i = 0; i < regions.length; i++){ + regions[i] = Draw.region("scorch" + (i + 1)); } } Tile tile = world.tileWorld(x, y); if(tile == null || tile.floor().liquidDrop != null) return; - + ScorchDecal decal = new ScorchDecal(); decal.set(x, y); decal.add(); @@ -31,10 +31,10 @@ public class ScorchDecal extends Decal { @Override public void drawDecal(){ - for (int i = 0; i < 5; i++) { - TextureRegion region = regions[Mathf.randomSeed(id - i, 0, scorches-1)]; + for(int i = 0; i < 5; i++){ + TextureRegion region = regions[Mathf.randomSeed(id - i, 0, scorches - 1)]; float rotation = Mathf.randomSeed(id + i, 0, 360); - float space = 1.5f + Mathf.randomSeed(id + i + 1, 0, 20)/10f; + float space = 1.5f + Mathf.randomSeed(id + i + 1, 0, 20) / 10f; Draw.grect(region, x + Angles.trnsx(rotation, space), y + Angles.trnsy(rotation, space), rotation - 90); } } diff --git a/core/src/io/anuke/mindustry/entities/effect/Shield.java b/core/src/io/anuke/mindustry/entities/effect/Shield.java index 31f7175048..da10da3fde 100644 --- a/core/src/io/anuke/mindustry/entities/effect/Shield.java +++ b/core/src/io/anuke/mindustry/entities/effect/Shield.java @@ -13,44 +13,43 @@ import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.shieldGroup; //todo re-implement -public class Shield extends BaseEntity implements DrawTrait { - public boolean active; - public boolean hitPlayers = false; - public float radius = 0f; - - private float uptime = 0f; - private final Tile tile; - - public Shield(Tile tile){ - this.tile = tile; - this.x = tile.worldx(); - this.y = tile.worldy(); - } - - public float drawSize(){ - return 150; - } - - @Override - public void update(){ - float alpha = 0.1f; - Interpolation interp = Interpolation.fade; - - if(active){ - uptime = interp.apply(uptime, 1f, alpha * Timers.delta()); - }else{ - uptime = interp.apply(uptime, 0f, alpha * Timers.delta()); - if(uptime <= 0.05f) - remove(); - } - uptime = Mathf.clamp(uptime); - - if(!(tile.block() instanceof ShieldBlock)){ - remove(); - return; - } - - ShieldBlock block = (ShieldBlock)tile.block(); +public class Shield extends BaseEntity implements DrawTrait{ + private final Tile tile; + public boolean active; + public boolean hitPlayers = false; + public float radius = 0f; + private float uptime = 0f; + + public Shield(Tile tile){ + this.tile = tile; + this.x = tile.worldx(); + this.y = tile.worldy(); + } + + public float drawSize(){ + return 150; + } + + @Override + public void update(){ + float alpha = 0.1f; + Interpolation interp = Interpolation.fade; + + if(active){ + uptime = interp.apply(uptime, 1f, alpha * Timers.delta()); + }else{ + uptime = interp.apply(uptime, 0f, alpha * Timers.delta()); + if(uptime <= 0.05f) + remove(); + } + uptime = Mathf.clamp(uptime); + + if(!(tile.block() instanceof ShieldBlock)){ + remove(); + return; + } + + ShieldBlock block = (ShieldBlock) tile.block(); /* Entities.getNearby(bulletGroup, x, y, block.shieldRadius * 2*uptime + 10, entity->{ @@ -64,39 +63,39 @@ public class Shield extends BaseEntity implements DrawTrait { } } });*/ - } - - @Override - public void draw(){ - if(!(tile.block() instanceof ShieldBlock) || radius <= 1f){ - return; - } + } - Fill.circle(x, y, drawRadius()); - } - - float drawRadius(){ - return (radius + Mathf.sin(Timers.time(), 25f, 1f)); - } - - public void removeDelay(){ - active = false; - } + @Override + public void draw(){ + if(!(tile.block() instanceof ShieldBlock) || radius <= 1f){ + return; + } - @Override - public EntityGroup targetGroup() { - return shieldGroup; - } + Fill.circle(x, y, drawRadius()); + } + + float drawRadius(){ + return (radius + Mathf.sin(Timers.time(), 25f, 1f)); + } + + public void removeDelay(){ + active = false; + } + + @Override + public EntityGroup targetGroup(){ + return shieldGroup; + } + + @Override + public void added(){ + active = true; + } + + @Override + public void removed(){ + active = false; + uptime = 0f; + } - @Override - public void added(){ - active = true; - } - - @Override - public void removed(){ - active = false; - uptime = 0f; - } - } diff --git a/core/src/io/anuke/mindustry/entities/traits/BelowLiquidTrait.java b/core/src/io/anuke/mindustry/entities/traits/BelowLiquidTrait.java index 37ee664fcb..c4abd8abf0 100644 --- a/core/src/io/anuke/mindustry/entities/traits/BelowLiquidTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/BelowLiquidTrait.java @@ -1,5 +1,7 @@ package io.anuke.mindustry.entities.traits; -/**A flag interface for marking an effect as appearing below liquids.*/ -public interface BelowLiquidTrait { +/** + * A flag interface for marking an effect as appearing below liquids. + */ +public interface BelowLiquidTrait{ } diff --git a/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java b/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java index 6a7f4d8cae..5b67677802 100644 --- a/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java @@ -36,34 +36,48 @@ import java.util.Arrays; import static io.anuke.mindustry.Vars.tilesize; import static io.anuke.mindustry.Vars.world; -/**Interface for units that build, break or mine things.*/ +/** + * Interface for units that build, break or mine things. + */ public interface BuilderTrait extends Entity{ //these are not instance variables! Translator[] tmptr = {new Translator(), new Translator(), new Translator(), new Translator()}; float placeDistance = 140f; float mineDistance = 70f; - /**Returns the queue for storing build requests.*/ + /** + * Returns the queue for storing build requests. + */ Queue getPlaceQueue(); - /**Returns the tile this builder is currently mining.*/ + /** + * Returns the tile this builder is currently mining. + */ Tile getMineTile(); - /**Sets the tile this builder is currently mining.*/ + /** + * Sets the tile this builder is currently mining. + */ void setMineTile(Tile tile); - /**Returns the minining speed of this miner. 1 = standard, 0.5 = half speed, 2 = double speed, etc.*/ + /** + * Returns the minining speed of this miner. 1 = standard, 0.5 = half speed, 2 = double speed, etc. + */ float getMinePower(); - /**Build power, can be any float. 1 = builds recipes in normal time, 0 = doesn't build at all.*/ + /** + * Build power, can be any float. 1 = builds recipes in normal time, 0 = doesn't build at all. + */ float getBuildPower(Tile tile); - /**Whether this type of builder can begin creating new blocks.*/ + /** + * Whether this type of builder can begin creating new blocks. + */ default boolean canCreateBlocks(){ return true; } - default void writeBuilding(DataOutput output) throws IOException { + default void writeBuilding(DataOutput output) throws IOException{ BuildRequest request = getCurrentRequest(); if(request != null){ @@ -83,17 +97,17 @@ public interface BuilderTrait extends Entity{ } default void readBuilding(DataInput input, boolean applyChanges) throws IOException{ - synchronized (getPlaceQueue()) { + synchronized(getPlaceQueue()){ if(applyChanges) getPlaceQueue().clear(); byte type = input.readByte(); - if (type != -1) { + if(type != -1){ int position = input.readInt(); BuildRequest request; - if (type == 1) { //remove + if(type == 1){ //remove request = new BuildRequest(position % world.width(), position / world.width()); - } else { //place + }else{ //place byte recipe = input.readByte(); byte rotation = input.readByte(); request = new BuildRequest(position % world.width(), position / world.width(), rotation, Recipe.getByID(recipe)); @@ -106,17 +120,21 @@ public interface BuilderTrait extends Entity{ } } - /**Return whether this builder's place queue contains items.*/ + /** + * Return whether this builder's place queue contains items. + */ default boolean isBuilding(){ return getPlaceQueue().size != 0; } - /**If a place request matching this signature is present, it is removed. - * Otherwise, a new place request is added to the queue.*/ + /** + * If a place request matching this signature is present, it is removed. + * Otherwise, a new place request is added to the queue. + */ default void replaceBuilding(int x, int y, int rotation, Recipe recipe){ - synchronized (getPlaceQueue()) { - for (BuildRequest request : getPlaceQueue()) { - if (request.x == x && request.y == y) { + synchronized(getPlaceQueue()){ + for(BuildRequest request : getPlaceQueue()){ + if(request.x == x && request.y == y){ clearBuilding(); addBuildRequest(request); return; @@ -127,16 +145,20 @@ public interface BuilderTrait extends Entity{ addBuildRequest(new BuildRequest(x, y, rotation, recipe)); } - /**Clears the placement queue.*/ + /** + * Clears the placement queue. + */ default void clearBuilding(){ getPlaceQueue().clear(); } - /**Add another build requests to the tail of the queue, if it doesn't exist there yet.*/ + /** + * Add another build requests to the tail of the queue, if it doesn't exist there yet. + */ default void addBuildRequest(BuildRequest place){ - synchronized (getPlaceQueue()) { - for (BuildRequest request : getPlaceQueue()) { - if (request.x == place.x && request.y == place.y) { + synchronized(getPlaceQueue()){ + for(BuildRequest request : getPlaceQueue()){ + if(request.x == place.x && request.y == place.y){ return; } } @@ -144,16 +166,20 @@ public interface BuilderTrait extends Entity{ } } - /**Return the build requests currently active, or the one at the top of the queue. - * May return null.*/ + /** + * Return the build requests currently active, or the one at the top of the queue. + * May return null. + */ default BuildRequest getCurrentRequest(){ - synchronized (getPlaceQueue()) { + synchronized(getPlaceQueue()){ return getPlaceQueue().size == 0 ? null : getPlaceQueue().first(); } } - /**Update building mechanism for this unit. - * This includes mining.*/ + /** + * Update building mechanism for this unit. + * This includes mining. + */ default void updateBuilding(Unit unit){ BuildRequest current = getCurrentRequest(); @@ -176,8 +202,8 @@ public interface BuilderTrait extends Entity{ Tile tile = world.tile(current.x, current.y); - if (!(tile.block() instanceof BuildBlock)) { - if(canCreateBlocks() && !current.remove && Build.validPlace(unit.getTeam(), current.x, current.y, current.recipe.result, current.rotation)) { + if(!(tile.block() instanceof BuildBlock)){ + if(canCreateBlocks() && !current.remove && Build.validPlace(unit.getTeam(), current.x, current.y, current.recipe.result, current.rotation)){ Build.beginPlace(unit.getTeam(), current.x, current.y, current.recipe, current.rotation); }else if(canCreateBlocks() && current.remove && Build.validBreak(unit.getTeam(), current.x, current.y)){ Build.beginBreak(unit.getTeam(), current.x, current.y); @@ -203,7 +229,9 @@ public interface BuilderTrait extends Entity{ current.progress = entity.progress(); } - /**Do not call directly.*/ + /** + * Do not call directly. + */ default void updateMining(Unit unit){ Tile tile = getMineTile(); @@ -216,26 +244,28 @@ public interface BuilderTrait extends Entity{ if(unit.inventory.canAcceptItem(item) && Mathf.chance(Timers.delta() * (0.06 - item.hardness * 0.01) * getMinePower())){ CallEntity.transferItemToUnit(item, - tile.worldx() + Mathf.range(tilesize/2f), - tile.worldy() + Mathf.range(tilesize/2f), + tile.worldx() + Mathf.range(tilesize / 2f), + tile.worldy() + Mathf.range(tilesize / 2f), unit); } if(Mathf.chance(0.06 * Timers.delta())){ Effects.effect(BlockFx.pulverizeSmall, - tile.worldx() + Mathf.range(tilesize/2f), - tile.worldy() + Mathf.range(tilesize/2f), 0f, item.color); + tile.worldx() + Mathf.range(tilesize / 2f), + tile.worldy() + Mathf.range(tilesize / 2f), 0f, item.color); } } } - /**Draw placement effects for an entity. This includes mining*/ + /** + * Draw placement effects for an entity. This includes mining + */ default void drawBuilding(Unit unit){ BuildRequest request; - synchronized (getPlaceQueue()) { - if (!isBuilding()) { - if (getMineTile() != null) { + synchronized(getPlaceQueue()){ + if(!isBuilding()){ + if(getMineTile() != null){ drawMining(unit); } return; @@ -255,7 +285,7 @@ public interface BuilderTrait extends Entity{ float px = unit.x + Angles.trnsx(unit.rotation, focusLen); float py = unit.y + Angles.trnsy(unit.rotation, focusLen); - float sz = Vars.tilesize*tile.block().size/2f; + float sz = Vars.tilesize * tile.block().size / 2f; float ang = unit.angleTo(tile); tmptr[0].set(tile.drawx() - sz, tile.drawy() - sz); @@ -286,14 +316,16 @@ public interface BuilderTrait extends Entity{ Draw.color(); } - /**Internal use only.*/ + /** + * Internal use only. + */ default void drawMining(Unit unit){ Tile tile = getMineTile(); if(tile == null) return; float focusLen = 4f + Mathf.absin(Timers.time(), 1.1f, 0.5f); - float swingScl = 12f, swingMag = tilesize/8f; + float swingScl = 12f, swingMag = tilesize / 8f; float flashScl = 0.3f; float px = unit.x + Angles.trnsx(unit.rotation, focusLen); @@ -302,10 +334,10 @@ public interface BuilderTrait extends Entity{ float ex = tile.worldx() + Mathf.sin(Timers.time() + 48, swingScl, swingMag); float ey = tile.worldy() + Mathf.sin(Timers.time() + 48, swingScl + 2f, swingMag); - Draw.color(Color.LIGHT_GRAY, Color.WHITE, 1f-flashScl + Mathf.absin(Timers.time(), 0.5f, flashScl)); + Draw.color(Color.LIGHT_GRAY, Color.WHITE, 1f - flashScl + Mathf.absin(Timers.time(), 0.5f, flashScl)); Shapes.laser("minelaser", "minelaser-end", px, py, ex, ey); - if(unit instanceof Player && ((Player) unit).isLocal) { + if(unit instanceof Player && ((Player) unit).isLocal){ Draw.color(Palette.accent); Lines.poly(tile.worldx(), tile.worldy(), 4, tilesize / 2f * Mathf.sqrt2, Timers.time()); } @@ -313,16 +345,20 @@ public interface BuilderTrait extends Entity{ Draw.color(); } - /**Class for storing build requests. Can be either a place or remove request.*/ - class BuildRequest { + /** + * Class for storing build requests. Can be either a place or remove request. + */ + class BuildRequest{ public final int x, y, rotation; public final Recipe recipe; public final boolean remove; public float progress; - /**This creates a build request.*/ - public BuildRequest(int x, int y, int rotation, Recipe recipe) { + /** + * This creates a build request. + */ + public BuildRequest(int x, int y, int rotation, Recipe recipe){ this.x = x; this.y = y; this.rotation = rotation; @@ -330,8 +366,10 @@ public interface BuilderTrait extends Entity{ this.remove = false; } - /**This creates a remove request.*/ - public BuildRequest(int x, int y) { + /** + * This creates a remove request. + */ + public BuildRequest(int x, int y){ this.x = x; this.y = y; this.rotation = -1; diff --git a/core/src/io/anuke/mindustry/entities/traits/CarriableTrait.java b/core/src/io/anuke/mindustry/entities/traits/CarriableTrait.java index c21bd5ccf5..296b782154 100644 --- a/core/src/io/anuke/mindustry/entities/traits/CarriableTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/CarriableTrait.java @@ -8,6 +8,7 @@ public interface CarriableTrait extends TeamTrait, TargetTrait, SolidTrait{ return getCarrier() != null; } - void setCarrier(CarryTrait carrier); CarryTrait getCarrier(); + + void setCarrier(CarryTrait carrier); } diff --git a/core/src/io/anuke/mindustry/entities/traits/CarryTrait.java b/core/src/io/anuke/mindustry/entities/traits/CarryTrait.java index a9150df1bd..63c10a4578 100644 --- a/core/src/io/anuke/mindustry/entities/traits/CarryTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/CarryTrait.java @@ -10,28 +10,6 @@ import io.anuke.ucore.core.Effects; import io.anuke.ucore.entities.trait.SolidTrait; public interface CarryTrait extends TeamTrait, SolidTrait, TargetTrait{ - /**Returns the thing this carrier is carrying.*/ - CarriableTrait getCarry(); - /**Sets the carrying unit. Internal use only! Use {@link #carry(CarriableTrait)} to set state.*/ - void setCarry(CarriableTrait unit); - /**Returns maximum mass this carrier can carry.*/ - float getCarryWeight(); - - /**Drops the unit that is being carried, if applicable.*/ - default void dropCarry(){ - carry(null); - } - - default void dropCarryLocal(){ - setCarryOf(null, this, null); - } - - /**Do not override unless absolutely necessary. - * Carries a unit. To drop a unit, call with {@code null}.*/ - default void carry(CarriableTrait unit){ - CallEntity.setCarryOf(this instanceof Player ? (Player)this : null, this, unit); - } - @Remote(called = Loc.both, targets = Loc.both, forward = true, in = In.entities) static void dropSelf(Player player){ if(player.getCarrier() != null){ @@ -62,4 +40,38 @@ public interface CarryTrait extends TeamTrait, SolidTrait, TargetTrait{ Effects.effect(UnitFx.unitPickup, trait); } } + + /** + * Returns the thing this carrier is carrying. + */ + CarriableTrait getCarry(); + + /** + * Sets the carrying unit. Internal use only! Use {@link #carry(CarriableTrait)} to set state. + */ + void setCarry(CarriableTrait unit); + + /** + * Returns maximum mass this carrier can carry. + */ + float getCarryWeight(); + + /** + * Drops the unit that is being carried, if applicable. + */ + default void dropCarry(){ + carry(null); + } + + default void dropCarryLocal(){ + setCarryOf(null, this, null); + } + + /** + * Do not override unless absolutely necessary. + * Carries a unit. To drop a unit, call with {@code null}. + */ + default void carry(CarriableTrait unit){ + CallEntity.setCarryOf(this instanceof Player ? (Player) this : null, this, unit); + } } diff --git a/core/src/io/anuke/mindustry/entities/traits/InventoryTrait.java b/core/src/io/anuke/mindustry/entities/traits/InventoryTrait.java index 506ca6bd6a..c84eaea6b4 100644 --- a/core/src/io/anuke/mindustry/entities/traits/InventoryTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/InventoryTrait.java @@ -2,6 +2,6 @@ package io.anuke.mindustry.entities.traits; import io.anuke.mindustry.entities.UnitInventory; -public interface InventoryTrait { +public interface InventoryTrait{ UnitInventory getInventory(); } diff --git a/core/src/io/anuke/mindustry/entities/traits/RepairTrait.java b/core/src/io/anuke/mindustry/entities/traits/RepairTrait.java index 52e9a1c86c..4712730e4c 100644 --- a/core/src/io/anuke/mindustry/entities/traits/RepairTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/RepairTrait.java @@ -3,7 +3,7 @@ package io.anuke.mindustry.entities.traits; import io.anuke.ucore.entities.trait.HealthTrait; //TODO implement -public interface RepairTrait extends TeamTrait { +public interface RepairTrait extends TeamTrait{ HealthTrait getRepairing(); diff --git a/core/src/io/anuke/mindustry/entities/traits/SaveTrait.java b/core/src/io/anuke/mindustry/entities/traits/SaveTrait.java index 94590db2fc..4e7009771e 100644 --- a/core/src/io/anuke/mindustry/entities/traits/SaveTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/SaveTrait.java @@ -2,6 +2,8 @@ package io.anuke.mindustry.entities.traits; import io.anuke.ucore.entities.trait.Entity; -/**Marks an entity as serializable.*/ +/** + * Marks an entity as serializable. + */ public interface SaveTrait extends Entity, TypeTrait, Saveable{ } diff --git a/core/src/io/anuke/mindustry/entities/traits/Saveable.java b/core/src/io/anuke/mindustry/entities/traits/Saveable.java index fee2a3123b..6f3950bcb0 100644 --- a/core/src/io/anuke/mindustry/entities/traits/Saveable.java +++ b/core/src/io/anuke/mindustry/entities/traits/Saveable.java @@ -4,7 +4,8 @@ import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; -public interface Saveable { +public interface Saveable{ void writeSave(DataOutput stream) throws IOException; + void readSave(DataInput stream) throws IOException; } diff --git a/core/src/io/anuke/mindustry/entities/traits/ShooterTrait.java b/core/src/io/anuke/mindustry/entities/traits/ShooterTrait.java index c51eae473d..12df85dda1 100644 --- a/core/src/io/anuke/mindustry/entities/traits/ShooterTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/ShooterTrait.java @@ -7,6 +7,8 @@ import io.anuke.ucore.util.Timer; public interface ShooterTrait extends VelocityTrait, TeamTrait, InventoryTrait{ Timer getTimer(); + int getShootTimer(boolean left); + Weapon getWeapon(); } diff --git a/core/src/io/anuke/mindustry/entities/traits/SpawnerTrait.java b/core/src/io/anuke/mindustry/entities/traits/SpawnerTrait.java index 1fd4a9daf0..55c1763b1f 100644 --- a/core/src/io/anuke/mindustry/entities/traits/SpawnerTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/SpawnerTrait.java @@ -3,8 +3,10 @@ package io.anuke.mindustry.entities.traits; import io.anuke.mindustry.entities.Unit; import io.anuke.mindustry.world.Tile; -public interface SpawnerTrait { +public interface SpawnerTrait{ Tile getTile(); + void updateSpawning(Unit unit); + float getSpawnProgress(); } diff --git a/core/src/io/anuke/mindustry/entities/traits/SyncTrait.java b/core/src/io/anuke/mindustry/entities/traits/SyncTrait.java index 471b3226c4..56bd43f948 100644 --- a/core/src/io/anuke/mindustry/entities/traits/SyncTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/SyncTrait.java @@ -10,18 +10,22 @@ import java.io.IOException; import static io.anuke.mindustry.Vars.threads; -public interface SyncTrait extends Entity, TypeTrait { +public interface SyncTrait extends Entity, TypeTrait{ - /**Whether smoothing of entities is enabled when using multithreading; not yet implemented.*/ + /** + * Whether smoothing of entities is enabled when using multithreading; not yet implemented. + */ static boolean isSmoothing(){ return threads.isEnabled() && threads.getTPS() <= Gdx.graphics.getFramesPerSecond() / 2f; } - /**Sets the position of this entity and updated the interpolator.*/ + /** + * Sets the position of this entity and updated the interpolator. + */ default void setNet(float x, float y){ set(x, y); - if(getInterpolator() != null) { + if(getInterpolator() != null){ getInterpolator().target.set(x, y); getInterpolator().last.set(x, y); getInterpolator().pos.set(0, 0); @@ -30,9 +34,12 @@ public interface SyncTrait extends Entity, TypeTrait { } } - /**Interpolate entity position only. Override if you need to interpolate rotations or other values.*/ + /** + * Interpolate entity position only. Override if you need to interpolate rotations or other values. + */ default void interpolate(){ - if(getInterpolator() == null) throw new RuntimeException("This entity must have an interpolator to interpolate()!"); + if(getInterpolator() == null) + throw new RuntimeException("This entity must have an interpolator to interpolate()!"); getInterpolator().update(); @@ -40,17 +47,22 @@ public interface SyncTrait extends Entity, TypeTrait { setY(getInterpolator().pos.y); } - /**Return the interpolator used for smoothing the position. Optional.*/ + /** + * Return the interpolator used for smoothing the position. Optional. + */ default Interpolator getInterpolator(){ return null; } - /**Whether syncing is enabled for this entity; true by default.*/ + /** + * Whether syncing is enabled for this entity; true by default. + */ default boolean isSyncing(){ return true; } //Read and write sync data, usually position void write(DataOutput data) throws IOException; + void read(DataInput data, long time) throws IOException; } diff --git a/core/src/io/anuke/mindustry/entities/traits/TargetTrait.java b/core/src/io/anuke/mindustry/entities/traits/TargetTrait.java index 488f853feb..f63cca760f 100644 --- a/core/src/io/anuke/mindustry/entities/traits/TargetTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/TargetTrait.java @@ -1,16 +1,21 @@ package io.anuke.mindustry.entities.traits; import io.anuke.mindustry.game.Team; -import io.anuke.ucore.entities.trait.VelocityTrait; import io.anuke.ucore.entities.trait.PosTrait; +import io.anuke.ucore.entities.trait.VelocityTrait; -/**Base interface for targetable entities.*/ -public interface TargetTrait extends PosTrait, VelocityTrait { +/** + * Base interface for targetable entities. + */ +public interface TargetTrait extends PosTrait, VelocityTrait{ boolean isDead(); + Team getTeam(); - /**Whether this entity is a valid target.*/ + /** + * Whether this entity is a valid target. + */ default boolean isValid(){ return !isDead(); } diff --git a/core/src/io/anuke/mindustry/entities/traits/TeamTrait.java b/core/src/io/anuke/mindustry/entities/traits/TeamTrait.java index a02c3e902c..3c7cbf7dd3 100644 --- a/core/src/io/anuke/mindustry/entities/traits/TeamTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/TeamTrait.java @@ -3,6 +3,6 @@ package io.anuke.mindustry.entities.traits; import io.anuke.mindustry.game.Team; import io.anuke.ucore.entities.trait.Entity; -public interface TeamTrait extends Entity { +public interface TeamTrait extends Entity{ Team getTeam(); } diff --git a/core/src/io/anuke/mindustry/entities/traits/TypeTrait.java b/core/src/io/anuke/mindustry/entities/traits/TypeTrait.java index 076c2d05b3..9bde9509fc 100644 --- a/core/src/io/anuke/mindustry/entities/traits/TypeTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/TypeTrait.java @@ -4,12 +4,14 @@ import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.ObjectIntMap; import io.anuke.ucore.function.Supplier; -public interface TypeTrait { +public interface TypeTrait{ int[] lastRegisteredID = {0}; Array> registeredTypes = new Array<>(); ObjectIntMap> typeToID = new ObjectIntMap<>(); - /**Register and return a type ID. The supplier should return a fresh instace of that type.*/ + /** + * Register and return a type ID. The supplier should return a fresh instace of that type. + */ static void registerType(Class type, Supplier supplier){ if(typeToID.get(type, -1) != -1){ throw new RuntimeException("Type is already registered: '" + type + "'!"); @@ -18,10 +20,12 @@ public interface TypeTrait { registeredTypes.add(supplier); int result = lastRegisteredID[0]; typeToID.put(type, result); - lastRegisteredID[0] ++; + lastRegisteredID[0]++; } - /**Registers a syncable type by ID.*/ + /** + * Registers a syncable type by ID. + */ static Supplier getTypeByID(int id){ if(id == -1){ throw new IllegalArgumentException("Attempt to retrieve invalid entity type ID! Did you forget to set it in ContentLoader.registerTypes()?"); @@ -29,11 +33,14 @@ public interface TypeTrait { return registeredTypes.get(id); } - /**Returns the type ID of this entity used for intstantiation. Should be < BYTE_MAX. - * Do not override!*/ + /** + * Returns the type ID of this entity used for intstantiation. Should be < BYTE_MAX. + * Do not override! + */ default int getTypeID(){ int id = typeToID.get(getClass(), -1); - if(id == -1) throw new RuntimeException("Class of type '" + getClass() + "' is not registered! Did you forget to register it in ContentLoader#registerTypes()?"); + if(id == -1) + throw new RuntimeException("Class of type '" + getClass() + "' is not registered! Did you forget to register it in ContentLoader#registerTypes()?"); return id; } } diff --git a/core/src/io/anuke/mindustry/entities/units/BaseUnit.java b/core/src/io/anuke/mindustry/entities/units/BaseUnit.java index c76d49cbeb..51a2e11c9a 100644 --- a/core/src/io/anuke/mindustry/entities/units/BaseUnit.java +++ b/core/src/io/anuke/mindustry/entities/units/BaseUnit.java @@ -30,7 +30,10 @@ import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Timers; import io.anuke.ucore.entities.EntityGroup; import io.anuke.ucore.graphics.Draw; -import io.anuke.ucore.util.*; +import io.anuke.ucore.util.Angles; +import io.anuke.ucore.util.Geometry; +import io.anuke.ucore.util.Mathf; +import io.anuke.ucore.util.Timer; import java.io.DataInput; import java.io.DataOutput; @@ -39,382 +42,392 @@ import java.io.IOException; import static io.anuke.mindustry.Vars.*; public abstract class BaseUnit extends Unit implements ShooterTrait{ - protected static int timerIndex = 0; + protected static int timerIndex = 0; - protected static final int timerTarget = timerIndex++; + protected static final int timerTarget = timerIndex++; - protected static final int timerShootLeft = timerIndex++; - protected static final int timerShootRight = timerIndex++; + protected static final int timerShootLeft = timerIndex++; + protected static final int timerShootRight = timerIndex++; - protected UnitType type; - protected Timer timer = new Timer(5); - protected StateMachine state = new StateMachine(); - protected TargetTrait target; + protected UnitType type; + protected Timer timer = new Timer(5); + protected StateMachine state = new StateMachine(); + protected TargetTrait target; - protected boolean isWave; - protected Squad squad; - protected int spawner; + protected boolean isWave; + protected Squad squad; + protected int spawner; - /**Initialize the type and team of this unit. Only call once!*/ - public void init(UnitType type, Team team){ - if(this.type != null) throw new RuntimeException("This unit is already initialized!"); + /** + * internal constructor used for deserialization, DO NOT USE + */ + public BaseUnit(){ + } - this.type = type; - this.team = team; - } + @Remote(called = Loc.server, in = In.entities) + public static void onUnitDeath(BaseUnit unit){ + if(unit == null) return; - public void setSpawner(Tile tile) { - this.spawner = tile.packedPosition(); - } + if(Net.server() || !Net.active()){ + UnitDrops.dropItems(unit); + } - public UnitType getType() { - return type; - } + float explosiveness = 2f + (unit.inventory.hasItem() ? unit.inventory.getItem().item.explosiveness * unit.inventory.getItem().amount : 0f); + float flammability = (unit.inventory.hasItem() ? unit.inventory.getItem().item.flammability * unit.inventory.getItem().amount : 0f); + Damage.dynamicExplosion(unit.x, unit.y, flammability, explosiveness, 0f, unit.getSize() / 2f, Palette.darkFlame); - public Tile getSpawner(){ - return world.tile(spawner); - } + unit.onSuperDeath(); - /**internal constructor used for deserialization, DO NOT USE*/ - public BaseUnit(){} + ScorchDecal.create(unit.x, unit.y); + Effects.effect(ExplosionFx.explosion, unit); + Effects.shake(2f, 2f, unit); - /**Sets this to a 'wave' unit, which means it has slightly different AI and will not run out of ammo.*/ - public void setWave(){ - isWave = true; - } + //must run afterwards so the unit's group is not null + threads.runDelay(unit::remove); + } - public void setSquad(Squad squad) { - this.squad = squad; - squad.units ++; - } + /** + * Initialize the type and team of this unit. Only call once! + */ + public void init(UnitType type, Team team){ + if(this.type != null) throw new RuntimeException("This unit is already initialized!"); - public void rotate(float angle){ - rotation = Mathf.slerpDelta(rotation, angle, type.rotatespeed); - } + this.type = type; + this.team = team; + } - public boolean targetHasFlag(BlockFlag flag){ - return target instanceof TileEntity && - ((TileEntity)target).tile.block().flags.contains(flag); - } + public UnitType getType(){ + return type; + } - public void updateRespawning(){ - if(spawner == -1) return; + public Tile getSpawner(){ + return world.tile(spawner); + } - Tile tile = world.tile(spawner); - if(tile != null && tile.entity != null){ - if(tile.entity instanceof SpawnerTrait){ - ((SpawnerTrait) tile.entity).updateSpawning(this); + public void setSpawner(Tile tile){ + this.spawner = tile.packedPosition(); + } + + /** + * Sets this to a 'wave' unit, which means it has slightly different AI and will not run out of ammo. + */ + public void setWave(){ + isWave = true; + } + + public void setSquad(Squad squad){ + this.squad = squad; + squad.units++; + } + + public void rotate(float angle){ + rotation = Mathf.slerpDelta(rotation, angle, type.rotatespeed); + } + + public boolean targetHasFlag(BlockFlag flag){ + return target instanceof TileEntity && + ((TileEntity) target).tile.block().flags.contains(flag); + } + + public void updateRespawning(){ + if(spawner == -1) return; + + Tile tile = world.tile(spawner); + if(tile != null && tile.entity != null){ + if(tile.entity instanceof SpawnerTrait){ + ((SpawnerTrait) tile.entity).updateSpawning(this); } - }else{ - spawner = -1; - } - } - - public void setState(UnitState state){ - this.state.set(state); - } - - public void retarget(Runnable run){ - if(timer.get(timerTarget, 20)){ - run.run(); - } - } - - /**Only runs when the unit has a target.*/ - public void behavior(){ - - } - - public void updateTargeting(){ - if(target == null || (target instanceof Unit && (target.isDead() || target.getTeam() == team)) - || (target instanceof TileEntity && ((TileEntity) target).tile.entity == null)){ - target = null; - } - } - public void targetClosestAllyFlag(BlockFlag flag){ - Tile target = Geometry.findClosest(x, y, world.indexer().getAllied(team, flag)); - if (target != null) this.target = target.entity; - } - - public void targetClosestEnemyFlag(BlockFlag flag){ - Tile target = Geometry.findClosest(x, y, world.indexer().getEnemy(team, flag)); - if (target != null) this.target = target.entity; - } - - public void targetClosest(){ - target = Units.getClosestTarget(team, x, y, inventory.getAmmoRange()); - } - - public TileEntity getClosestEnemyCore(){ - if(Vars.state.teams.has(team)){ - ObjectSet datas = Vars.state.teams.enemyDataOf(team); - - for(TeamData data : datas){ - Tile tile = Geometry.findClosest(x, y, data.cores); - if(tile != null){ - return tile.entity; - } - } - } - return null; - } - - public UnitState getStartState(){ - return null; - } - - protected void drawItems(){ - float backTrns = 4f, itemSize = 5f; - if(inventory.hasItem()){ - ItemStack stack = inventory.getItem(); - int stored = Mathf.clamp(stack.amount / 6, 1, 8); - - for(int i = 0; i < stored; i ++) { - float angT = i == 0 ? 0 : Mathf.randomSeedRange(i + 2, 60f); - float lenT = i == 0 ? 0 : Mathf.randomSeedRange(i + 3, 1f) - 1f; - Draw.rect(stack.item.region, - x + Angles.trnsx(rotation + 180f + angT, backTrns + lenT), - y + Angles.trnsy(rotation + 180f + angT, backTrns + lenT), - itemSize, itemSize, rotation); - } - } - } - - @Override - public boolean isValid() { - return super.isValid() && isAdded(); - } - - @Override - public Timer getTimer() { - return timer; - } - - @Override - public int getShootTimer(boolean left) { - return left ? timerShootLeft : timerShootRight; - } - - @Override - public Weapon getWeapon() { - return type.weapon; - } - - @Override - public TextureRegion getIconRegion() { - return type.iconRegion; - } - - @Override - public int getItemCapacity() { - return type.itemCapacity; - } - - @Override - public int getAmmoCapacity() { - return type.ammoCapacity; - } - - @Override - public boolean isInfiniteAmmo() { - return isWave; - } - - @Override - public void interpolate() { - super.interpolate(); - - if(interpolator.values.length > 0){ - rotation = interpolator.values[0]; - } - } - - @Override - public float maxHealth() { - return type.health; - } - - @Override - public float getArmor() { - return type.armor; - } - - @Override - public boolean acceptsAmmo(Item item) { - return getWeapon().getAmmoType(item) != null && inventory.canAcceptAmmo(getWeapon().getAmmoType(item)); - } - - @Override - public void addAmmo(Item item) { - inventory.addAmmo(getWeapon().getAmmoType(item)); - } - - @Override - public float getSize() { - return 8; - } - - @Override - public float getMass() { - return type.mass; - } - - @Override - public boolean isFlying() { - return type.isFlying; - } - - @Override - public void update(){ - if(hitTime > 0){ - hitTime -= Timers.delta(); - } - - if(hitTime < 0) hitTime = 0; - - if(isDead()){ - updateRespawning(); - return; - } - - if(Net.client()){ - interpolate(); - status.update(this); - return; - } - - if(!Net.client()){ - avoidOthers(8f); - } - - if(squad != null){ - squad.update(); - } - - updateTargeting(); - - state.update(); - updateVelocityStatus(type.drag, type.maxVelocity); - - if(target != null) behavior(); - - if(!isWave) { - x = Mathf.clamp(x, 0, world.width() * tilesize); - y = Mathf.clamp(y, 0, world.height() * tilesize); - } - } - - @Override - public void draw(){ - - } - - @Override - public void drawUnder(){ - - } - - @Override - public void drawOver(){ - - } - - @Override - public void removed() { - Tile tile = world.tile(spawner); - - if(tile != null && tile.entity instanceof UnitFactoryEntity){ - UnitFactoryEntity factory = (UnitFactoryEntity)tile.entity; - factory.hasSpawned = false; - } - - spawner = -1; - } - - @Override - public float drawSize(){ - return 14; - } - - @Override - public void onDeath(){ - CallEntity.onUnitDeath(this); - } - - @Override - public void added(){ - hitbox.setSize(type.hitsize); - hitboxTile.setSize(type.hitsizeTile); - state.set(getStartState()); - - health(maxHealth()); - } - - @Override - public EntityGroup targetGroup() { - return unitGroups[team.ordinal()]; - } - - @Override - public void writeSave(DataOutput stream) throws IOException { - super.writeSave(stream); - stream.writeByte(type.id); - stream.writeBoolean(isWave); - stream.writeInt(spawner); - } - - @Override - public void readSave(DataInput stream) throws IOException { - super.readSave(stream); - byte type = stream.readByte(); - this.isWave = stream.readBoolean(); - this.spawner = stream.readInt(); - - this.type = UnitType.getByID(type); - add(); - } - - @Override - public void write(DataOutput data) throws IOException{ - super.writeSave(data); - data.writeByte(type.id); - data.writeInt(spawner); - } - - @Override - public void read(DataInput data, long time) throws IOException{ - float lastx = x, lasty = y, lastrot = rotation; - super.readSave(data); - this.type = UnitType.getByID(data.readByte()); - this.spawner = data.readInt(); - - interpolator.read(lastx, lasty, x, y, time, rotation); - rotation = lastrot; - } - - public void onSuperDeath(){ - super.onDeath(); - } - - @Remote(called = Loc.server, in = In.entities) - public static void onUnitDeath(BaseUnit unit){ - if(unit == null) return; - - if(Net.server() || !Net.active()){ - UnitDrops.dropItems(unit); - } - - float explosiveness = 2f + (unit.inventory.hasItem() ? unit.inventory.getItem().item.explosiveness * unit.inventory.getItem().amount : 0f); - float flammability = (unit.inventory.hasItem() ? unit.inventory.getItem().item.flammability * unit.inventory.getItem().amount : 0f); - Damage.dynamicExplosion(unit.x, unit.y, flammability, explosiveness, 0f, unit.getSize()/2f, Palette.darkFlame); - - unit.onSuperDeath(); - - ScorchDecal.create(unit.x, unit.y); - Effects.effect(ExplosionFx.explosion, unit); - Effects.shake(2f, 2f, unit); - - //must run afterwards so the unit's group is not null - threads.runDelay(unit::remove); - } + }else{ + spawner = -1; + } + } + + public void setState(UnitState state){ + this.state.set(state); + } + + public void retarget(Runnable run){ + if(timer.get(timerTarget, 20)){ + run.run(); + } + } + + /** + * Only runs when the unit has a target. + */ + public void behavior(){ + + } + + public void updateTargeting(){ + if(target == null || (target instanceof Unit && (target.isDead() || target.getTeam() == team)) + || (target instanceof TileEntity && ((TileEntity) target).tile.entity == null)){ + target = null; + } + } + + public void targetClosestAllyFlag(BlockFlag flag){ + Tile target = Geometry.findClosest(x, y, world.indexer().getAllied(team, flag)); + if(target != null) this.target = target.entity; + } + + public void targetClosestEnemyFlag(BlockFlag flag){ + Tile target = Geometry.findClosest(x, y, world.indexer().getEnemy(team, flag)); + if(target != null) this.target = target.entity; + } + + public void targetClosest(){ + target = Units.getClosestTarget(team, x, y, inventory.getAmmoRange()); + } + + public TileEntity getClosestEnemyCore(){ + if(Vars.state.teams.has(team)){ + ObjectSet datas = Vars.state.teams.enemyDataOf(team); + + for(TeamData data : datas){ + Tile tile = Geometry.findClosest(x, y, data.cores); + if(tile != null){ + return tile.entity; + } + } + } + return null; + } + + public UnitState getStartState(){ + return null; + } + + protected void drawItems(){ + float backTrns = 4f, itemSize = 5f; + if(inventory.hasItem()){ + ItemStack stack = inventory.getItem(); + int stored = Mathf.clamp(stack.amount / 6, 1, 8); + + for(int i = 0; i < stored; i++){ + float angT = i == 0 ? 0 : Mathf.randomSeedRange(i + 2, 60f); + float lenT = i == 0 ? 0 : Mathf.randomSeedRange(i + 3, 1f) - 1f; + Draw.rect(stack.item.region, + x + Angles.trnsx(rotation + 180f + angT, backTrns + lenT), + y + Angles.trnsy(rotation + 180f + angT, backTrns + lenT), + itemSize, itemSize, rotation); + } + } + } + + @Override + public boolean isValid(){ + return super.isValid() && isAdded(); + } + + @Override + public Timer getTimer(){ + return timer; + } + + @Override + public int getShootTimer(boolean left){ + return left ? timerShootLeft : timerShootRight; + } + + @Override + public Weapon getWeapon(){ + return type.weapon; + } + + @Override + public TextureRegion getIconRegion(){ + return type.iconRegion; + } + + @Override + public int getItemCapacity(){ + return type.itemCapacity; + } + + @Override + public int getAmmoCapacity(){ + return type.ammoCapacity; + } + + @Override + public boolean isInfiniteAmmo(){ + return isWave; + } + + @Override + public void interpolate(){ + super.interpolate(); + + if(interpolator.values.length > 0){ + rotation = interpolator.values[0]; + } + } + + @Override + public float maxHealth(){ + return type.health; + } + + @Override + public float getArmor(){ + return type.armor; + } + + @Override + public boolean acceptsAmmo(Item item){ + return getWeapon().getAmmoType(item) != null && inventory.canAcceptAmmo(getWeapon().getAmmoType(item)); + } + + @Override + public void addAmmo(Item item){ + inventory.addAmmo(getWeapon().getAmmoType(item)); + } + + @Override + public float getSize(){ + return 8; + } + + @Override + public float getMass(){ + return type.mass; + } + + @Override + public boolean isFlying(){ + return type.isFlying; + } + + @Override + public void update(){ + if(hitTime > 0){ + hitTime -= Timers.delta(); + } + + if(hitTime < 0) hitTime = 0; + + if(isDead()){ + updateRespawning(); + return; + } + + if(Net.client()){ + interpolate(); + status.update(this); + return; + } + + if(!Net.client()){ + avoidOthers(8f); + } + + if(squad != null){ + squad.update(); + } + + updateTargeting(); + + state.update(); + updateVelocityStatus(type.drag, type.maxVelocity); + + if(target != null) behavior(); + + if(!isWave){ + x = Mathf.clamp(x, 0, world.width() * tilesize); + y = Mathf.clamp(y, 0, world.height() * tilesize); + } + } + + @Override + public void draw(){ + + } + + @Override + public void drawUnder(){ + + } + + @Override + public void drawOver(){ + + } + + @Override + public void removed(){ + Tile tile = world.tile(spawner); + + if(tile != null && tile.entity instanceof UnitFactoryEntity){ + UnitFactoryEntity factory = (UnitFactoryEntity) tile.entity; + factory.hasSpawned = false; + } + + spawner = -1; + } + + @Override + public float drawSize(){ + return 14; + } + + @Override + public void onDeath(){ + CallEntity.onUnitDeath(this); + } + + @Override + public void added(){ + hitbox.setSize(type.hitsize); + hitboxTile.setSize(type.hitsizeTile); + state.set(getStartState()); + + health(maxHealth()); + } + + @Override + public EntityGroup targetGroup(){ + return unitGroups[team.ordinal()]; + } + + @Override + public void writeSave(DataOutput stream) throws IOException{ + super.writeSave(stream); + stream.writeByte(type.id); + stream.writeBoolean(isWave); + stream.writeInt(spawner); + } + + @Override + public void readSave(DataInput stream) throws IOException{ + super.readSave(stream); + byte type = stream.readByte(); + this.isWave = stream.readBoolean(); + this.spawner = stream.readInt(); + + this.type = UnitType.getByID(type); + add(); + } + + @Override + public void write(DataOutput data) throws IOException{ + super.writeSave(data); + data.writeByte(type.id); + data.writeInt(spawner); + } + + @Override + public void read(DataInput data, long time) throws IOException{ + float lastx = x, lasty = y, lastrot = rotation; + super.readSave(data); + this.type = UnitType.getByID(data.readByte()); + this.spawner = data.readInt(); + + interpolator.read(lastx, lasty, x, y, time, rotation); + rotation = lastrot; + } + + public void onSuperDeath(){ + super.onDeath(); + } } diff --git a/core/src/io/anuke/mindustry/entities/units/FlyingUnit.java b/core/src/io/anuke/mindustry/entities/units/FlyingUnit.java index b4353ca108..cdcdbf4717 100644 --- a/core/src/io/anuke/mindustry/entities/units/FlyingUnit.java +++ b/core/src/io/anuke/mindustry/entities/units/FlyingUnit.java @@ -23,7 +23,96 @@ import static io.anuke.mindustry.Vars.world; public abstract class FlyingUnit extends BaseUnit implements CarryTrait{ protected static Translator vec = new Translator(); protected static float wobblyness = 0.6f; + public final UnitState + resupply = new UnitState(){ + public void entered(){ + target = null; + } + + public void update(){ + if(inventory.totalAmmo() + 10 >= inventory.ammoCapacity()){ + state.set(attack); + }else if(!targetHasFlag(BlockFlag.resupplyPoint)){ + retarget(() -> targetClosestAllyFlag(BlockFlag.resupplyPoint)); + }else{ + circle(20f); + } + } + }, + idle = new UnitState(){ + public void update(){ + retarget(() -> { + targetClosest(); + targetClosestEnemyFlag(BlockFlag.target); + + if(target != null){ + setState(attack); + } + }); + + target = getClosestCore(); + if(target != null){ + circle(50f); + } + velocity.scl(0.8f); + } + }, + attack = new UnitState(){ + public void entered(){ + target = null; + } + + public void update(){ + if(Units.invalidateTarget(target, team, x, y)){ + target = null; + } + + if(!inventory.hasAmmo()){ + state.set(resupply); + }else if(target == null){ + retarget(() -> { + targetClosest(); + targetClosestEnemyFlag(BlockFlag.target); + targetClosestEnemyFlag(BlockFlag.producer); + + if(target == null){ + setState(idle); + } + }); + }else{ + attack(150f); + + if((Mathf.angNear(angleTo(target), rotation, 15f) || !inventory.getAmmo().bullet.keepVelocity) //bombers don't care about rotation + && distanceTo(target) < inventory.getAmmo().getRange()){ + AmmoType ammo = inventory.getAmmo(); + inventory.useAmmo(); + + Vector2 to = Predict.intercept(FlyingUnit.this, target, ammo.bullet.speed); + + getWeapon().update(FlyingUnit.this, to.x, to.y); + } + } + } + }, + retreat = new UnitState(){ + public void entered(){ + target = null; + } + + public void update(){ + if(health >= maxHealth()){ + state.set(attack); + }else if(!targetHasFlag(BlockFlag.repair)){ + retarget(() -> { + Tile target = Geometry.findClosest(x, y, world.indexer().getAllied(team, BlockFlag.repair)); + if(target != null) FlyingUnit.this.target = target.entity; + }); + }else{ + circle(20f); + } + } + }; protected Trail trail = new Trail(8); protected CarriableTrait carrying; @@ -34,26 +123,26 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{ @Override public void drawShadow(){ - Draw.rect(type.region, x + elevation*elevationScale, y - elevation*elevationScale, rotation - 90); + Draw.rect(type.region, x + elevation * elevationScale, y - elevation * elevationScale, rotation - 90); } @Override - public CarriableTrait getCarry() { + public CarriableTrait getCarry(){ return carrying; } @Override - public void setCarry(CarriableTrait unit) { + public void setCarry(CarriableTrait unit){ this.carrying = unit; } @Override - public float getCarryWeight() { + public float getCarryWeight(){ return type.carryWeight; } @Override - public void update() { + public void update(){ super.update(); updateRotation(); @@ -64,7 +153,7 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{ } @Override - public void draw() { + public void draw(){ Draw.alpha(hitTime / hitDuration); Draw.rect(type.name, x, y, rotation - 90); @@ -75,12 +164,12 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{ } @Override - public void drawOver() { + public void drawOver(){ trail.draw(Palette.lightTrail, 5f); } @Override - public void behavior() { + public void behavior(){ if(health <= health * type.retreatPercent && !isWave && Geometry.findClosest(x, y, world.indexer().getAllied(team, BlockFlag.repair)) != null){ setState(retreat); @@ -98,7 +187,7 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{ } @Override - public float drawSize() { + public float drawSize(){ return 60; } @@ -108,7 +197,7 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{ x += Mathf.sin(Timers.time() + id * 999, 25f, 0.07f); y += Mathf.cos(Timers.time() + id * 999, 25f, 0.07f); - if (velocity.len() <= 0.2f) { + if(velocity.len() <= 0.2f){ rotation += Mathf.sin(Timers.time() + id * 99, 10f, 8f); } } @@ -127,7 +216,7 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{ vec.set(target.getX() - x, target.getY() - y); if(vec.len() < circleLength){ - vec.rotate((circleLength-vec.len())/circleLength * 180f); + vec.rotate((circleLength - vec.len()) / circleLength * 180f); } vec.setLength(speed * Timers.delta()); @@ -140,7 +229,7 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{ vec.set(target.getX() - x, target.getY() - y); - float length = Mathf.clamp((distanceTo(target) - circleLength)/100f, -1f, 1f); + float length = Mathf.clamp((distanceTo(target) - circleLength) / 100f, -1f, 1f); vec.setLength(type.speed * Timers.delta() * length); if(length < 0) vec.rotate(180f); @@ -157,102 +246,11 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{ if(diff > 100f && vec.len() < circleLength){ vec.setAngle(velocity.angle()); }else{ - vec.setAngle(Mathf.slerpDelta(velocity.angle(), vec.angle(), 0.44f)); + vec.setAngle(Mathf.slerpDelta(velocity.angle(), vec.angle(), 0.44f)); } - vec.setLength(type.speed*Timers.delta()); + vec.setLength(type.speed * Timers.delta()); velocity.add(vec); } - - public final UnitState - - resupply = new UnitState(){ - public void entered() { - target = null; - } - - public void update() { - if(inventory.totalAmmo() + 10 >= inventory.ammoCapacity()){ - state.set(attack); - }else if(!targetHasFlag(BlockFlag.resupplyPoint)){ - retarget(() -> targetClosestAllyFlag(BlockFlag.resupplyPoint)); - }else{ - circle(20f); - } - } - }, - idle = new UnitState() { - public void update() { - retarget(() -> { - targetClosest(); - targetClosestEnemyFlag(BlockFlag.target); - - if(target != null){ - setState(attack); - } - }); - - target = getClosestCore(); - if(target != null){ - circle(50f); - } - velocity.scl(0.8f); - } - }, - attack = new UnitState(){ - public void entered() { - target = null; - } - - public void update() { - if(Units.invalidateTarget(target, team, x, y)){ - target = null; - } - - if(!inventory.hasAmmo()) { - state.set(resupply); - }else if (target == null){ - retarget(() -> { - targetClosest(); - targetClosestEnemyFlag(BlockFlag.target); - targetClosestEnemyFlag(BlockFlag.producer); - - if(target == null){ - setState(idle); - } - }); - }else{ - attack(150f); - - if ((Mathf.angNear(angleTo(target), rotation, 15f) || !inventory.getAmmo().bullet.keepVelocity) //bombers don't care about rotation - && distanceTo(target) < inventory.getAmmo().getRange()) { - AmmoType ammo = inventory.getAmmo(); - inventory.useAmmo(); - - Vector2 to = Predict.intercept(FlyingUnit.this, target, ammo.bullet.speed); - - getWeapon().update(FlyingUnit.this, to.x, to.y); - } - } - } - }, - retreat = new UnitState() { - public void entered() { - target = null; - } - - public void update() { - if(health >= maxHealth()){ - state.set(attack); - }else if(!targetHasFlag(BlockFlag.repair)){ - retarget(() -> { - Tile target = Geometry.findClosest(x, y, world.indexer().getAllied(team, BlockFlag.repair)); - if (target != null) FlyingUnit.this.target = target.entity; - }); - }else{ - circle(20f); - } - } - }; } diff --git a/core/src/io/anuke/mindustry/entities/units/GroundUnit.java b/core/src/io/anuke/mindustry/entities/units/GroundUnit.java index 0ce352809f..5dba19a82d 100644 --- a/core/src/io/anuke/mindustry/entities/units/GroundUnit.java +++ b/core/src/io/anuke/mindustry/entities/units/GroundUnit.java @@ -26,24 +26,101 @@ import java.io.IOException; import static io.anuke.mindustry.Vars.world; -public abstract class GroundUnit extends BaseUnit { +public abstract class GroundUnit extends BaseUnit{ protected static Translator vec = new Translator(); protected float walkTime; protected float baseRotation; + public final UnitState + + resupply = new UnitState(){ + public void entered(){ + target = null; + } + + public void update(){ + Tile tile = Geometry.findClosest(x, y, world.indexer().getAllied(team, BlockFlag.resupplyPoint)); + + if(tile != null && distanceTo(tile) > 40){ + moveAwayFromCore(); + } + + //TODO move toward resupply point + if(isWave || inventory.totalAmmo() + 10 >= inventory.ammoCapacity()){ + state.set(attack); + } + } + }, + attack = new UnitState(){ + public void entered(){ + target = null; + } + + public void update(){ + TileEntity core = getClosestEnemyCore(); + float dst = core == null ? 0 : distanceTo(core); + + if(core != null && inventory.hasAmmo() && dst < inventory.getAmmo().getRange() / 1.1f){ + target = core; + }else{ + retarget(() -> targetClosest()); + } + + if(!inventory.hasAmmo()){ + state.set(resupply); + }else if(target != null){ + if(core != null){ + if(dst > inventory.getAmmo().getRange() * 0.5f){ + moveToCore(); + } + + }else{ + moveToCore(); + } + + if(distanceTo(target) < inventory.getAmmo().getRange()){ + rotate(angleTo(target)); + + if(Mathf.angNear(angleTo(target), rotation, 13f)){ + AmmoType ammo = inventory.getAmmo(); + + Vector2 to = Predict.intercept(GroundUnit.this, target, ammo.bullet.speed); + + getWeapon().update(GroundUnit.this, to.x, to.y); + } + } + + }else{ + moveToCore(); + } + } + }, + retreat = new UnitState(){ + public void entered(){ + target = null; + } + + public void update(){ + if(health >= health){ + state.set(attack); + } + + moveAwayFromCore(); + } + }; protected Weapon weapon; @Override - public void init(UnitType type, Team team) { + public void init(UnitType type, Team team){ super.init(type, team); this.weapon = type.weapon; } @Override - public void interpolate() { + public void interpolate(){ super.interpolate(); - if(interpolator.values.length > 1) { + if(interpolator.values.length > 1){ baseRotation = interpolator.values[1]; } } @@ -57,12 +134,12 @@ public abstract class GroundUnit extends BaseUnit { } @Override - public UnitState getStartState() { + public UnitState getStartState(){ return resupply; } @Override - public void update() { + public void update(){ super.update(); if(!velocity.isZero(0.0001f) && (target == null || !inventory.hasAmmo() || (inventory.hasAmmo() && distanceTo(target) > inventory.getAmmoRange()))){ @@ -71,12 +148,16 @@ public abstract class GroundUnit extends BaseUnit { } @Override - public Weapon getWeapon() { + public Weapon getWeapon(){ return weapon; } + public void setWeapon(Weapon weapon){ + this.weapon = weapon; + } + @Override - public void draw() { + public void draw(){ Draw.alpha(hitTime / hitDuration); float walktime = walkTime; @@ -89,25 +170,25 @@ public abstract class GroundUnit extends BaseUnit { Draw.tint(Color.WHITE, floor.liquidColor, 0.5f); } - for (int i : Mathf.signs) { + for(int i : Mathf.signs){ Draw.rect(type.legRegion, x + Angles.trnsx(baseRotation, ft * i), y + Angles.trnsy(baseRotation, ft * i), 12f * i, 12f - Mathf.clamp(ft * i, 0, 2), baseRotation - 90); } - if(floor.isLiquid) { + if(floor.isLiquid){ Draw.tint(Color.WHITE, floor.liquidColor, drownTime * 0.4f); - }else { + }else{ Draw.tint(Color.WHITE); } - Draw.rect(type.baseRegion, x, y, baseRotation- 90); + Draw.rect(type.baseRegion, x, y, baseRotation - 90); - Draw.rect(type.region, x, y, rotation -90); + Draw.rect(type.region, x, y, rotation - 90); - for (int i : Mathf.signs) { - float tra = rotation - 90, trY = - weapon.getRecoil(this, i > 0) + type.weaponOffsetY; + for(int i : Mathf.signs){ + float tra = rotation - 90, trY = -weapon.getRecoil(this, i > 0) + type.weaponOffsetY; float w = i > 0 ? -12 : 12; Draw.rect(weapon.equipRegion, x + Angles.trnsx(tra, type.weaponOffsetX * i, trY), @@ -120,35 +201,35 @@ public abstract class GroundUnit extends BaseUnit { } @Override - public void behavior() { + public void behavior(){ if(health <= health * type.retreatPercent && !isWave){ setState(retreat); } } @Override - public void updateTargeting() { + public void updateTargeting(){ super.updateTargeting(); - if(Units.invalidateTarget(target, team, x, y, Float.MAX_VALUE)){ + if(Units.invalidateTarget(target, team, x, y, Float.MAX_VALUE)){ target = null; } } @Override - public void write(DataOutput data) throws IOException { + public void write(DataOutput data) throws IOException{ super.write(data); data.writeByte(weapon.id); } @Override - public void read(DataInput data, long time) throws IOException { + public void read(DataInput data, long time) throws IOException{ super.read(data, time); weapon = Upgrade.getByID(data.readByte()); } @Override - public void writeSave(DataOutput stream) throws IOException { + public void writeSave(DataOutput stream) throws IOException{ stream.writeByte(weapon.id); super.writeSave(stream); } @@ -159,10 +240,6 @@ public abstract class GroundUnit extends BaseUnit { super.readSave(stream); } - public void setWeapon(Weapon weapon){ - this.weapon = weapon; - } - protected void moveToCore(){ Tile tile = world.tileWorld(x, y); if(tile == null) return; @@ -189,82 +266,4 @@ public abstract class GroundUnit extends BaseUnit { walkTime += Timers.delta(); velocity.add(vec); } - - public final UnitState - - resupply = new UnitState(){ - public void entered() { - target = null; - } - - public void update() { - Tile tile = Geometry.findClosest(x, y, world.indexer().getAllied(team, BlockFlag.resupplyPoint)); - - if (tile != null && distanceTo(tile) > 40) { - moveAwayFromCore(); - } - - //TODO move toward resupply point - if(isWave || inventory.totalAmmo() + 10 >= inventory.ammoCapacity()){ - state.set(attack); - } - } - }, - attack = new UnitState(){ - public void entered() { - target = null; - } - - public void update() { - TileEntity core = getClosestEnemyCore(); - float dst = core == null ? 0 :distanceTo(core); - - if(core != null && inventory.hasAmmo() && dst < inventory.getAmmo().getRange()/1.1f){ - target = core; - }else { - retarget(() -> targetClosest()); - } - - if(!inventory.hasAmmo()) { - state.set(resupply); - }else if(target != null){ - if(core != null){ - if(dst > inventory.getAmmo().getRange() * 0.5f){ - moveToCore(); - } - - }else{ - moveToCore(); - } - - if(distanceTo(target) < inventory.getAmmo().getRange()){ - rotate(angleTo(target)); - - if (Mathf.angNear(angleTo(target), rotation, 13f)) { - AmmoType ammo = inventory.getAmmo(); - - Vector2 to = Predict.intercept(GroundUnit.this, target, ammo.bullet.speed); - - getWeapon().update(GroundUnit.this, to.x, to.y); - } - } - - }else{ - moveToCore(); - } - } - }, - retreat = new UnitState() { - public void entered() { - target = null; - } - - public void update() { - if(health >= health){ - state.set(attack); - } - - moveAwayFromCore(); - } - }; } diff --git a/core/src/io/anuke/mindustry/entities/units/Squad.java b/core/src/io/anuke/mindustry/entities/units/Squad.java index 41ad5f9d58..1068de0a6b 100644 --- a/core/src/io/anuke/mindustry/entities/units/Squad.java +++ b/core/src/io/anuke/mindustry/entities/units/Squad.java @@ -5,9 +5,11 @@ import io.anuke.ucore.util.Translator; import static io.anuke.mindustry.Vars.threads; -/**Used to group entities together, for formations and such. - * Usually, squads are used by units spawned in the same wave.*/ -public class Squad { +/** + * Used to group entities together, for formations and such. + * Usually, squads are used by units spawned in the same wave. + */ +public class Squad{ public Vector2 direction = new Translator(); public int units; diff --git a/core/src/io/anuke/mindustry/entities/units/StateMachine.java b/core/src/io/anuke/mindustry/entities/units/StateMachine.java index 082f7d114f..a676716693 100644 --- a/core/src/io/anuke/mindustry/entities/units/StateMachine.java +++ b/core/src/io/anuke/mindustry/entities/units/StateMachine.java @@ -1,13 +1,13 @@ package io.anuke.mindustry.entities.units; -public class StateMachine { +public class StateMachine{ private UnitState state; public void update(){ if(state != null) state.update(); } - public void set( UnitState next){ + public void set(UnitState next){ if(next == state) return; if(state != null) state.exited(); this.state = next; diff --git a/core/src/io/anuke/mindustry/entities/units/UnitDrops.java b/core/src/io/anuke/mindustry/entities/units/UnitDrops.java index c931cd875c..2ba240de70 100644 --- a/core/src/io/anuke/mindustry/entities/units/UnitDrops.java +++ b/core/src/io/anuke/mindustry/entities/units/UnitDrops.java @@ -6,7 +6,7 @@ import io.anuke.mindustry.entities.effect.ItemDrop; import io.anuke.mindustry.type.Item; import io.anuke.ucore.util.Mathf; -public class UnitDrops { +public class UnitDrops{ private static final int maxItems = 200; private static Item[] dropTable; @@ -19,7 +19,7 @@ public class UnitDrops { dropTable = new Item[]{Items.tungsten, Items.lead, Items.carbide}; } - for (int i = 0; i < 3; i++) { + for(int i = 0; i < 3; i++){ for(Item item : dropTable){ if(Mathf.chance(0.03)){ int amount = Mathf.random(20, 40); diff --git a/core/src/io/anuke/mindustry/entities/units/UnitState.java b/core/src/io/anuke/mindustry/entities/units/UnitState.java index c11ce3aa8b..5c5f9c64a8 100644 --- a/core/src/io/anuke/mindustry/entities/units/UnitState.java +++ b/core/src/io/anuke/mindustry/entities/units/UnitState.java @@ -1,7 +1,12 @@ package io.anuke.mindustry.entities.units; -public interface UnitState { - default void entered(){} - default void exited(){} - default void update(){} +public interface UnitState{ + default void entered(){ + } + + default void exited(){ + } + + default void update(){ + } } diff --git a/core/src/io/anuke/mindustry/entities/units/UnitType.java b/core/src/io/anuke/mindustry/entities/units/UnitType.java index d03396120b..848ef6d372 100644 --- a/core/src/io/anuke/mindustry/entities/units/UnitType.java +++ b/core/src/io/anuke/mindustry/entities/units/UnitType.java @@ -18,12 +18,9 @@ import io.anuke.ucore.util.Bundles; public class UnitType implements UnlockableContent{ private static byte lastid = 0; private static Array types = new Array<>(); - - protected final Supplier constructor; - public final String name; public final byte id; - + protected final Supplier constructor; public float health = 60; public float hitsize = 5f; public float hitsizeTile = 4f; @@ -57,44 +54,52 @@ public class UnitType implements UnlockableContent{ TypeTrait.registerType(type, mainConstructor); } + public static UnitType getByID(byte id){ + return types.get(id); + } + + public static Array all(){ + return types; + } + @Override - public void displayInfo(Table table) { + public void displayInfo(Table table){ ContentDisplay.displayUnit(table, this); } @Override - public String localizedName() { + public String localizedName(){ return Bundles.get("unit." + name + ".name"); } @Override - public TextureRegion getContentIcon() { + public TextureRegion getContentIcon(){ return iconRegion; } @Override - public void load() { + public void load(){ iconRegion = Draw.region("unit-icon-" + name); region = Draw.region(name); - if(!isFlying) { + if(!isFlying){ legRegion = Draw.region(name + "-leg"); baseRegion = Draw.region(name + "-base"); } } @Override - public String getContentTypeName() { + public String getContentTypeName(){ return "unit-type"; } @Override - public String getContentName() { + public String getContentName(){ return name; } @Override - public Array getAll() { + public Array getAll(){ return types; } @@ -103,12 +108,4 @@ public class UnitType implements UnlockableContent{ unit.init(this, team); return unit; } - - public static UnitType getByID(byte id){ - return types.get(id); - } - - public static Array all(){ - return types; - } } diff --git a/core/src/io/anuke/mindustry/entities/units/types/Drone.java b/core/src/io/anuke/mindustry/entities/units/types/Drone.java index ac004b943f..3cf689b327 100644 --- a/core/src/io/anuke/mindustry/entities/units/types/Drone.java +++ b/core/src/io/anuke/mindustry/entities/units/types/Drone.java @@ -39,7 +39,7 @@ import java.io.IOException; import static io.anuke.mindustry.Vars.*; -public class Drone extends FlyingUnit implements BuilderTrait { +public class Drone extends FlyingUnit implements BuilderTrait{ protected static ObjectSet toMine; protected static float discoverRange = 120f; protected static boolean initialized; @@ -47,195 +47,17 @@ public class Drone extends FlyingUnit implements BuilderTrait { protected Item targetItem; protected Tile mineTile; protected Queue placeQueue = new ThreadQueue<>(); - - /**Initialize placement event notifier system. - * Static initialization is to be avoided, thus, this is done lazily.*/ - private static void initEvents(){ - if(initialized) return; - - toMine = ObjectSet.with(Items.lead, Items.tungsten); - - Events.on(BlockBuildEvent.class, (team, tile) -> { - EntityGroup group = unitGroups[team.ordinal()]; - - if(!(tile.entity instanceof BuildEntity)) return; - BuildEntity entity = tile.entity(); - - for(BaseUnit unit : group.all()){ - if(unit instanceof Drone){ - ((Drone) unit).notifyPlaced(entity); - } - } - }); - - initialized = true; - } - - { - initEvents(); - } - - private void notifyPlaced(BuildEntity entity){ - float timeToBuild = entity.recipe.cost; - float dist = Math.min(entity.distanceTo(x, y) - placeDistance, 0); - - if(dist / type.maxVelocity < timeToBuild * 0.9f){ - //CallEntity.onDroneBeginBuild(this, entity.tile, entity.recipe); - target = entity; - setState(build); - } - } - - @Override - public float getBuildPower(Tile tile) { - return type.buildPower; - } - - @Override - public float getMinePower() { - return type.minePower; - } - - @Override - public Queue getPlaceQueue() { - return placeQueue; - } - - @Override - public Tile getMineTile() { - return mineTile; - } - - @Override - public void setMineTile(Tile tile) { - mineTile = tile; - } - - @Override - public void update() { - super.update(); - - x += Mathf.sin(Timers.time() + id * 999, 25f, 0.07f); - y += Mathf.cos(Timers.time() + id * 999, 25f, 0.07f); - - updateBuilding(this); - } - - @Override - protected void updateRotation() { - if(target != null && (state.is(repair) || state.is(mine))){ - rotation = Mathf.slerpDelta(rotation, angleTo(target), 0.3f); - }else{ - rotation = Mathf.slerpDelta(rotation, velocity.angle(), 0.3f); - } - - if(velocity.len() <= 0.2f && !(state.is(repair) && target != null)){ - rotation += Mathf.sin(Timers.time() + id * 99, 10f, 5f); - } - } - - @Override - public void behavior() { - if(health <= health * type.retreatPercent && - Geometry.findClosest(x, y, world.indexer().getAllied(team, BlockFlag.repair)) != null){ - setState(retreat); - } - } - - @Override - public UnitState getStartState() { - return repair; - } - - @Override - public void drawOver() { - trail.draw(Palette.lightTrail, 3f); - - TargetTrait entity = target; - - if(entity instanceof TileEntity && state.is(repair)){ - float len = 5f; - Draw.color(Color.BLACK, Color.WHITE, 0.95f + Mathf.absin(Timers.time(), 0.8f, 0.05f)); - Shapes.laser("beam", "beam-end", - x + Angles.trnsx(rotation, len), - y + Angles.trnsy(rotation, len), - entity.getX(), entity.getY()); - Draw.color(); - } - - drawBuilding(this); - } - - @Override - public float drawSize() { - return isBuilding() ? placeDistance*2f : 30f; - } - - @Override - public float getAmmoFraction() { - return inventory.getItem().amount / (float)type.itemCapacity; - } - - protected void findItem(){ - TileEntity entity = getClosestCore(); - if(entity == null){ - return; - } - targetItem = Mathf.findMin(toMine, (a, b) -> -Integer.compare(entity.items.get(a), entity.items.get(b))); - } - - protected boolean findItemDrop(){ - TileEntity core = getClosestCore(); - - if(core == null) return false; - - //find nearby dropped items to pick up if applicable - ItemDrop drop = EntityPhysics.getClosest(itemGroup, x, y, 60f, - item -> core.tile.block().acceptStack(item.getItem(), item.getAmount(), core.tile, Drone.this) == item.getAmount() && - inventory.canAcceptItem(item.getItem(), 1)); - if(drop != null){ - setState(pickup); - target = drop; - return true; - } - return false; - } - - @Override - public boolean canCreateBlocks() { - return false; - } - - @Override - public void write(DataOutput data) throws IOException { - super.write(data); - data.writeInt(mineTile == null ? -1 : mineTile.packedPosition()); - writeBuilding(data); - } - - @Override - public void read(DataInput data, long time) throws IOException { - super.read(data, time); - int mined = data.readInt(); - - readBuilding(data); - - if(mined != -1){ - mineTile = world.tile(mined); - } - } - public final UnitState - build = new UnitState(){ - public void entered() { + build = new UnitState(){ + public void entered(){ if(!(target instanceof BuildEntity)){ target = null; } } - public void update() { - BuildEntity entity = (BuildEntity)target; + public void update(){ + BuildEntity entity = (BuildEntity) target; TileEntity core = getClosestCore(); if(entity == null){ @@ -268,17 +90,17 @@ public class Drone extends FlyingUnit implements BuilderTrait { }, repair = new UnitState(){ - public void entered() { + public void entered(){ target = null; } - public void update() { - if(target != null && (((TileEntity)target).health >= ((TileEntity)target).tile.block().health + public void update(){ + if(target != null && (((TileEntity) target).health >= ((TileEntity) target).tile.block().health || target.distanceTo(Drone.this) > discoverRange)){ target = null; } - if (target == null) { + if(target == null){ retarget(() -> { target = Units.findAllyTile(team, x, y, discoverRange, tile -> tile.entity != null && tile.entity.health + 0.0001f < tile.block().health); @@ -296,140 +118,319 @@ public class Drone extends FlyingUnit implements BuilderTrait { } } }, - mine = new UnitState() { - public void entered() { - target = null; - } - - public void update() { - TileEntity entity = getClosestCore(); - - if(entity == null) return; - - if(targetItem == null) { - findItem(); - } - - //core full - if(targetItem != null && entity.tile.block().acceptStack(targetItem, 1, entity.tile, Drone.this) == 0){ - setState(repair); - return; - } - - //if inventory is full, drop it off. - if(inventory.isFull()){ - setState(drop); - }else{ - if(targetItem != null && !inventory.canAcceptItem(targetItem)){ - setState(drop); - return; + mine = new UnitState(){ + public void entered(){ + target = null; } - retarget(() -> { - if(findItemDrop()){ - return; - } + public void update(){ + TileEntity entity = getClosestCore(); - if(getMineTile() == null){ + if(entity == null) return; + + if(targetItem == null){ findItem(); } - if(targetItem == null) return; - - target = world.indexer().findClosestOre(x, y, targetItem); - }); - - if(target instanceof Tile) { - moveTo(type.range/1.5f); - - if (distanceTo(target) < type.range && mineTile != target) { - setMineTile((Tile)target); + //core full + if(targetItem != null && entity.tile.block().acceptStack(targetItem, 1, entity.tile, Drone.this) == 0){ + setState(repair); + return; } - if(((Tile)target).block() != Blocks.air){ + //if inventory is full, drop it off. + if(inventory.isFull()){ setState(drop); + }else{ + if(targetItem != null && !inventory.canAcceptItem(targetItem)){ + setState(drop); + return; + } + + retarget(() -> { + if(findItemDrop()){ + return; + } + + if(getMineTile() == null){ + findItem(); + } + + if(targetItem == null) return; + + target = world.indexer().findClosestOre(x, y, targetItem); + }); + + if(target instanceof Tile){ + moveTo(type.range / 1.5f); + + if(distanceTo(target) < type.range && mineTile != target){ + setMineTile((Tile) target); + } + + if(((Tile) target).block() != Blocks.air){ + setState(drop); + } + } } } - } - } - public void exited() { - setMineTile(null); - } - }, - pickup = new UnitState() { - public void entered() { - target = null; - } - - public void update() { - ItemDrop item = (ItemDrop)target; - - if(inventory.isFull() || !inventory.canAcceptItem(item.getItem(), 1)){ - setState(drop); - return; - } - - if(distanceTo(item) < 4){ - item.collision(Drone.this, x, y); - } - - //item has been picked up - if(item.getAmount() == 0){ - if(!findItemDrop()){ - setState(drop); + public void exited(){ + setMineTile(null); } - } - - moveTo(0f); - } - }, - drop = new UnitState() { - public void entered() { - target = null; - } - - public void update() { - if(inventory.isEmpty()){ - setState(mine); - return; - } - - target = getClosestCore(); - - if(target == null) return; - - TileEntity tile = (TileEntity)target; - - if(distanceTo(target) < type.range){ - if(tile.tile.block().acceptStack(inventory.getItem().item, inventory.getItem().amount, tile.tile, Drone.this) == inventory.getItem().amount) { - CallEntity.transferItemTo(inventory.getItem().item, inventory.getItem().amount, x, y, tile.tile); - inventory.clearItem(); + }, + pickup = new UnitState(){ + public void entered(){ + target = null; } - setState(repair); - } + public void update(){ + ItemDrop item = (ItemDrop) target; - circle(type.range/1.8f); - } - }, - retreat = new UnitState() { - public void entered() { - target = null; - } + if(inventory.isFull() || !inventory.canAcceptItem(item.getItem(), 1)){ + setState(drop); + return; + } - public void update() { - if(health >= health){ - state.set(attack); - }else if(!targetHasFlag(BlockFlag.repair)){ - if(timer.get(timerTarget, 20)) { - Tile target = Geometry.findClosest(x, y, world.indexer().getAllied(team, BlockFlag.repair)); - if (target != null) Drone.this.target = target.entity; + if(distanceTo(item) < 4){ + item.collision(Drone.this, x, y); + } + + //item has been picked up + if(item.getAmount() == 0){ + if(!findItemDrop()){ + setState(drop); + } + } + + moveTo(0f); + } + }, + drop = new UnitState(){ + public void entered(){ + target = null; + } + + public void update(){ + if(inventory.isEmpty()){ + setState(mine); + return; + } + + target = getClosestCore(); + + if(target == null) return; + + TileEntity tile = (TileEntity) target; + + if(distanceTo(target) < type.range){ + if(tile.tile.block().acceptStack(inventory.getItem().item, inventory.getItem().amount, tile.tile, Drone.this) == inventory.getItem().amount){ + CallEntity.transferItemTo(inventory.getItem().item, inventory.getItem().amount, x, y, tile.tile); + inventory.clearItem(); + } + + setState(repair); + } + + circle(type.range / 1.8f); + } + }, + retreat = new UnitState(){ + public void entered(){ + target = null; + } + + public void update(){ + if(health >= health){ + state.set(attack); + }else if(!targetHasFlag(BlockFlag.repair)){ + if(timer.get(timerTarget, 20)){ + Tile target = Geometry.findClosest(x, y, world.indexer().getAllied(team, BlockFlag.repair)); + if(target != null) Drone.this.target = target.entity; + } + }else{ + circle(40f); + } + } + }; + + { + initEvents(); + } + + /** + * Initialize placement event notifier system. + * Static initialization is to be avoided, thus, this is done lazily. + */ + private static void initEvents(){ + if(initialized) return; + + toMine = ObjectSet.with(Items.lead, Items.tungsten); + + Events.on(BlockBuildEvent.class, (team, tile) -> { + EntityGroup group = unitGroups[team.ordinal()]; + + if(!(tile.entity instanceof BuildEntity)) return; + BuildEntity entity = tile.entity(); + + for(BaseUnit unit : group.all()){ + if(unit instanceof Drone){ + ((Drone) unit).notifyPlaced(entity); } - }else{ - circle(40f); } + }); + + initialized = true; + } + + private void notifyPlaced(BuildEntity entity){ + float timeToBuild = entity.recipe.cost; + float dist = Math.min(entity.distanceTo(x, y) - placeDistance, 0); + + if(dist / type.maxVelocity < timeToBuild * 0.9f){ + //CallEntity.onDroneBeginBuild(this, entity.tile, entity.recipe); + target = entity; + setState(build); } - }; + } + + @Override + public float getBuildPower(Tile tile){ + return type.buildPower; + } + + @Override + public float getMinePower(){ + return type.minePower; + } + + @Override + public Queue getPlaceQueue(){ + return placeQueue; + } + + @Override + public Tile getMineTile(){ + return mineTile; + } + + @Override + public void setMineTile(Tile tile){ + mineTile = tile; + } + + @Override + public void update(){ + super.update(); + + x += Mathf.sin(Timers.time() + id * 999, 25f, 0.07f); + y += Mathf.cos(Timers.time() + id * 999, 25f, 0.07f); + + updateBuilding(this); + } + + @Override + protected void updateRotation(){ + if(target != null && (state.is(repair) || state.is(mine))){ + rotation = Mathf.slerpDelta(rotation, angleTo(target), 0.3f); + }else{ + rotation = Mathf.slerpDelta(rotation, velocity.angle(), 0.3f); + } + + if(velocity.len() <= 0.2f && !(state.is(repair) && target != null)){ + rotation += Mathf.sin(Timers.time() + id * 99, 10f, 5f); + } + } + + @Override + public void behavior(){ + if(health <= health * type.retreatPercent && + Geometry.findClosest(x, y, world.indexer().getAllied(team, BlockFlag.repair)) != null){ + setState(retreat); + } + } + + @Override + public UnitState getStartState(){ + return repair; + } + + @Override + public void drawOver(){ + trail.draw(Palette.lightTrail, 3f); + + TargetTrait entity = target; + + if(entity instanceof TileEntity && state.is(repair)){ + float len = 5f; + Draw.color(Color.BLACK, Color.WHITE, 0.95f + Mathf.absin(Timers.time(), 0.8f, 0.05f)); + Shapes.laser("beam", "beam-end", + x + Angles.trnsx(rotation, len), + y + Angles.trnsy(rotation, len), + entity.getX(), entity.getY()); + Draw.color(); + } + + drawBuilding(this); + } + + @Override + public float drawSize(){ + return isBuilding() ? placeDistance * 2f : 30f; + } + + @Override + public float getAmmoFraction(){ + return inventory.getItem().amount / (float) type.itemCapacity; + } + + protected void findItem(){ + TileEntity entity = getClosestCore(); + if(entity == null){ + return; + } + targetItem = Mathf.findMin(toMine, (a, b) -> -Integer.compare(entity.items.get(a), entity.items.get(b))); + } + + protected boolean findItemDrop(){ + TileEntity core = getClosestCore(); + + if(core == null) return false; + + //find nearby dropped items to pick up if applicable + ItemDrop drop = EntityPhysics.getClosest(itemGroup, x, y, 60f, + item -> core.tile.block().acceptStack(item.getItem(), item.getAmount(), core.tile, Drone.this) == item.getAmount() && + inventory.canAcceptItem(item.getItem(), 1)); + if(drop != null){ + setState(pickup); + target = drop; + return true; + } + return false; + } + + @Override + public boolean canCreateBlocks(){ + return false; + } + + @Override + public void write(DataOutput data) throws IOException{ + super.write(data); + data.writeInt(mineTile == null ? -1 : mineTile.packedPosition()); + writeBuilding(data); + } + + @Override + public void read(DataInput data, long time) throws IOException{ + super.read(data, time); + int mined = data.readInt(); + + readBuilding(data); + + if(mined != -1){ + mineTile = world.tile(mined); + } + } } diff --git a/core/src/io/anuke/mindustry/entities/units/types/Fabricator.java b/core/src/io/anuke/mindustry/entities/units/types/Fabricator.java index 89dcea9646..90119c8550 100644 --- a/core/src/io/anuke/mindustry/entities/units/types/Fabricator.java +++ b/core/src/io/anuke/mindustry/entities/units/types/Fabricator.java @@ -1,5 +1,5 @@ package io.anuke.mindustry.entities.units.types; -public class Fabricator extends Drone { +public class Fabricator extends Drone{ } diff --git a/core/src/io/anuke/mindustry/entities/units/types/Monsoon.java b/core/src/io/anuke/mindustry/entities/units/types/Monsoon.java index 09db7fc53a..b87e0d2f81 100644 --- a/core/src/io/anuke/mindustry/entities/units/types/Monsoon.java +++ b/core/src/io/anuke/mindustry/entities/units/types/Monsoon.java @@ -2,6 +2,6 @@ package io.anuke.mindustry.entities.units.types; import io.anuke.mindustry.entities.units.FlyingUnit; -public class Monsoon extends FlyingUnit { +public class Monsoon extends FlyingUnit{ } diff --git a/core/src/io/anuke/mindustry/entities/units/types/Scout.java b/core/src/io/anuke/mindustry/entities/units/types/Scout.java index 765dbfbb12..bdfdbe4f89 100644 --- a/core/src/io/anuke/mindustry/entities/units/types/Scout.java +++ b/core/src/io/anuke/mindustry/entities/units/types/Scout.java @@ -2,6 +2,6 @@ package io.anuke.mindustry.entities.units.types; import io.anuke.mindustry.entities.units.GroundUnit; -public class Scout extends GroundUnit { +public class Scout extends GroundUnit{ } diff --git a/core/src/io/anuke/mindustry/entities/units/types/Vtol.java b/core/src/io/anuke/mindustry/entities/units/types/Vtol.java index 370446b148..cf02014794 100644 --- a/core/src/io/anuke/mindustry/entities/units/types/Vtol.java +++ b/core/src/io/anuke/mindustry/entities/units/types/Vtol.java @@ -2,6 +2,6 @@ package io.anuke.mindustry.entities.units.types; import io.anuke.mindustry.entities.units.FlyingUnit; -public class Vtol extends FlyingUnit { +public class Vtol extends FlyingUnit{ } diff --git a/core/src/io/anuke/mindustry/game/Content.java b/core/src/io/anuke/mindustry/game/Content.java index 542f78f97c..accf8d0947 100644 --- a/core/src/io/anuke/mindustry/game/Content.java +++ b/core/src/io/anuke/mindustry/game/Content.java @@ -2,20 +2,32 @@ package io.anuke.mindustry.game; import com.badlogic.gdx.utils.Array; -/**Base interface for a content type that is loaded in {@link io.anuke.mindustry.core.ContentLoader}.*/ -public interface Content { +/** + * Base interface for a content type that is loaded in {@link io.anuke.mindustry.core.ContentLoader}. + */ +public interface Content{ - /**Returns the type name of this piece of content. - * This should return the same value for all instances of this content type.*/ + /** + * Returns the type name of this piece of content. + * This should return the same value for all instances of this content type. + */ String getContentTypeName(); - /**Returns a list of all instances of this content.*/ + /** + * Returns a list of all instances of this content. + */ Array getAll(); - /**Called after all content is created. Do not use to load regions or texture data!*/ - default void init(){} + /** + * Called after all content is created. Do not use to load regions or texture data! + */ + default void init(){ + } - /**Called after all content is created, only on non-headless versions. - * Use for loading regions or other image data.*/ - default void load(){} + /** + * Called after all content is created, only on non-headless versions. + * Use for loading regions or other image data. + */ + default void load(){ + } } diff --git a/core/src/io/anuke/mindustry/game/ContentDatabase.java b/core/src/io/anuke/mindustry/game/ContentDatabase.java index d01a7e97cc..ed658e111f 100644 --- a/core/src/io/anuke/mindustry/game/ContentDatabase.java +++ b/core/src/io/anuke/mindustry/game/ContentDatabase.java @@ -8,13 +8,19 @@ import io.anuke.mindustry.game.EventType.UnlockEvent; import io.anuke.ucore.core.Events; import io.anuke.ucore.core.Settings; -public class ContentDatabase { - /**Maps unlockable type names to a set of unlocked content.*/ +public class ContentDatabase{ + /** + * Maps unlockable type names to a set of unlocked content. + */ private ObjectMap> unlocked = new ObjectMap<>(); - /**Whether unlockables have changed since the last save.*/ + /** + * Whether unlockables have changed since the last save. + */ private boolean dirty; - /**Returns whether or not this piece of content is unlocked yet.*/ + /** + * Returns whether or not this piece of content is unlocked yet. + */ public boolean isUnlocked(UnlockableContent content){ if(!unlocked.containsKey(content.getContentTypeName())){ unlocked.put(content.getContentTypeName(), new ObjectSet<>()); @@ -25,10 +31,13 @@ public class ContentDatabase { return set.contains(content.getContentName()); } - /**Makes this piece of content 'unlocked', if possible. + /** + * Makes this piece of content 'unlocked', if possible. * If this piece of content is already unlocked or cannot be unlocked due to dependencies, nothing changes. * Results are not saved until you call {@link #save()}. - * @return whether or not this content was newly unlocked.*/ + * + * @return whether or not this content was newly unlocked. + */ public boolean unlockContent(UnlockableContent content){ if(!content.canBeUnlocked()) return false; @@ -48,12 +57,16 @@ public class ContentDatabase { return ret; } - /**Returns whether unlockables have changed since the last save.*/ + /** + * Returns whether unlockables have changed since the last save. + */ public boolean isDirty(){ return dirty; } - /**Clears all unlocked content.*/ + /** + * Clears all unlocked content. + */ public void reset(){ unlocked.clear(); dirty = true; diff --git a/core/src/io/anuke/mindustry/game/Difficulty.java b/core/src/io/anuke/mindustry/game/Difficulty.java index 4f7091a58f..7c86e5685e 100644 --- a/core/src/io/anuke/mindustry/game/Difficulty.java +++ b/core/src/io/anuke/mindustry/game/Difficulty.java @@ -2,7 +2,7 @@ package io.anuke.mindustry.game; import io.anuke.ucore.util.Bundles; -public enum Difficulty { +public enum Difficulty{ easy(4f, 2f, 1f), normal(2f, 1f, 1f), hard(1.5f, 0.5f, 0.75f), @@ -10,13 +10,19 @@ public enum Difficulty { //purge removed due to new wave system /*purge(0.25f, 0.01f, 0.25f)*/; - /**The scaling of how many waves it takes for one more enemy of a type to appear. + /** + * The scaling of how many waves it takes for one more enemy of a type to appear. * For example: with enemeyScaling = 2 and the default scaling being 2, it would take 4 waves for - * an enemy spawn to go from 1->2 enemies.*/ + * an enemy spawn to go from 1->2 enemies. + */ public final float enemyScaling; - /**Multiplier of the time between waves.*/ + /** + * Multiplier of the time between waves. + */ public final float timeScaling; - /**Scaling of max time between waves. Default time is 4 minutes.*/ + /** + * Scaling of max time between waves. Default time is 4 minutes. + */ public final float maxTimeScaling; private String value; @@ -28,7 +34,7 @@ public enum Difficulty { } @Override - public String toString() { + public String toString(){ if(value == null){ value = Bundles.get("setting.difficulty." + name()); } diff --git a/core/src/io/anuke/mindustry/game/EventType.java b/core/src/io/anuke/mindustry/game/EventType.java index 9aecf1a473..ec880f3be9 100644 --- a/core/src/io/anuke/mindustry/game/EventType.java +++ b/core/src/io/anuke/mindustry/game/EventType.java @@ -4,7 +4,7 @@ import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.world.Tile; import io.anuke.ucore.function.Event; -public class EventType { +public class EventType{ public interface PlayEvent extends Event{ void handle(); @@ -22,19 +22,25 @@ public class EventType { void handle(); } - /**This event is called from the logic thread. - * DO NOT INITIALIZE GRAPHICS HERE.*/ + /** + * This event is called from the logic thread. + * DO NOT INITIALIZE GRAPHICS HERE. + */ public interface WorldLoadEvent extends Event{ void handle(); } - /**Called after the WorldLoadEvent is, and all logic has been loaded. - * It is safe to intialize graphics here.*/ + /** + * Called after the WorldLoadEvent is, and all logic has been loaded. + * It is safe to intialize graphics here. + */ public interface WorldLoadGraphicsEvent extends Event{ void handle(); } - /**Called from the logic thread. Do not access graphics here!*/ + /** + * Called from the logic thread. Do not access graphics here! + */ public interface TileChangeEvent extends Event{ void handle(Tile tile); } diff --git a/core/src/io/anuke/mindustry/game/GameMode.java b/core/src/io/anuke/mindustry/game/GameMode.java index cbc7f7349d..fcf9e8c09a 100644 --- a/core/src/io/anuke/mindustry/game/GameMode.java +++ b/core/src/io/anuke/mindustry/game/GameMode.java @@ -3,8 +3,8 @@ package io.anuke.mindustry.game; import io.anuke.ucore.util.Bundles; public enum GameMode{ - waves, - //disabled for technical reasons + waves, + //disabled for technical reasons /*sandbox{ { infiniteResources = true; @@ -16,16 +16,16 @@ public enum GameMode{ disableWaveTimer = true; } }; - public boolean infiniteResources; - public boolean disableWaveTimer; + public boolean infiniteResources; + public boolean disableWaveTimer; - public String description(){ - return Bundles.get("mode."+name()+".description"); - } + public String description(){ + return Bundles.get("mode." + name() + ".description"); + } - @Override - public String toString(){ - return Bundles.get("mode."+name()+".name"); - } + @Override + public String toString(){ + return Bundles.get("mode." + name() + ".name"); + } } diff --git a/core/src/io/anuke/mindustry/game/SpawnGroup.java b/core/src/io/anuke/mindustry/game/SpawnGroup.java index 6c91faa1ac..4d8fe850be 100644 --- a/core/src/io/anuke/mindustry/game/SpawnGroup.java +++ b/core/src/io/anuke/mindustry/game/SpawnGroup.java @@ -8,84 +8,118 @@ import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.type.StatusEffect; import io.anuke.mindustry.type.Weapon; -/**A spawn group defines spawn information for a specific type of unit, with optional extra information like +/** + * A spawn group defines spawn information for a specific type of unit, with optional extra information like * weapon equipped, ammo used, and status effects. - * Each spawn group can have multiple sub-groups spawned in different areas of the map.*/ -public class SpawnGroup { - /**The unit type spawned*/ - public final UnitType type; - /**When this spawn should end*/ - protected int end = Integer.MAX_VALUE; - /**When this spawn should start*/ - protected int begin; - /**The spacing, in waves, of spawns. For example, 2 = spawns every other wave*/ - protected int spacing = 1; - /**Maximum amount of units that spawn*/ - protected int max = 60; - /**How many waves need to pass before the amount of units spawned increases by 1*/ - protected float unitScaling = 9999f; - /**How many waves need to pass before the amount of instances of this group increases by 1*/ - protected float groupScaling = 9999f; - /**Amount of enemies spawned initially, with no scaling*/ - protected int unitAmount = 1; - /**Amount of enemies spawned initially, with no scaling*/ - protected int groupAmount = 1; - /**Weapon used by the spawned unit. Null to disable. Only applicable to ground units.*/ - protected Weapon weapon; - /**Status effect applied to the spawned unit. Null to disable.*/ - protected StatusEffect effect; - /**Items this unit spawns with. Null to disable.*/ - protected ItemStack items; - /**Ammo type this unit spawns with. Null to use the first available ammo.*/ - protected Item ammoItem; - - public SpawnGroup(UnitType type){ - this.type = type; - } + * Each spawn group can have multiple sub-groups spawned in different areas of the map. + */ +public class SpawnGroup{ + /** + * The unit type spawned + */ + public final UnitType type; + /** + * When this spawn should end + */ + protected int end = Integer.MAX_VALUE; + /** + * When this spawn should start + */ + protected int begin; + /** + * The spacing, in waves, of spawns. For example, 2 = spawns every other wave + */ + protected int spacing = 1; + /** + * Maximum amount of units that spawn + */ + protected int max = 60; + /** + * How many waves need to pass before the amount of units spawned increases by 1 + */ + protected float unitScaling = 9999f; + /** + * How many waves need to pass before the amount of instances of this group increases by 1 + */ + protected float groupScaling = 9999f; + /** + * Amount of enemies spawned initially, with no scaling + */ + protected int unitAmount = 1; + /** + * Amount of enemies spawned initially, with no scaling + */ + protected int groupAmount = 1; + /** + * Weapon used by the spawned unit. Null to disable. Only applicable to ground units. + */ + protected Weapon weapon; + /** + * Status effect applied to the spawned unit. Null to disable. + */ + protected StatusEffect effect; + /** + * Items this unit spawns with. Null to disable. + */ + protected ItemStack items; + /** + * Ammo type this unit spawns with. Null to use the first available ammo. + */ + protected Item ammoItem; - /**Returns the amount of units spawned on a specific wave.*/ - public int getUnitsSpawned(int wave){ - if(wave < begin || wave > end || (wave - begin) % spacing != 0){ - return 0; - } - float scaling = this.unitScaling; - - return Math.min(unitAmount-1 + Math.max((int)((wave / spacing) / scaling), 1), max); - } + public SpawnGroup(UnitType type){ + this.type = type; + } - /**Returns the amount of different unit groups at a specific wave.*/ - public int getGroupsSpawned(int wave){ - if(wave < begin || wave > end || (wave - begin) % spacing != 0){ - return 0; - } - float scaling = this.groupScaling; + /** + * Returns the amount of units spawned on a specific wave. + */ + public int getUnitsSpawned(int wave){ + if(wave < begin || wave > end || (wave - begin) % spacing != 0){ + return 0; + } + float scaling = this.unitScaling; - return Math.min(groupAmount-1 + Math.max((int)((wave / spacing) / groupScaling), 1), max); - } + return Math.min(unitAmount - 1 + Math.max((int) ((wave / spacing) / scaling), 1), max); + } - /**Creates a unit, and assigns correct values based on this group's data. - * This method does not add() the unit.*/ - public BaseUnit createUnit(Team team){ - BaseUnit unit = type.create(team); + /** + * Returns the amount of different unit groups at a specific wave. + */ + public int getGroupsSpawned(int wave){ + if(wave < begin || wave > end || (wave - begin) % spacing != 0){ + return 0; + } + float scaling = this.groupScaling; - if(unit instanceof GroundUnit && weapon != null){ - ((GroundUnit) unit).setWeapon(weapon); - } + return Math.min(groupAmount - 1 + Math.max((int) ((wave / spacing) / groupScaling), 1), max); + } - if(effect != null){ - unit.applyEffect(effect, 10000f); - } + /** + * Creates a unit, and assigns correct values based on this group's data. + * This method does not add() the unit. + */ + public BaseUnit createUnit(Team team){ + BaseUnit unit = type.create(team); - if(items != null){ - unit.inventory.addItem(items.item, items.amount); - } + if(unit instanceof GroundUnit && weapon != null){ + ((GroundUnit) unit).setWeapon(weapon); + } - if(ammoItem != null){ - unit.inventory.addAmmo(unit.getWeapon().getAmmoType(ammoItem)); - }else{ - unit.inventory.addAmmo(unit.getWeapon().getAmmoType(unit.getWeapon().getAcceptedItems().iterator().next())); - } + if(effect != null){ + unit.applyEffect(effect, 10000f); + } - return unit; - } + if(items != null){ + unit.inventory.addItem(items.item, items.amount); + } + + if(ammoItem != null){ + unit.inventory.addAmmo(unit.getWeapon().getAmmoType(ammoItem)); + }else{ + unit.inventory.addAmmo(unit.getWeapon().getAmmoType(unit.getWeapon().getAcceptedItems().iterator().next())); + } + + return unit; + } } diff --git a/core/src/io/anuke/mindustry/game/Team.java b/core/src/io/anuke/mindustry/game/Team.java index 0d97c39285..7fce5dc6fb 100644 --- a/core/src/io/anuke/mindustry/game/Team.java +++ b/core/src/io/anuke/mindustry/game/Team.java @@ -2,7 +2,7 @@ package io.anuke.mindustry.game; import com.badlogic.gdx.graphics.Color; -public enum Team { +public enum Team{ none(Color.DARK_GRAY), blue(Color.ROYAL), red(Color.valueOf("e84737")), @@ -10,11 +10,10 @@ public enum Team { purple(Color.valueOf("ba5bd9")), orange(Color.valueOf("e8c66a")); + public final static Team[] all = values(); public final Color color; public final int intColor; - public final static Team[] all = values(); - Team(Color color){ this.color = color; intColor = Color.rgba8888(color); diff --git a/core/src/io/anuke/mindustry/game/TeamInfo.java b/core/src/io/anuke/mindustry/game/TeamInfo.java index 33ea3b37c7..8559fde11d 100644 --- a/core/src/io/anuke/mindustry/game/TeamInfo.java +++ b/core/src/io/anuke/mindustry/game/TeamInfo.java @@ -6,8 +6,10 @@ import io.anuke.mindustry.world.Tile; import io.anuke.ucore.util.ThreadArray; import io.anuke.ucore.util.ThreadSet; -/**Class for various team-based utilities.*/ -public class TeamInfo { +/** + * Class for various team-based utilities. + */ +public class TeamInfo{ private ObjectMap map = new ObjectMap<>(); private ThreadSet allies = new ThreadSet<>(), enemies = new ThreadSet<>(); @@ -18,30 +20,37 @@ public class TeamInfo { private int allyBits = 0; private int enemyBits = 0; - /**Returns all teams on a side.*/ - public ObjectSet getTeams(boolean ally) { + /** + * Returns all teams on a side. + */ + public ObjectSet getTeams(boolean ally){ return ally ? allyData : enemyData; } - /**Returns all team data.*/ - public ObjectSet getTeams() { + /** + * Returns all team data. + */ + public ObjectSet getTeams(){ return allTeamData; } - /**Register a team. + /** + * Register a team. + * * @param team The team type enum. * @param ally Whether this team is an ally with the player or an enemy with the player. - * In PvP situations with dedicated servers, the sides can be arbitrary.*/ + * In PvP situations with dedicated servers, the sides can be arbitrary. + */ public void add(Team team, boolean ally){ if(has(team)) throw new RuntimeException("Can't define team information twice!"); TeamData data = new TeamData(team, ally); - if(ally) { + if(ally){ allies.add(team); allyData.add(data); allyBits |= (1 << team.ordinal()); - }else { + }else{ enemies.add(team); enemyData.add(data); enemyBits |= (1 << team.ordinal()); @@ -53,20 +62,26 @@ public class TeamInfo { map.put(team, data); } - /**Returns team data by type. Call {@link #has(Team)} first to make sure it's active!*/ + /** + * Returns team data by type. Call {@link #has(Team)} first to make sure it's active! + */ public TeamData get(Team team){ if(!has(team)) throw new RuntimeException("This team is not active! Check has() before calling get()."); return map.get(team); } - /**Returns whether the specified team is active, e.g. whether it is participating in the game.*/ + /** + * Returns whether the specified team is active, e.g. whether it is participating in the game. + */ public boolean has(Team team){ return map.containsKey(team); } - /**Returns a set of all teams that are enemies of this team. - * For teams not active, an empty set is returned.*/ - public ObjectSet enemiesOf(Team team) { + /** + * Returns a set of all teams that are enemies of this team. + * For teams not active, an empty set is returned. + */ + public ObjectSet enemiesOf(Team team){ boolean ally = allies.contains(team); boolean enemy = enemies.contains(team); @@ -76,9 +91,11 @@ public class TeamInfo { return ally ? enemies : allies; } - /**Returns a set of all teams that are allies of this team. - * For teams not active, an empty set is returned.*/ - public ObjectSet alliesOf(Team team) { + /** + * Returns a set of all teams that are allies of this team. + * For teams not active, an empty set is returned. + */ + public ObjectSet alliesOf(Team team){ boolean ally = allies.contains(team); boolean enemy = enemies.contains(team); @@ -88,9 +105,11 @@ public class TeamInfo { return !ally ? enemies : allies; } - /**Returns a set of all teams that are enemies of this team. - * For teams not active, an empty set is returned.*/ - public ObjectSet enemyDataOf(Team team) { + /** + * Returns a set of all teams that are enemies of this team. + * For teams not active, an empty set is returned. + */ + public ObjectSet enemyDataOf(Team team){ boolean ally = allies.contains(team); boolean enemy = enemies.contains(team); @@ -100,7 +119,9 @@ public class TeamInfo { return ally ? enemyData : allyData; } - /**Returns whether or not these two teams are enemies.*/ + /** + * Returns whether or not these two teams are enemies. + */ public boolean areEnemies(Team team, Team other){ if(team == other) return false; //fast fail to be more efficient boolean ally = (allyBits & (1 << team.ordinal())) != 0; @@ -108,12 +129,12 @@ public class TeamInfo { return (ally == enemy) || !ally; //if it's not in the game, target everything. } - public class TeamData { + public class TeamData{ public final ThreadArray cores = new ThreadArray<>(); public final Team team; public final boolean ally; - public TeamData(Team team, boolean ally) { + public TeamData(Team team, boolean ally){ this.team = team; this.ally = ally; } diff --git a/core/src/io/anuke/mindustry/game/UnlockableContent.java b/core/src/io/anuke/mindustry/game/UnlockableContent.java index b42ed1c645..6c04c7ad06 100644 --- a/core/src/io/anuke/mindustry/game/UnlockableContent.java +++ b/core/src/io/anuke/mindustry/game/UnlockableContent.java @@ -5,37 +5,54 @@ import io.anuke.ucore.scene.ui.layout.Table; import static io.anuke.mindustry.Vars.control; -/**Base interface for an unlockable content type.*/ +/** + * Base interface for an unlockable content type. + */ public interface UnlockableContent extends Content{ - /**Returns the unqiue name of this piece of content. + /** + * Returns the unqiue name of this piece of content. * The name only needs to be unique for all content of this type. * Do not use IDs for names! Make sure this string stays constant with each update unless removed. - * (e.g. having a recipe and a block, both with name "wall" is fine, as they are different types).*/ + * (e.g. having a recipe and a block, both with name "wall" is fine, as they are different types). + */ String getContentName(); - /**Returns the localized name of this content.*/ + /** + * Returns the localized name of this content. + */ String localizedName(); TextureRegion getContentIcon(); - /**This should show all necessary info about this content in the specified table.*/ + /** + * This should show all necessary info about this content in the specified table. + */ void displayInfo(Table table); - /**Called when this content is unlocked. Use this to unlock other related content.*/ - default void onUnlock(){} + /** + * Called when this content is unlocked. Use this to unlock other related content. + */ + default void onUnlock(){ + } - /**Whether this content is always hidden in the content info dialog.*/ + /** + * Whether this content is always hidden in the content info dialog. + */ default boolean isHidden(){ return false; } - /**Lists the content that must be unlocked in order for this specific content to become unlocked. May return null.*/ + /** + * Lists the content that must be unlocked in order for this specific content to become unlocked. May return null. + */ default UnlockableContent[] getDependencies(){ return null; } - /**Returns whether dependencies are satisfied for unlocking this content.*/ + /** + * Returns whether dependencies are satisfied for unlocking this content. + */ default boolean canBeUnlocked(){ UnlockableContent[] depend = getDependencies(); if(depend == null){ diff --git a/core/src/io/anuke/mindustry/game/WaveCreator.java b/core/src/io/anuke/mindustry/game/WaveCreator.java index c1d2adb8e2..a5e5e25340 100644 --- a/core/src/io/anuke/mindustry/game/WaveCreator.java +++ b/core/src/io/anuke/mindustry/game/WaveCreator.java @@ -8,183 +8,183 @@ import io.anuke.mindustry.content.Weapons; import io.anuke.mindustry.type.ItemStack; public class WaveCreator{ - - public static Array getSpawns(){ - return Array.with( - new SpawnGroup(UnitTypes.scout){{ - end = 8; - unitScaling = 2; - }}, - new SpawnGroup(UnitTypes.vtol){{ - begin = 12; - end = 14; - }}, + public static Array getSpawns(){ + return Array.with( + new SpawnGroup(UnitTypes.scout){{ + end = 8; + unitScaling = 2; + }}, - new SpawnGroup(UnitTypes.scout){{ - begin = 11; - unitScaling = 2; - spacing = 2; - max = 4; - }}, + new SpawnGroup(UnitTypes.vtol){{ + begin = 12; + end = 14; + }}, - new SpawnGroup(UnitTypes.titan){{ - begin = 9; - spacing = 3; - unitScaling = 2; + new SpawnGroup(UnitTypes.scout){{ + begin = 11; + unitScaling = 2; + spacing = 2; + max = 4; + }}, - end = 30; - }}, + new SpawnGroup(UnitTypes.titan){{ + begin = 9; + spacing = 3; + unitScaling = 2; - new SpawnGroup(UnitTypes.scout){{ - begin = 10; - unitScaling = 2; - unitAmount = 1; - spacing = 2; - ammoItem = Items.tungsten; - end = 30; - }}, + end = 30; + }}, - new SpawnGroup(UnitTypes.titan){{ - begin = 28; - spacing = 3; - unitScaling = 2; - weapon = Weapons.flamethrower; - end = 40; - }}, + new SpawnGroup(UnitTypes.scout){{ + begin = 10; + unitScaling = 2; + unitAmount = 1; + spacing = 2; + ammoItem = Items.tungsten; + end = 30; + }}, - new SpawnGroup(UnitTypes.titan){{ - begin = 45; - spacing = 3; - unitScaling = 2; - weapon = Weapons.flamethrower; - effect = StatusEffects.overdrive; - }}, + new SpawnGroup(UnitTypes.titan){{ + begin = 28; + spacing = 3; + unitScaling = 2; + weapon = Weapons.flamethrower; + end = 40; + }}, - new SpawnGroup(UnitTypes.titan){{ - begin = 120; - spacing = 2; - unitScaling = 3; - unitAmount = 5; - weapon = Weapons.flakgun; - effect = StatusEffects.overdrive; - }}, + new SpawnGroup(UnitTypes.titan){{ + begin = 45; + spacing = 3; + unitScaling = 2; + weapon = Weapons.flamethrower; + effect = StatusEffects.overdrive; + }}, - new SpawnGroup(UnitTypes.vtol){{ - begin = 16; - unitScaling = 2; - spacing = 2; + new SpawnGroup(UnitTypes.titan){{ + begin = 120; + spacing = 2; + unitScaling = 3; + unitAmount = 5; + weapon = Weapons.flakgun; + effect = StatusEffects.overdrive; + }}, - end = 39; - max = 7; - }}, + new SpawnGroup(UnitTypes.vtol){{ + begin = 16; + unitScaling = 2; + spacing = 2; - new SpawnGroup(UnitTypes.scout){{ - begin = 82; - spacing = 3; - unitAmount = 4; - groupAmount = 2; - unitScaling = 3; - effect = StatusEffects.overdrive; - ammoItem = Items.silicon; - }}, + end = 39; + max = 7; + }}, - new SpawnGroup(UnitTypes.scout){{ - begin = 41; - spacing = 5; - unitAmount = 1; - unitScaling = 3; - effect = StatusEffects.shielded; - ammoItem = Items.thorium; - max = 10; - }}, + new SpawnGroup(UnitTypes.scout){{ + begin = 82; + spacing = 3; + unitAmount = 4; + groupAmount = 2; + unitScaling = 3; + effect = StatusEffects.overdrive; + ammoItem = Items.silicon; + }}, - new SpawnGroup(UnitTypes.scout){{ - begin = 35; - spacing = 3; - unitAmount = 4; - groupAmount = 2; - effect = StatusEffects.overdrive; - items = new ItemStack(Items.blastCompound, 60); - end = 60; - }}, + new SpawnGroup(UnitTypes.scout){{ + begin = 41; + spacing = 5; + unitAmount = 1; + unitScaling = 3; + effect = StatusEffects.shielded; + ammoItem = Items.thorium; + max = 10; + }}, - new SpawnGroup(UnitTypes.scout){{ - begin = 42; - spacing = 3; - unitAmount = 4; - groupAmount = 2; - effect = StatusEffects.overdrive; - items = new ItemStack(Items.pyratite, 100); - end = 130; - }}, + new SpawnGroup(UnitTypes.scout){{ + begin = 35; + spacing = 3; + unitAmount = 4; + groupAmount = 2; + effect = StatusEffects.overdrive; + items = new ItemStack(Items.blastCompound, 60); + end = 60; + }}, - new SpawnGroup(UnitTypes.monsoon){{ - begin = 40; - ammoItem = Items.blastCompound; - unitAmount = 2; - spacing = 2; - unitScaling = 3; - max = 8; - }}, + new SpawnGroup(UnitTypes.scout){{ + begin = 42; + spacing = 3; + unitAmount = 4; + groupAmount = 2; + effect = StatusEffects.overdrive; + items = new ItemStack(Items.pyratite, 100); + end = 130; + }}, - new SpawnGroup(UnitTypes.vtol){{ - begin = 50; - unitAmount = 4; - unitScaling = 3; - spacing = 5; - groupAmount = 2; - effect = StatusEffects.overdrive; - max = 8; - }}, + new SpawnGroup(UnitTypes.monsoon){{ + begin = 40; + ammoItem = Items.blastCompound; + unitAmount = 2; + spacing = 2; + unitScaling = 3; + max = 8; + }}, - new SpawnGroup(UnitTypes.monsoon){{ - begin = 53; - ammoItem = Items.pyratite; - unitAmount = 2; - unitScaling = 3; - spacing = 4; - max = 8; - end = 74; - }}, + new SpawnGroup(UnitTypes.vtol){{ + begin = 50; + unitAmount = 4; + unitScaling = 3; + spacing = 5; + groupAmount = 2; + effect = StatusEffects.overdrive; + max = 8; + }}, - new SpawnGroup(UnitTypes.monsoon){{ - begin = 53; - ammoItem = Items.coal; - unitAmount = 2; - unitScaling = 3; - spacing = 4; - max = 8; - end = 74; - }} - ); - } + new SpawnGroup(UnitTypes.monsoon){{ + begin = 53; + ammoItem = Items.pyratite; + unitAmount = 2; + unitScaling = 3; + spacing = 4; + max = 8; + end = 74; + }}, - public static void testWaves(int from, int to){ - Array spawns = getSpawns(); - for(int i = from; i <= to; i ++){ - System.out.print(i+": "); - int total = 0; - for(SpawnGroup spawn : spawns){ - int a = spawn.getUnitsSpawned(i) * spawn.getGroupsSpawned(i); - total += a; - - if(a > 0){ - System.out.print(a+"x" + spawn.type.name); + new SpawnGroup(UnitTypes.monsoon){{ + begin = 53; + ammoItem = Items.coal; + unitAmount = 2; + unitScaling = 3; + spacing = 4; + max = 8; + end = 74; + }} + ); + } - if(spawn.weapon != null){ - System.out.print(":" + spawn.weapon.name); - } + public static void testWaves(int from, int to){ + Array spawns = getSpawns(); + for(int i = from; i <= to; i++){ + System.out.print(i + ": "); + int total = 0; + for(SpawnGroup spawn : spawns){ + int a = spawn.getUnitsSpawned(i) * spawn.getGroupsSpawned(i); + total += a; - if(spawn.ammoItem != null){ - System.out.print(":" + spawn.ammoItem.name); - } + if(a > 0){ + System.out.print(a + "x" + spawn.type.name); - System.out.print(" "); - } - } - System.out.print(" (" + total + ")"); - System.out.println(); - } - } + if(spawn.weapon != null){ + System.out.print(":" + spawn.weapon.name); + } + + if(spawn.ammoItem != null){ + System.out.print(":" + spawn.ammoItem.name); + } + + System.out.print(" "); + } + } + System.out.print(" (" + total + ")"); + System.out.println(); + } + } } diff --git a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java index 7a898eb72f..0f6317a7e0 100644 --- a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java @@ -15,203 +15,207 @@ import static io.anuke.mindustry.Vars.*; import static io.anuke.ucore.core.Core.camera; public class BlockRenderer{ - private final static int initialRequests = 32*32; + private final static int initialRequests = 32 * 32; - private FloorRenderer floorRenderer; - - private Array requests = new Array<>(initialRequests); - private Layer lastLayer; - private int requestidx = 0; - private int iterateidx = 0; + private FloorRenderer floorRenderer; - public BlockRenderer(){ - floorRenderer = new FloorRenderer(); + private Array requests = new Array<>(initialRequests); + private Layer lastLayer; + private int requestidx = 0; + private int iterateidx = 0; - for(int i = 0; i < requests.size; i ++){ - requests.set(i, new BlockRequest()); - } - } - - private class BlockRequest implements Comparable{ - Tile tile; - Layer layer; - - @Override - public int compareTo(BlockRequest other){ - return layer.compareTo(other.layer); - } + public BlockRenderer(){ + floorRenderer = new FloorRenderer(); - @Override - public String toString(){ - return tile.block().name + ":" + layer.toString(); - } - } - - /**Process all blocks to draw, simultaneously drawing block shadows and static blocks.*/ - public void processBlocks(){ - requestidx = 0; - lastLayer = null; - - int rangex = (int) (camera.viewportWidth * camera.zoom / tilesize / 2)+2; - int rangey = (int) (camera.viewportHeight * camera.zoom / tilesize / 2)+2; + for(int i = 0; i < requests.size; i++){ + requests.set(i, new BlockRequest()); + } + } - int expandr = 4; - - Graphics.surface(renderer.effectSurface, true, false); + /** + * Process all blocks to draw, simultaneously drawing block shadows and static blocks. + */ + public void processBlocks(){ + requestidx = 0; + lastLayer = null; - int avgx = Mathf.scl(camera.position.x, tilesize); - int avgy = Mathf.scl(camera.position.y, tilesize); + int rangex = (int) (camera.viewportWidth * camera.zoom / tilesize / 2) + 2; + int rangey = (int) (camera.viewportHeight * camera.zoom / tilesize / 2) + 2; - int minx = Math.max(avgx - rangex - expandr, 0); - int miny = Math.max(avgy - rangey - expandr, 0); - int maxx = Math.min(world.width() - 1, avgx + rangex + expandr); - int maxy = Math.min(world.height() - 1, avgy+ rangey + expandr); + int expandr = 4; - for(int x = minx; x <= maxx; x++){ - for(int y = miny; y <= maxy; y++){ - boolean expanded = (Math.abs(x - avgx) > rangex || Math.abs(y - avgy) > rangey); + Graphics.surface(renderer.effectSurface, true, false); - synchronized (Tile.tileSetLock) { - Tile tile = world.rawTile(x, y); + int avgx = Mathf.scl(camera.position.x, tilesize); + int avgy = Mathf.scl(camera.position.y, tilesize); - if (tile != null) { - Block block = tile.block(); + int minx = Math.max(avgx - rangex - expandr, 0); + int miny = Math.max(avgy - rangey - expandr, 0); + int maxx = Math.min(world.width() - 1, avgx + rangex + expandr); + int maxy = Math.min(world.height() - 1, avgy + rangey + expandr); - if (!expanded && block != Blocks.air && world.isAccessible(x, y)) { - tile.block().drawShadow(tile); - } + for(int x = minx; x <= maxx; x++){ + for(int y = miny; y <= maxy; y++){ + boolean expanded = (Math.abs(x - avgx) > rangex || Math.abs(y - avgy) > rangey); - if (!(block instanceof StaticBlock)) { - if (block != Blocks.air) { - if (!expanded) { - addRequest(tile, Layer.block); - } + synchronized(Tile.tileSetLock){ + Tile tile = world.rawTile(x, y); - if (block.expanded || !expanded) { - if (block.layer != null && block.isLayer(tile)) { - addRequest(tile, block.layer); - } + if(tile != null){ + Block block = tile.block(); - if (block.layer2 != null && block.isLayer2(tile)) { - addRequest(tile, block.layer2); - } - } - } - } - } - } - } - } + if(!expanded && block != Blocks.air && world.isAccessible(x, y)){ + tile.block().drawShadow(tile); + } - //TODO this actually isn't necessary - Draw.color(0, 0, 0, 0.15f); - Graphics.flushSurface(); - Draw.color(); + if(!(block instanceof StaticBlock)){ + if(block != Blocks.air){ + if(!expanded){ + addRequest(tile, Layer.block); + } - Graphics.end(); - floorRenderer.beginDraw(); - floorRenderer.drawLayer(CacheLayer.walls); - floorRenderer.endDraw(); - Graphics.begin(); + if(block.expanded || !expanded){ + if(block.layer != null && block.isLayer(tile)){ + addRequest(tile, block.layer); + } - Sort.instance().sort(requests.items, 0, requestidx); - iterateidx = 0; - } + if(block.layer2 != null && block.isLayer2(tile)){ + addRequest(tile, block.layer2); + } + } + } + } + } + } + } + } - public int getRequests(){ - return requestidx; - } - - public void drawBlocks(Layer stopAt){ - - for(; iterateidx < requestidx; iterateidx ++){ + //TODO this actually isn't necessary + Draw.color(0, 0, 0, 0.15f); + Graphics.flushSurface(); + Draw.color(); - if(iterateidx < requests.size && requests.get(iterateidx).layer.ordinal() > stopAt.ordinal()){ - break; - } - - BlockRequest req = requests.get(iterateidx); + Graphics.end(); + floorRenderer.beginDraw(); + floorRenderer.drawLayer(CacheLayer.walls); + floorRenderer.endDraw(); + Graphics.begin(); - if(req.layer != lastLayer){ - if(lastLayer != null) layerEnds(lastLayer); - layerBegins(req.layer); - } + Sort.instance().sort(requests.items, 0, requestidx); + iterateidx = 0; + } - synchronized (Tile.tileSetLock) { - Block block = req.tile.block(); + public int getRequests(){ + return requestidx; + } - if (req.layer == Layer.block) { - block.draw(req.tile); - } else if (req.layer == block.layer) { - block.drawLayer(req.tile); - } else if (req.layer == block.layer2) { - block.drawLayer2(req.tile); - } - } + public void drawBlocks(Layer stopAt){ - lastLayer = req.layer; - } - } + for(; iterateidx < requestidx; iterateidx++){ - public void drawTeamBlocks(Layer layer, Team team){ - int index = this.iterateidx; + if(iterateidx < requests.size && requests.get(iterateidx).layer.ordinal() > stopAt.ordinal()){ + break; + } - for(; index < requestidx; index ++){ + BlockRequest req = requests.get(iterateidx); - if(index < requests.size && requests.get(index).layer.ordinal() > layer.ordinal()){ - break; - } + if(req.layer != lastLayer){ + if(lastLayer != null) layerEnds(lastLayer); + layerBegins(req.layer); + } - BlockRequest req = requests.get(index); - if(req.tile.getTeam() != team) continue; + synchronized(Tile.tileSetLock){ + Block block = req.tile.block(); - synchronized (Tile.tileSetLock) { - Block block = req.tile.block(); + if(req.layer == Layer.block){ + block.draw(req.tile); + }else if(req.layer == block.layer){ + block.drawLayer(req.tile); + }else if(req.layer == block.layer2){ + block.drawLayer2(req.tile); + } + } - if (req.layer == block.layer) { - block.drawLayer(req.tile); - } else if (req.layer == block.layer2) { - block.drawLayer2(req.tile); - } - } - } - } + lastLayer = req.layer; + } + } - public void skipLayer(Layer stopAt){ + public void drawTeamBlocks(Layer layer, Team team){ + int index = this.iterateidx; - for(; iterateidx < requestidx; iterateidx ++){ - if(iterateidx < requests.size && requests.get(iterateidx).layer.ordinal() > stopAt.ordinal()){ - break; - } - } - } + for(; index < requestidx; index++){ - public void beginFloor(){ - floorRenderer.beginDraw(); - } + if(index < requests.size && requests.get(index).layer.ordinal() > layer.ordinal()){ + break; + } - public void endFloor(){ - floorRenderer.endDraw(); - } + BlockRequest req = requests.get(index); + if(req.tile.getTeam() != team) continue; - public void drawFloor(){ - floorRenderer.drawFloor(); - } + synchronized(Tile.tileSetLock){ + Block block = req.tile.block(); - private void layerBegins(Layer layer){} + if(req.layer == block.layer){ + block.drawLayer(req.tile); + }else if(req.layer == block.layer2){ + block.drawLayer2(req.tile); + } + } + } + } - private void layerEnds(Layer layer){} + public void skipLayer(Layer stopAt){ - private void addRequest(Tile tile, Layer layer){ - if(requestidx >= requests.size){ - requests.add(new BlockRequest()); - } - BlockRequest r = requests.get(requestidx); - if(r == null){ - requests.set(requestidx, r = new BlockRequest()); - } - r.tile = tile; - r.layer = layer; - requestidx ++; - } + for(; iterateidx < requestidx; iterateidx++){ + if(iterateidx < requests.size && requests.get(iterateidx).layer.ordinal() > stopAt.ordinal()){ + break; + } + } + } + + public void beginFloor(){ + floorRenderer.beginDraw(); + } + + public void endFloor(){ + floorRenderer.endDraw(); + } + + public void drawFloor(){ + floorRenderer.drawFloor(); + } + + private void layerBegins(Layer layer){ + } + + private void layerEnds(Layer layer){ + } + + private void addRequest(Tile tile, Layer layer){ + if(requestidx >= requests.size){ + requests.add(new BlockRequest()); + } + BlockRequest r = requests.get(requestidx); + if(r == null){ + requests.set(requestidx, r = new BlockRequest()); + } + r.tile = tile; + r.layer = layer; + requestidx++; + } + + private class BlockRequest implements Comparable{ + Tile tile; + Layer layer; + + @Override + public int compareTo(BlockRequest other){ + return layer.compareTo(other.layer); + } + + @Override + public String toString(){ + return tile.block().name + ":" + layer.toString(); + } + } } diff --git a/core/src/io/anuke/mindustry/graphics/CacheLayer.java b/core/src/io/anuke/mindustry/graphics/CacheLayer.java index f1471c2a42..aecf703ae2 100644 --- a/core/src/io/anuke/mindustry/graphics/CacheLayer.java +++ b/core/src/io/anuke/mindustry/graphics/CacheLayer.java @@ -8,7 +8,7 @@ import io.anuke.ucore.graphics.Shader; import static io.anuke.mindustry.Vars.renderer; -public enum CacheLayer { +public enum CacheLayer{ water{ @Override public void begin(){ @@ -57,11 +57,11 @@ public enum CacheLayer { walls; public void begin(){ - + } public void end(){ - + } protected void beginShader(){ diff --git a/core/src/io/anuke/mindustry/graphics/FloorRenderer.java b/core/src/io/anuke/mindustry/graphics/FloorRenderer.java index a93bde5a6f..5ccefa23be 100644 --- a/core/src/io/anuke/mindustry/graphics/FloorRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/FloorRenderer.java @@ -26,7 +26,7 @@ import java.util.Arrays; import static io.anuke.mindustry.Vars.tilesize; import static io.anuke.mindustry.Vars.world; -public class FloorRenderer { +public class FloorRenderer{ private final static int chunksize = 64; private Chunk[][] cache; @@ -38,6 +38,35 @@ public class FloorRenderer { Events.on(WorldLoadGraphicsEvent.class, this::clearTiles); } + static ShaderProgram createDefaultShader(){ + String vertexShader = "attribute vec4 " + ShaderProgram.POSITION_ATTRIBUTE + ";\n" // + + "attribute vec2 " + ShaderProgram.TEXCOORD_ATTRIBUTE + "0;\n" // + + "uniform mat4 u_projTrans;\n" // + + "varying vec2 v_texCoords;\n" // + + "\n" // + + "void main()\n" // + + "{\n" // + + " v_texCoords = " + ShaderProgram.TEXCOORD_ATTRIBUTE + "0;\n" // + + " gl_Position = u_projTrans * " + ShaderProgram.POSITION_ATTRIBUTE + ";\n" // + + "}\n"; + String fragmentShader = "#ifdef GL_ES\n" // + + "#define LOWP lowp\n" // + + "precision mediump float;\n" // + + "#else\n" // + + "#define LOWP \n" // + + "#endif\n" // + + "varying vec2 v_texCoords;\n" // + + "uniform sampler2D u_texture;\n" // + + "void main()\n"// + + "{\n" // + + " gl_FragColor = texture2D(u_texture, v_texCoords);\n" // + + "}"; + + ShaderProgram shader = new ShaderProgram(vertexShader, fragmentShader); + if(!shader.isCompiled()) throw new IllegalArgumentException("Error compiling shader: " + shader.getLog()); + return shader; + } + public void drawFloor(){ if(cache == null){ return; @@ -45,11 +74,11 @@ public class FloorRenderer { OrthographicCamera camera = Core.camera; - int crangex = (int)(camera.viewportWidth * camera.zoom / (chunksize * tilesize))+1; - int crangey = (int)(camera.viewportHeight * camera.zoom / (chunksize * tilesize))+1; + int crangex = (int) (camera.viewportWidth * camera.zoom / (chunksize * tilesize)) + 1; + int crangey = (int) (camera.viewportHeight * camera.zoom / (chunksize * tilesize)) + 1; - for(int x = -crangex; x <= crangex; x++) { - for (int y = -crangey; y <= crangey; y++) { + for(int x = -crangex; x <= crangex; x++){ + for(int y = -crangey; y <= crangey; y++){ int worldx = Mathf.scl(camera.position.x, chunksize * tilesize) + x; int worldy = Mathf.scl(camera.position.y, chunksize * tilesize) + y; @@ -71,13 +100,13 @@ public class FloorRenderer { int worldx = Mathf.scl(camera.position.x, chunksize * tilesize) + x; int worldy = Mathf.scl(camera.position.y, chunksize * tilesize) + y; - if (!Mathf.inBounds(worldx, worldy, cache)) + if(!Mathf.inBounds(worldx, worldy, cache)) continue; Chunk chunk = cache[worldx][worldy]; //loop through all layers, and add layer index if it exists - for(int i = 0; i < layers - 1; i ++){ + for(int i = 0; i < layers - 1; i++){ if(chunk.caches[i] != -1){ drawnLayerSet.add(i); } @@ -95,7 +124,7 @@ public class FloorRenderer { Graphics.end(); beginDraw(); - for(int i = 0; i < drawnLayers.size; i ++) { + for(int i = 0; i < drawnLayers.size; i++){ CacheLayer layer = CacheLayer.values()[drawnLayers.get(i)]; drawLayer(layer); @@ -131,13 +160,13 @@ public class FloorRenderer { OrthographicCamera camera = Core.camera; - int crangex = (int)(camera.viewportWidth * camera.zoom / (chunksize * tilesize))+1; - int crangey = (int)(camera.viewportHeight * camera.zoom / (chunksize * tilesize))+1; + int crangex = (int) (camera.viewportWidth * camera.zoom / (chunksize * tilesize)) + 1; + int crangey = (int) (camera.viewportHeight * camera.zoom / (chunksize * tilesize)) + 1; layer.begin(); - for (int x = -crangex; x <= crangex; x++) { - for (int y = -crangey; y <= crangey; y++) { + for(int x = -crangex; x <= crangex; x++){ + for(int y = -crangey; y <= crangey; y++){ int worldx = Mathf.scl(camera.position.x, chunksize * tilesize) + x; int worldy = Mathf.scl(camera.position.y, chunksize * tilesize) + y; @@ -166,12 +195,12 @@ public class FloorRenderer { ObjectSet used = new ObjectSet<>(); - for(int tilex = cx * chunksize; tilex < (cx + 1) * chunksize; tilex++) { - for (int tiley = cy * chunksize; tiley < (cy + 1) * chunksize; tiley++) { + for(int tilex = cx * chunksize; tilex < (cx + 1) * chunksize; tilex++){ + for(int tiley = cy * chunksize; tiley < (cy + 1) * chunksize; tiley++){ Tile tile = world.tile(tilex, tiley); - if (tile != null){ + if(tile != null){ used.add(tile.block().cacheLayer == CacheLayer.walls ? - CacheLayer.walls : tile.floor().cacheLayer); + CacheLayer.walls : tile.floor().cacheLayer); } } } @@ -180,7 +209,7 @@ public class FloorRenderer { cacheChunkLayer(cx, cy, chunk, layer); } - // Log.info("Time to cache a chunk: {0}", TimeUtils.timeSinceNanos(time) / 1000000f); + // Log.info("Time to cache a chunk: {0}", TimeUtils.timeSinceNanos(time) / 1000000f); } private void cacheChunkLayer(int cx, int cy, Chunk chunk, CacheLayer layer){ @@ -211,25 +240,21 @@ public class FloorRenderer { chunk.caches[layer.ordinal()] = cbatch.getLastCache(); } - private class Chunk{ - int[] caches = new int[CacheLayer.values().length]; - } - public void clearTiles(){ if(cbatch != null) cbatch.dispose(); Timers.mark(); - int chunksx = Mathf.ceil((float)world.width() / chunksize), chunksy = Mathf.ceil((float)world.height() / chunksize); + int chunksx = Mathf.ceil((float) world.width() / chunksize), chunksy = Mathf.ceil((float) world.height() / chunksize); cache = new Chunk[chunksx][chunksy]; - cbatch = new CacheBatch(world.width()*world.height()*4*4); + cbatch = new CacheBatch(world.width() * world.height() * 4 * 4); Log.info("Time to create: {0}", Timers.elapsed()); Timers.mark(); - for (int x = 0; x < chunksx; x++) { - for (int y = 0; y < chunksy; y++) { + for(int x = 0; x < chunksx; x++){ + for(int y = 0; y < chunksy; y++){ cache[x][y] = new Chunk(); Arrays.fill(cache[x][y].caches, -1); @@ -240,32 +265,7 @@ public class FloorRenderer { Log.info("Time to cache: {0}", Timers.elapsed()); } - static ShaderProgram createDefaultShader () { - String vertexShader = "attribute vec4 " + ShaderProgram.POSITION_ATTRIBUTE + ";\n" // - + "attribute vec2 " + ShaderProgram.TEXCOORD_ATTRIBUTE + "0;\n" // - + "uniform mat4 u_projTrans;\n" // - + "varying vec2 v_texCoords;\n" // - + "\n" // - + "void main()\n" // - + "{\n" // - + " v_texCoords = " + ShaderProgram.TEXCOORD_ATTRIBUTE + "0;\n" // - + " gl_Position = u_projTrans * " + ShaderProgram.POSITION_ATTRIBUTE + ";\n" // - + "}\n"; - String fragmentShader = "#ifdef GL_ES\n" // - + "#define LOWP lowp\n" // - + "precision mediump float;\n" // - + "#else\n" // - + "#define LOWP \n" // - + "#endif\n" // - + "varying vec2 v_texCoords;\n" // - + "uniform sampler2D u_texture;\n" // - + "void main()\n"// - + "{\n" // - + " gl_FragColor = texture2D(u_texture, v_texCoords);\n" // - + "}"; - - ShaderProgram shader = new ShaderProgram(vertexShader, fragmentShader); - if (!shader.isCompiled()) throw new IllegalArgumentException("Error compiling shader: " + shader.getLog()); - return shader; + private class Chunk{ + int[] caches = new int[CacheLayer.values().length]; } } diff --git a/core/src/io/anuke/mindustry/graphics/FogRenderer.java b/core/src/io/anuke/mindustry/graphics/FogRenderer.java index 2e8c2ba52b..6ebdfb8f90 100644 --- a/core/src/io/anuke/mindustry/graphics/FogRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/FogRenderer.java @@ -24,7 +24,9 @@ import java.nio.ByteBuffer; import static io.anuke.mindustry.Vars.*; -/**Used for rendering fog of war. A framebuffer is used for this.*/ +/** + * Used for rendering fog of war. A framebuffer is used for this. + */ public class FogRenderer implements Disposable{ private TextureRegion region = new TextureRegion(); private FrameBuffer buffer; @@ -42,8 +44,8 @@ public class FogRenderer implements Disposable{ Graphics.clear(0, 0, 0, 1f); buffer.end(); - for (int x = 0; x < world.width(); x++) { - for (int y = 0; y < world.height(); y++) { + for(int x = 0; x < world.width(); x++){ + for(int y = 0; y < world.height(); y++){ Tile tile = world.tile(x, y); if(tile.getTeam() == players[0].getTeam() && tile.block().synthetic() && tile.block().viewRange > 0){ @@ -66,14 +68,14 @@ public class FogRenderer implements Disposable{ float vw = Core.camera.viewportWidth * Core.camera.zoom; float vh = Core.camera.viewportHeight * Core.camera.zoom; - float px = Core.camera.position.x -= vw/2f; - float py = Core.camera.position.y -= vh/2f; + float px = Core.camera.position.x -= vw / 2f; + float py = Core.camera.position.y -= vh / 2f; float u = px / tilesize / world.width(); float v = py / tilesize / world.height(); - float u2 = (px + vw)/ tilesize / world.width(); - float v2 = (py + vh)/ tilesize / world.height(); + float u2 = (px + vw) / tilesize / world.width(); + float v2 = (py + vh) / tilesize / world.height(); if(Core.batch instanceof ClipSpriteBatch){ ((ClipSpriteBatch) Core.batch).enableClip(false); @@ -137,7 +139,7 @@ public class FogRenderer implements Disposable{ } @Override - public void dispose() { + public void dispose(){ if(buffer != null) buffer.dispose(); } } diff --git a/core/src/io/anuke/mindustry/graphics/Layer.java b/core/src/io/anuke/mindustry/graphics/Layer.java index 3bf5949605..f04144a2cd 100644 --- a/core/src/io/anuke/mindustry/graphics/Layer.java +++ b/core/src/io/anuke/mindustry/graphics/Layer.java @@ -1,16 +1,28 @@ package io.anuke.mindustry.graphics; public enum Layer{ - /**Base block layer.*/ - block, - /**for placement*/ + /** + * Base block layer. + */ + block, + /** + * for placement + */ placement, - /**First overlay. Stuff like conveyor items.*/ - overlay, - /**"High" blocks, like turrets.*/ - turret, - /**Power lasers.*/ - power, - /**Extra lasers, like healing turrets.*/ - laser + /** + * First overlay. Stuff like conveyor items. + */ + overlay, + /** + * "High" blocks, like turrets. + */ + turret, + /** + * Power lasers. + */ + power, + /** + * Extra lasers, like healing turrets. + */ + laser } diff --git a/core/src/io/anuke/mindustry/graphics/MinimapRenderer.java b/core/src/io/anuke/mindustry/graphics/MinimapRenderer.java index 096c4455a7..2760dbdc78 100644 --- a/core/src/io/anuke/mindustry/graphics/MinimapRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/MinimapRenderer.java @@ -54,7 +54,7 @@ public class MinimapRenderer implements Disposable{ public void zoomBy(int amount){ zoom += amount; - zoom = Mathf.clamp(zoom, 1, Math.min(world.width(), world.height())/baseSize/2); + zoom = Mathf.clamp(zoom, 1, Math.min(world.width(), world.height()) / baseSize / 2); } public void reset(){ @@ -71,10 +71,10 @@ public class MinimapRenderer implements Disposable{ int sz = baseSize * zoom; float dx = (Core.camera.position.x / tilesize); float dy = (Core.camera.position.y / tilesize); - dx = Mathf.clamp(dx, sz, world.width()-sz); - dy = Mathf.clamp(dy, sz, world.height()-sz); + dx = Mathf.clamp(dx, sz, world.width() - sz); + dy = Mathf.clamp(dy, sz, world.height() - sz); - synchronized (units){ + synchronized(units){ rect.set((dx - sz) * tilesize, (dy - sz) * tilesize, sz * 2 * tilesize, sz * 2 * tilesize); Graphics.flush(); @@ -93,24 +93,24 @@ public class MinimapRenderer implements Disposable{ } } - public TextureRegion getRegion() { + public TextureRegion getRegion(){ if(texture == null) return null; int sz = Mathf.clamp(baseSize * zoom, baseSize, Math.min(world.width(), world.height())); float dx = (Core.camera.position.x / tilesize); float dy = (Core.camera.position.y / tilesize); - dx = Mathf.clamp(dx, sz, world.width()-sz); - dy = Mathf.clamp(dy, sz, world.height()-sz); + dx = Mathf.clamp(dx, sz, world.width() - sz); + dy = Mathf.clamp(dy, sz, world.height() - sz); float invTexWidth = 1f / texture.getWidth(); float invTexHeight = 1f / texture.getHeight(); - float x = dx - sz, y = world.height()-dy - sz, width = sz*2, height = sz*2; + float x = dx - sz, y = world.height() - dy - sz, width = sz * 2, height = sz * 2; region.setRegion(x * invTexWidth, y * invTexHeight, (x + width) * invTexWidth, (y + height) * invTexHeight); return region; } public void updateAll(){ - for(int x = 0; x < world.width(); x ++){ - for(int y = 0; y < world.height(); y ++){ + for(int x = 0; x < world.width(); x++){ + for(int y = 0; y < world.height(); y++){ pixmap.drawPixel(x, pixmap.getHeight() - 1 - y, colorFor(world.tile(x, y))); } } @@ -128,10 +128,10 @@ public class MinimapRenderer implements Disposable{ int sz = baseSize * zoom; float dx = (Core.camera.position.x / tilesize); float dy = (Core.camera.position.y / tilesize); - dx = Mathf.clamp(dx, sz, world.width()-sz); - dy = Mathf.clamp(dy, sz, world.height()-sz); + dx = Mathf.clamp(dx, sz, world.width() - sz); + dy = Mathf.clamp(dy, sz, world.height() - sz); - synchronized (units) { + synchronized(units){ rect.set((dx - sz) * tilesize, (dy - sz) * tilesize, sz * 2 * tilesize, sz * 2 * tilesize); units.clear(); Units.getNearby(rect, units::add); @@ -142,7 +142,7 @@ public class MinimapRenderer implements Disposable{ int color = tile.breakable() ? tile.target().getTeam().intColor : ColorMapper.getBlockColor(tile.block()); if(color == 0) color = ColorMapper.getBlockColor(tile.floor()); if(tile.elevation > 0){ - float mul = 1.1f+tile.elevation/4f; + float mul = 1.1f + tile.elevation / 4f; tmpColor.set(color); tmpColor.mul(mul, mul, mul, 1f); color = Color.rgba8888(tmpColor); @@ -151,7 +151,7 @@ public class MinimapRenderer implements Disposable{ } @Override - public void dispose() { + public void dispose(){ pixmap.dispose(); texture.dispose(); texture = null; diff --git a/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java b/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java index dd23a56dd5..d207cb61b4 100644 --- a/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java @@ -12,7 +12,6 @@ import io.anuke.mindustry.game.TeamInfo.TeamData; import io.anuke.mindustry.input.InputHandler; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; -import io.anuke.mindustry.world.consumers.Consume; import io.anuke.mindustry.world.meta.BlockBar; import io.anuke.ucore.core.Graphics; import io.anuke.ucore.core.Settings; @@ -25,10 +24,10 @@ import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.*; -public class OverlayRenderer { +public class OverlayRenderer{ public void drawBottom(){ - for(Player player : players) { + for(Player player : players){ InputHandler input = control.input(player.playerIndex); if(!input.isDrawing() || player.isDead()) continue; @@ -44,7 +43,7 @@ public class OverlayRenderer { public void drawTop(){ - for(Player player : players) { + for(Player player : players){ if(player.isDead()) continue; //dead player don't draw InputHandler input = control.input(player.playerIndex); @@ -53,7 +52,7 @@ public class OverlayRenderer { if(input.frag.config.isShown()){ Tile tile = input.frag.config.getSelectedTile(); - synchronized (Tile.tileSetLock) { + synchronized(Tile.tileSetLock){ tile.block().drawConfigure(tile); } } @@ -63,14 +62,14 @@ public class OverlayRenderer { Draw.reset(); //draw selected block bars and info - if (input.recipe == null && !ui.hasMouse() && !input.frag.config.isShown()) { + if(input.recipe == null && !ui.hasMouse() && !input.frag.config.isShown()){ Vector2 vec = Graphics.world(input.getMouseX(), input.getMouseY()); Tile tile = world.tileWorld(vec.x, vec.y); - if (tile != null && tile.block() != Blocks.air) { + if(tile != null && tile.block() != Blocks.air){ Tile target = tile.target(); - if (showBlockDebug && target.entity != null) { + if(showBlockDebug && target.entity != null){ Draw.color(Color.RED); Lines.crect(target.drawx(), target.drawy(), target.block().size * tilesize, target.block().size * tilesize); Vector2 v = new Vector2(); @@ -79,7 +78,7 @@ public class OverlayRenderer { Draw.tscl(0.25f); Array arr = target.block().getDebugInfo(target); StringBuilder result = new StringBuilder(); - for (int i = 0; i < arr.size / 2; i++) { + for(int i = 0; i < arr.size / 2; i++){ result.append(arr.get(i * 2)); result.append(": "); result.append(arr.get(i * 2 + 1)); @@ -93,27 +92,27 @@ public class OverlayRenderer { Draw.reset(); } - synchronized (Tile.tileSetLock) { + synchronized(Tile.tileSetLock){ Block block = target.block(); TileEntity entity = target.entity; - if (entity != null) { + if(entity != null){ int[] values = {0, 0}; boolean[] doDraw = {false}; Callable drawbars = () -> { - for (BlockBar bar : block.bars.list()) { + for(BlockBar bar : block.bars.list()){ float offset = Mathf.sign(bar.top) * (block.size / 2f * tilesize + 2f + (bar.top ? values[0] : values[1])); float value = bar.value.get(target); - if (MathUtils.isEqual(value, -1f)) continue; + if(MathUtils.isEqual(value, -1f)) continue; if(doDraw[0]){ drawBar(bar.type.color, target.drawx(), target.drawy() + offset, value); } - if (bar.top) + if(bar.top) values[0]++; else values[1]++; @@ -123,11 +122,11 @@ public class OverlayRenderer { drawbars.run(); if(values[0] > 0){ - drawEncloser(target.drawx(), target.drawy() + block.size * tilesize/2f + 2f, values[0]); + drawEncloser(target.drawx(), target.drawy() + block.size * tilesize / 2f + 2f, values[0]); } if(values[1] > 0){ - drawEncloser(target.drawx(), target.drawy() - block.size * tilesize/2f - 2f - values[1], values[1]); + drawEncloser(target.drawx(), target.drawy() - block.size * tilesize / 2f - 2f - values[1], values[1]); } doDraw[0] = true; @@ -143,7 +142,7 @@ public class OverlayRenderer { } } - if (input.isDroppingItem()) { + if(input.isDroppingItem()){ Vector2 v = Graphics.world(input.getMouseX(), input.getMouseY()); float size = 8; Draw.rect(player.inventory.getItem().item.region, v.x, v.y, size, size); @@ -152,8 +151,8 @@ public class OverlayRenderer { Draw.reset(); Tile tile = world.tileWorld(v.x, v.y); - if (tile != null) tile = tile.target(); - if (tile != null && tile.block().acceptStack(player.inventory.getItem().item, player.inventory.getItem().amount, tile, player) > 0) { + if(tile != null) tile = tile.target(); + if(tile != null && tile.block().acceptStack(player.inventory.getItem().item, player.inventory.getItem().amount, tile, player) > 0){ Draw.color(Palette.place); Lines.square(tile.drawx(), tile.drawy(), tile.block().size * tilesize / 2f + 1 + Mathf.absin(Timers.time(), 5f, 1f)); Draw.color(); @@ -177,9 +176,9 @@ public class OverlayRenderer { float x = unit.x; float y = unit.y; - if(unit == players[0] && players.length == 1 && snapCamera) { - x = (int)(x + 0.0001f); - y = (int)(y + 0.0001f); + if(unit == players[0] && players.length == 1 && snapCamera){ + x = (int) (x + 0.0001f); + y = (int) (y + 0.0001f); } drawEncloser(x, y - 9f, 2f); @@ -197,7 +196,7 @@ public class OverlayRenderer { float w = (int) (len * 2 * finion); Draw.color(Color.BLACK); - Fill.crect(x - len, y, len*2f, 1); + Fill.crect(x - len, y, len * 2f, 1); if(finion > 0){ Draw.color(color); Fill.crect(x - len, y, Math.max(1, w), 1); @@ -210,7 +209,7 @@ public class OverlayRenderer { float len = 4; Draw.color(Palette.bar); - Fill.crect(x - len, y - 1, len*2f, height + 2f); + Fill.crect(x - len, y - 1, len * 2f, height + 2f); Draw.color(); } } diff --git a/core/src/io/anuke/mindustry/graphics/Palette.java b/core/src/io/anuke/mindustry/graphics/Palette.java index b717d2441f..1f369df6f2 100644 --- a/core/src/io/anuke/mindustry/graphics/Palette.java +++ b/core/src/io/anuke/mindustry/graphics/Palette.java @@ -2,7 +2,7 @@ package io.anuke.mindustry.graphics; import com.badlogic.gdx.graphics.Color; -public class Palette { +public class Palette{ public static final Color bulletYellow = Color.valueOf("ffeec9"); public static final Color bulletYellowBack = Color.valueOf("f9c87a"); diff --git a/core/src/io/anuke/mindustry/graphics/Shaders.java b/core/src/io/anuke/mindustry/graphics/Shaders.java index 21c02966f5..996d8e07fe 100644 --- a/core/src/io/anuke/mindustry/graphics/Shaders.java +++ b/core/src/io/anuke/mindustry/graphics/Shaders.java @@ -13,100 +13,100 @@ import static io.anuke.mindustry.Vars.tilesize; import static io.anuke.mindustry.Vars.world; public class Shaders{ - public static Outline outline; + public static Outline outline; public static BlockBuild blockbuild; public static BlockPreview blockpreview; - public static Shield shield; - public static SurfaceShader water; - public static SurfaceShader lava; - public static SurfaceShader oil; - public static Space space; - public static UnitBuild build; - public static MixShader mix; - public static Shader fullMix; - public static FogShader fog; + public static Shield shield; + public static SurfaceShader water; + public static SurfaceShader lava; + public static SurfaceShader oil; + public static Space space; + public static UnitBuild build; + public static MixShader mix; + public static Shader fullMix; + public static FogShader fog; - public static void init(){ - outline = new Outline(); - blockbuild = new BlockBuild(); - blockpreview = new BlockPreview(); - shield = new Shield(); - water = new SurfaceShader("water"); - lava = new SurfaceShader("lava"); - oil = new SurfaceShader("oil"); - space = new Space(); - build = new UnitBuild(); - mix = new MixShader(); - fog = new FogShader(); - fullMix = new Shader("fullmix", "default"); - } + public static void init(){ + outline = new Outline(); + blockbuild = new BlockBuild(); + blockpreview = new BlockPreview(); + shield = new Shield(); + water = new SurfaceShader("water"); + lava = new SurfaceShader("lava"); + oil = new SurfaceShader("oil"); + space = new Space(); + build = new UnitBuild(); + mix = new MixShader(); + fog = new FogShader(); + fullMix = new Shader("fullmix", "default"); + } - public static class FogShader extends Shader{ - public FogShader(){ - super("fog", "default"); - } - } + public static class FogShader extends Shader{ + public FogShader(){ + super("fog", "default"); + } + } - public static class MixShader extends Shader{ - public Color color = new Color(Color.WHITE); + public static class MixShader extends Shader{ + public Color color = new Color(Color.WHITE); - public MixShader(){ - super("mix", "default"); - } + public MixShader(){ + super("mix", "default"); + } - @Override - public void apply() { - super.apply(); - shader.setUniformf("u_color", color); - } - } + @Override + public void apply(){ + super.apply(); + shader.setUniformf("u_color", color); + } + } - public static class Space extends SurfaceShader{ + public static class Space extends SurfaceShader{ - public Space(){ - super("space2"); - } + public Space(){ + super("space2"); + } - @Override - public void apply(){ - super.apply(); - shader.setUniformf("u_center", world.width() * tilesize/2f, world.height() * tilesize/2f); - } - } + @Override + public void apply(){ + super.apply(); + shader.setUniformf("u_center", world.width() * tilesize / 2f, world.height() * tilesize / 2f); + } + } - public static class UnitBuild extends Shader{ - public float progress, time; - public Color color = new Color(); - public TextureRegion region; + public static class UnitBuild extends Shader{ + public float progress, time; + public Color color = new Color(); + public TextureRegion region; - public UnitBuild() { - super("build", "default"); - } + public UnitBuild(){ + super("build", "default"); + } - @Override - public void apply(){ - shader.setUniformf("u_time", time); - shader.setUniformf("u_color", color); - shader.setUniformf("u_progress", progress); - shader.setUniformf("u_uv", region.getU(), region.getV()); - shader.setUniformf("u_uv2", region.getU2(), region.getV2()); - shader.setUniformf("u_texsize", region.getTexture().getWidth(), region.getTexture().getHeight()); - } - } + @Override + public void apply(){ + shader.setUniformf("u_time", time); + shader.setUniformf("u_color", color); + shader.setUniformf("u_progress", progress); + shader.setUniformf("u_uv", region.getU(), region.getV()); + shader.setUniformf("u_uv2", region.getU2(), region.getV2()); + shader.setUniformf("u_texsize", region.getTexture().getWidth(), region.getTexture().getHeight()); + } + } - public static class Outline extends Shader{ - public Color color = new Color(); + public static class Outline extends Shader{ + public Color color = new Color(); - public Outline(){ - super("outline", "default"); - } - - @Override - public void apply(){ - shader.setUniformf("u_color", color); - shader.setUniformf("u_texsize", region.getTexture().getWidth(), region.getTexture().getHeight()); - } - } + public Outline(){ + super("outline", "default"); + } + + @Override + public void apply(){ + shader.setUniformf("u_color", color); + shader.setUniformf("u_texsize", region.getTexture().getWidth(), region.getTexture().getHeight()); + } + } public static class BlockBuild extends Shader{ public Color color = new Color(); @@ -136,7 +136,7 @@ public class Shaders{ @Override public void apply(){ - // shader.setUniformf("u_progress", progress); + // shader.setUniformf("u_progress", progress); shader.setUniformf("u_color", color); shader.setUniformf("u_uv", region.getU(), region.getV()); shader.setUniformf("u_uv2", region.getU2(), region.getV2()); @@ -144,49 +144,49 @@ public class Shaders{ shader.setUniformf("u_texsize", region.getTexture().getWidth(), region.getTexture().getHeight()); } } - - public static class Shield extends Shader{ - public static final int MAX_HITS = 3*64; - public Color color = new Color(); - public FloatArray hits; - - public Shield(){ - super("shield", "default"); - } - - @Override - public void apply(){ - float scaling = Core.cameraScale / 4f / Core.camera.zoom; - if(hits.size > 0){ - shader.setUniform3fv("u_hits[0]", hits.items, 0, Math.min(hits.size, MAX_HITS)); - shader.setUniformi("u_hitamount", Math.min(hits.size, MAX_HITS)/3); - } - shader.setUniformf("u_dp", Unit.dp.scl(1f)); - shader.setUniformf("u_color", color); - shader.setUniformf("u_time", Timers.time() / Unit.dp.scl(1f)); - shader.setUniformf("u_scaling", scaling); - shader.setUniformf("u_offset", - Core.camera.position.x - Core.camera.viewportWidth/2 * Core.camera.zoom, - Core.camera.position.y - Core.camera.viewportHeight/2 * Core.camera.zoom); - shader.setUniformf("u_texsize", Gdx.graphics.getWidth() / Core.cameraScale * Core.camera.zoom, - Gdx.graphics.getHeight() / Core.cameraScale * Core.camera.zoom); - } - } - public static class SurfaceShader extends Shader{ + public static class Shield extends Shader{ + public static final int MAX_HITS = 3 * 64; + public Color color = new Color(); + public FloatArray hits; - public SurfaceShader(String frag){ - super(frag, "default"); - } + public Shield(){ + super("shield", "default"); + } - @Override - public void apply(){ - shader.setUniformf("camerapos", - Core.camera.position.x - Core.camera.viewportWidth/2 * Core.camera.zoom, - Core.camera.position.y - Core.camera.viewportHeight/2 * Core.camera.zoom); - shader.setUniformf("screensize", Gdx.graphics.getWidth() / Core.cameraScale * Core.camera.zoom, - Gdx.graphics.getHeight() / Core.cameraScale * Core.camera.zoom); - shader.setUniformf("time", Timers.time()); - } - } + @Override + public void apply(){ + float scaling = Core.cameraScale / 4f / Core.camera.zoom; + if(hits.size > 0){ + shader.setUniform3fv("u_hits[0]", hits.items, 0, Math.min(hits.size, MAX_HITS)); + shader.setUniformi("u_hitamount", Math.min(hits.size, MAX_HITS) / 3); + } + shader.setUniformf("u_dp", Unit.dp.scl(1f)); + shader.setUniformf("u_color", color); + shader.setUniformf("u_time", Timers.time() / Unit.dp.scl(1f)); + shader.setUniformf("u_scaling", scaling); + shader.setUniformf("u_offset", + Core.camera.position.x - Core.camera.viewportWidth / 2 * Core.camera.zoom, + Core.camera.position.y - Core.camera.viewportHeight / 2 * Core.camera.zoom); + shader.setUniformf("u_texsize", Gdx.graphics.getWidth() / Core.cameraScale * Core.camera.zoom, + Gdx.graphics.getHeight() / Core.cameraScale * Core.camera.zoom); + } + } + + public static class SurfaceShader extends Shader{ + + public SurfaceShader(String frag){ + super(frag, "default"); + } + + @Override + public void apply(){ + shader.setUniformf("camerapos", + Core.camera.position.x - Core.camera.viewportWidth / 2 * Core.camera.zoom, + Core.camera.position.y - Core.camera.viewportHeight / 2 * Core.camera.zoom); + shader.setUniformf("screensize", Gdx.graphics.getWidth() / Core.cameraScale * Core.camera.zoom, + Gdx.graphics.getHeight() / Core.cameraScale * Core.camera.zoom); + shader.setUniformf("time", Timers.time()); + } + } } diff --git a/core/src/io/anuke/mindustry/graphics/Trail.java b/core/src/io/anuke/mindustry/graphics/Trail.java index 0a21f06d3e..badf28a389 100644 --- a/core/src/io/anuke/mindustry/graphics/Trail.java +++ b/core/src/io/anuke/mindustry/graphics/Trail.java @@ -8,8 +8,10 @@ import io.anuke.ucore.graphics.Fill; import io.anuke.ucore.graphics.Lines; import io.anuke.ucore.util.Mathf; -/**Class that renders a trail.*/ -public class Trail { +/** + * Class that renders a trail. + */ +public class Trail{ private final static float maxJump = 15f; private final int length; private final FloatArray points = new FloatArray(); @@ -26,7 +28,7 @@ public class Trail { points.add(curx, cury); - if(points.size > length*2) { + if(points.size > length * 2){ float[] items = points.items; System.arraycopy(items, 2, items, 0, points.size - 2); points.size -= 2; @@ -48,14 +50,14 @@ public class Trail { float y = points.get(i + 1); float x2 = points.get(i + 2); float y2 = points.get(i + 3); - float s = Mathf.clamp((float)(i) / points.size); + float s = Mathf.clamp((float) (i) / points.size); Lines.stroke(s * stroke); Lines.line(x, y, x2, y2); } if(points.size >= 2){ - Fill.circle(points.get(points.size-2), points.get(points.size-1), stroke/2f); + Fill.circle(points.get(points.size - 2), points.get(points.size - 1), stroke / 2f); } Draw.reset(); diff --git a/core/src/io/anuke/mindustry/input/CursorType.java b/core/src/io/anuke/mindustry/input/CursorType.java index fd55b7998e..3b8773f6cb 100644 --- a/core/src/io/anuke/mindustry/input/CursorType.java +++ b/core/src/io/anuke/mindustry/input/CursorType.java @@ -3,8 +3,10 @@ package io.anuke.mindustry.input; import io.anuke.ucore.function.Callable; import io.anuke.ucore.scene.utils.Cursors; -/**Type of cursor for displaying on desktop.*/ -public enum CursorType { +/** + * Type of cursor for displaying on desktop. + */ +public enum CursorType{ normal(Cursors::restoreCursor), hand(Cursors::setHand), drill(() -> Cursors.set("drill")), @@ -16,7 +18,9 @@ public enum CursorType { this.call = call; } - /**Sets the current system cursor to this.*/ + /** + * Sets the current system cursor to this. + */ void set(){ call.run(); } diff --git a/core/src/io/anuke/mindustry/input/DefaultKeybinds.java b/core/src/io/anuke/mindustry/input/DefaultKeybinds.java index 4941ba130e..94e07bf924 100644 --- a/core/src/io/anuke/mindustry/input/DefaultKeybinds.java +++ b/core/src/io/anuke/mindustry/input/DefaultKeybinds.java @@ -8,58 +8,58 @@ import io.anuke.ucore.core.KeyBinds; import io.anuke.ucore.core.KeyBinds.Category; import io.anuke.ucore.input.Input; -public class DefaultKeybinds { +public class DefaultKeybinds{ public static void load(){ String[] sections = {"player_1"}; - for(String section : sections) { + for(String section : sections){ KeyBinds.defaultSection(section, DeviceType.keyboard, - new Category("General"), - "move_x", new Axis(Input.A, Input.D), - "move_y", new Axis(Input.S, Input.W), - //"select", Input.MOUSE_LEFT, - //"break", Input.MOUSE_RIGHT, - //"shoot", Input.MOUSE_LEFT, - "rotate", new Axis(Input.SCROLL), - "dash", Input.SHIFT_LEFT, - "drop_unit", Input.SHIFT_LEFT, - new Category("View"), - "zoom_hold", Input.CONTROL_LEFT, - "zoom", new Axis(Input.SCROLL), - "zoom_minimap", new Axis(Input.MINUS, Input.PLUS), - "menu", Gdx.app.getType() == ApplicationType.Android ? Input.BACK : Input.ESCAPE, - "pause", Input.SPACE, - "toggle_menus", Input.C, - new Category("Multiplayer"), - "player_list", Input.TAB, - "chat", Input.ENTER, - "chat_history_prev", Input.UP, - "chat_history_next", Input.DOWN, - "chat_scroll", new Axis(Input.SCROLL), - "console", Input.GRAVE + new Category("General"), + "move_x", new Axis(Input.A, Input.D), + "move_y", new Axis(Input.S, Input.W), + //"select", Input.MOUSE_LEFT, + //"break", Input.MOUSE_RIGHT, + //"shoot", Input.MOUSE_LEFT, + "rotate", new Axis(Input.SCROLL), + "dash", Input.SHIFT_LEFT, + "drop_unit", Input.SHIFT_LEFT, + new Category("View"), + "zoom_hold", Input.CONTROL_LEFT, + "zoom", new Axis(Input.SCROLL), + "zoom_minimap", new Axis(Input.MINUS, Input.PLUS), + "menu", Gdx.app.getType() == ApplicationType.Android ? Input.BACK : Input.ESCAPE, + "pause", Input.SPACE, + "toggle_menus", Input.C, + new Category("Multiplayer"), + "player_list", Input.TAB, + "chat", Input.ENTER, + "chat_history_prev", Input.UP, + "chat_history_next", Input.DOWN, + "chat_scroll", new Axis(Input.SCROLL), + "console", Input.GRAVE ); KeyBinds.defaultSection(section, DeviceType.controller, - new Category("General"), - "move_x", new Axis(Input.CONTROLLER_L_STICK_HORIZONTAL_AXIS), - "move_y", new Axis(Input.CONTROLLER_L_STICK_VERTICAL_AXIS), - "cursor_x", new Axis(Input.CONTROLLER_R_STICK_HORIZONTAL_AXIS), - "cursor_y", new Axis(Input.CONTROLLER_R_STICK_VERTICAL_AXIS), - //"select", Input.CONTROLLER_R_BUMPER, - //"break", Input.CONTROLLER_L_BUMPER, - //"shoot", Input.CONTROLLER_R_TRIGGER, - "dash", Input.CONTROLLER_Y, - "rotate_alt", new Axis(Input.CONTROLLER_DPAD_RIGHT, Input.CONTROLLER_DPAD_LEFT), - "rotate", new Axis(Input.CONTROLLER_A, Input.CONTROLLER_B), - new Category("View"), - "zoom_hold", Input.ANY_KEY, - "zoom", new Axis(Input.CONTROLLER_DPAD_DOWN, Input.CONTROLLER_DPAD_UP), - "menu", Input.CONTROLLER_X, - "pause", Input.CONTROLLER_L_TRIGGER, - new Category("Multiplayer"), - "player_list", Input.CONTROLLER_START + new Category("General"), + "move_x", new Axis(Input.CONTROLLER_L_STICK_HORIZONTAL_AXIS), + "move_y", new Axis(Input.CONTROLLER_L_STICK_VERTICAL_AXIS), + "cursor_x", new Axis(Input.CONTROLLER_R_STICK_HORIZONTAL_AXIS), + "cursor_y", new Axis(Input.CONTROLLER_R_STICK_VERTICAL_AXIS), + //"select", Input.CONTROLLER_R_BUMPER, + //"break", Input.CONTROLLER_L_BUMPER, + //"shoot", Input.CONTROLLER_R_TRIGGER, + "dash", Input.CONTROLLER_Y, + "rotate_alt", new Axis(Input.CONTROLLER_DPAD_RIGHT, Input.CONTROLLER_DPAD_LEFT), + "rotate", new Axis(Input.CONTROLLER_A, Input.CONTROLLER_B), + new Category("View"), + "zoom_hold", Input.ANY_KEY, + "zoom", new Axis(Input.CONTROLLER_DPAD_DOWN, Input.CONTROLLER_DPAD_UP), + "menu", Input.CONTROLLER_X, + "pause", Input.CONTROLLER_L_TRIGGER, + new Category("Multiplayer"), + "player_list", Input.CONTROLLER_START ); } diff --git a/core/src/io/anuke/mindustry/input/DesktopInput.java b/core/src/io/anuke/mindustry/input/DesktopInput.java index dc1d462627..a156939e1a 100644 --- a/core/src/io/anuke/mindustry/input/DesktopInput.java +++ b/core/src/io/anuke/mindustry/input/DesktopInput.java @@ -27,40 +27,49 @@ import static io.anuke.mindustry.input.CursorType.*; import static io.anuke.mindustry.input.PlaceMode.*; public class DesktopInput extends InputHandler{ - //controller info - private float controlx, controly; - private boolean controlling; private final String section; - - /**Current cursor type.*/ + //controller info + private float controlx, controly; + private boolean controlling; + /** + * Current cursor type. + */ private CursorType cursorType = normal; - /**Position where the player started dragging a line.*/ + /** + * Position where the player started dragging a line. + */ private int selectX, selectY; - /**Whether selecting mode is active.*/ + /** + * Whether selecting mode is active. + */ private PlaceMode mode; - /**Animation scale for line.*/ + /** + * Animation scale for line. + */ private float selectScale; - public DesktopInput(Player player){ - super(player); - this.section = "player_" + (player.playerIndex + 1); + public DesktopInput(Player player){ + super(player); + this.section = "player_" + (player.playerIndex + 1); } - /**Draws a placement icon for a specific block.*/ - void drawPlace(int x, int y, Block block, int rotation){ + /** + * Draws a placement icon for a specific block. + */ + void drawPlace(int x, int y, Block block, int rotation){ if(validPlace(x, y, block, rotation)){ Draw.color(); TextureRegion[] regions = block.getBlockIcon(); for(TextureRegion region : regions){ - Draw.rect(region, x *tilesize + block.offset(), y * tilesize + block.offset(), + Draw.rect(region, x * tilesize + block.offset(), y * tilesize + block.offset(), region.getRegionWidth() * selectScale, region.getRegionHeight() * selectScale, block.rotate ? rotation * 90 : 0); } }else{ Draw.color(Palette.remove); - Lines.square(x*tilesize + block.offset(), y*tilesize + block.offset(), block.size * tilesize/2f); + Lines.square(x * tilesize + block.offset(), y * tilesize + block.offset(), block.size * tilesize / 2f); } } @@ -75,15 +84,15 @@ public class DesktopInput extends InputHandler{ if(cursor == null) return; - //draw selection(s) - if(mode == placing) { + //draw selection(s) + if(mode == placing){ NormalizeResult result = PlaceUtils.normalizeArea(selectX, selectY, cursor.x, cursor.y, rotation, true, maxLength); - for (int i = 0; i <= result.getLength(); i += recipe.result.size) { + for(int i = 0; i <= result.getLength(); i += recipe.result.size){ int x = selectX + i * Mathf.sign(cursor.x - selectX) * Mathf.bool(result.isX()); int y = selectY + i * Mathf.sign(cursor.y - selectY) * Mathf.bool(!result.isX()); - if (i + recipe.result.size > result.getLength() && recipe.result.rotate) { + if(i + recipe.result.size > result.getLength() && recipe.result.rotate){ Draw.color(!validPlace(x, y, recipe.result, result.rotation) ? Palette.remove : Palette.placeRotate); Draw.grect("place-arrow", x * tilesize + recipe.result.offset(), y * tilesize + recipe.result.offset(), result.rotation * 90 - 90); @@ -99,37 +108,37 @@ public class DesktopInput extends InputHandler{ Draw.color(Palette.remove); - for(int x = dresult.x; x <= dresult.x2; x ++){ - for(int y = dresult.y; y <= dresult.y2; y ++){ + for(int x = dresult.x; x <= dresult.x2; x++){ + for(int y = dresult.y; y <= dresult.y2; y++){ Tile tile = world.tile(x, y); if(tile == null || !validBreak(tile.x, tile.y)) continue; tile = tile.target(); - Lines.poly(tile.drawx(), tile.drawy(), 4, tile.block().size * tilesize/2f, 45 + 15); + Lines.poly(tile.drawx(), tile.drawy(), 4, tile.block().size * tilesize / 2f, 45 + 15); } } Lines.rect(result.x, result.y, result.x2 - result.x, result.y2 - result.y); }else if(isPlacing()){ - if(recipe.result.rotate){ - Draw.color(!validPlace(cursor.x, cursor.y, recipe.result, rotation) ? Palette.remove : Palette.placeRotate); - Draw.grect("place-arrow", cursor.worldx() + recipe.result.offset(), + if(recipe.result.rotate){ + Draw.color(!validPlace(cursor.x, cursor.y, recipe.result, rotation) ? Palette.remove : Palette.placeRotate); + Draw.grect("place-arrow", cursor.worldx() + recipe.result.offset(), cursor.worldy() + recipe.result.offset(), rotation * 90 - 90); } drawPlace(cursor.x, cursor.y, recipe.result, rotation); - recipe.result.drawPlace(cursor.x, cursor.y, rotation, validPlace(cursor.x, cursor.y, recipe.result, rotation)); + recipe.result.drawPlace(cursor.x, cursor.y, rotation, validPlace(cursor.x, cursor.y, recipe.result, rotation)); } Draw.reset(); } - @Override - public void update(){ + @Override + public void update(){ if(Net.active() && Inputs.keyTap("player_list")){ ui.listfrag.toggle(); } - if(player.isDead() || state.is(State.menu) || ui.hasDialog()) return; + if(player.isDead() || state.is(State.menu) || ui.hasDialog()) return; if(recipe != null && !Settings.getBool("desktop-place-help", false)){ ui.showInfo("Desktop controls have been changed.\nTo deselect a block or stop building, [accent]use the middle mouse button[]."); @@ -137,40 +146,40 @@ public class DesktopInput extends InputHandler{ Settings.save(); } - player.isBoosting = Inputs.keyDown("dash"); + player.isBoosting = Inputs.keyDown("dash"); - //deslect if not placing - if(!isPlacing() && mode == placing){ - mode = none; + //deslect if not placing + if(!isPlacing() && mode == placing){ + mode = none; } if(player.isShooting && !canShoot()){ - player.isShooting = false; + player.isShooting = false; } if(isPlacing()){ cursorType = hand; selectScale = Mathf.lerpDelta(selectScale, 1f, 0.2f); }else{ - selectScale = 0f; + selectScale = 0f; } - boolean controller = KeyBinds.getSection(section).device.type == DeviceType.controller; + boolean controller = KeyBinds.getSection(section).device.type == DeviceType.controller; - //zoom and rotate things - if(Inputs.getAxisActive("zoom") && (Inputs.keyDown(section,"zoom_hold") || controller)){ - renderer.scaleCamera((int) Inputs.getAxisTapped(section, "zoom")); - } + //zoom and rotate things + if(Inputs.getAxisActive("zoom") && (Inputs.keyDown(section, "zoom_hold") || controller)){ + renderer.scaleCamera((int) Inputs.getAxisTapped(section, "zoom")); + } - renderer.minimap().zoomBy(-(int)Inputs.getAxisTapped(section,"zoom_minimap")); - rotation = Mathf.mod(rotation + (int)Inputs.getAxisTapped(section,"rotate"), 4); + renderer.minimap().zoomBy(-(int) Inputs.getAxisTapped(section, "zoom_minimap")); + rotation = Mathf.mod(rotation + (int) Inputs.getAxisTapped(section, "rotate"), 4); - Tile cursor = tileAt(control.gdxInput().getX(), control.gdxInput().getY()); + Tile cursor = tileAt(control.gdxInput().getX(), control.gdxInput().getY()); - if(player.isDead()){ + if(player.isDead()){ cursorType = normal; }else if(cursor != null){ - cursor = cursor.target(); + cursor = cursor.target(); cursorType = cursor.block().getCursor(cursor); @@ -187,15 +196,15 @@ public class DesktopInput extends InputHandler{ } } - if(!ui.hasMouse()) { - cursorType.set(); - } + if(!ui.hasMouse()){ + cursorType.set(); + } cursorType = normal; - } + } - @Override - public boolean touchDown (int screenX, int screenY, int pointer, int button) { + @Override + public boolean touchDown(int screenX, int screenY, int pointer, int button){ if(player.isDead() || state.is(State.menu) || ui.hasDialog() || ui.hasMouse()) return false; Tile cursor = tileAt(screenX, screenY); @@ -203,12 +212,12 @@ public class DesktopInput extends InputHandler{ float worldx = Graphics.world(screenX, screenY).x, worldy = Graphics.world(screenX, screenY).y; - if(button == Buttons.LEFT) { //left = begin placing - if (isPlacing()) { + if(button == Buttons.LEFT){ //left = begin placing + if(isPlacing()){ selectX = cursor.x; selectY = cursor.y; mode = placing; - } else { + }else{ //only begin shooting if there's no cursor event if(!tileTapped(cursor) && !tryTapPlayer(worldx, worldy) && player.getPlaceQueue().size == 0 && !droppingItem && !tryBeginMine(cursor) && player.getMineTile() == null){ @@ -232,7 +241,7 @@ public class DesktopInput extends InputHandler{ } @Override - public boolean touchUp (int screenX, int screenY, int pointer, int button) { + public boolean touchUp(int screenX, int screenY, int pointer, int button){ if(button == Buttons.LEFT){ player.isShooting = false; } @@ -260,8 +269,8 @@ public class DesktopInput extends InputHandler{ }else if(mode == breaking){ //touch up while breaking, break everything in selection NormalizeResult result = PlaceUtils.normalizeArea(selectX, selectY, cursor.x, cursor.y, rotation, false, maxLength); - for(int x = 0; x <= Math.abs(result.x2 - result.x); x ++ ){ - for(int y = 0; y <= Math.abs(result.y2 - result.y); y ++){ + for(int x = 0; x <= Math.abs(result.x2 - result.x); x++){ + for(int y = 0; y <= Math.abs(result.y2 - result.y); y++){ int wx = selectX + x * Mathf.sign(cursor.x - selectX); int wy = selectY + y * Mathf.sign(cursor.y - selectY); @@ -278,23 +287,23 @@ public class DesktopInput extends InputHandler{ } @Override - public float getMouseX() { + public float getMouseX(){ return !controlling ? control.gdxInput().getX() : controlx; } @Override - public float getMouseY() { + public float getMouseY(){ return !controlling ? control.gdxInput().getY() : controly; } @Override - public boolean isCursorVisible() { + public boolean isCursorVisible(){ return controlling; } @Override public void updateController(){ - boolean mousemove = Gdx.input.getDeltaX() > 1 || Gdx.input.getDeltaY() > 1; + boolean mousemove = Gdx.input.getDeltaX() > 1 || Gdx.input.getDeltaY() > 1; if(KeyBinds.getSection(section).device.type == DeviceType.controller && (!mousemove || player.playerIndex > 0)){ if(player.playerIndex > 0){ @@ -312,17 +321,17 @@ public class DesktopInput extends InputHandler{ float xa = Inputs.getAxis(section, "cursor_x"); float ya = Inputs.getAxis(section, "cursor_y"); - if(Math.abs(xa) > controllerMin || Math.abs(ya) > controllerMin) { - float scl = Settings.getInt("sensitivity", 100)/100f * Unit.dp.scl(1f); - controlx += xa*baseControllerSpeed*scl; - controly -= ya*baseControllerSpeed*scl; + if(Math.abs(xa) > controllerMin || Math.abs(ya) > controllerMin){ + float scl = Settings.getInt("sensitivity", 100) / 100f * Unit.dp.scl(1f); + controlx += xa * baseControllerSpeed * scl; + controly -= ya * baseControllerSpeed * scl; controlling = true; if(player.playerIndex == 0){ Gdx.input.setCursorCatched(true); } - Inputs.getProcessor().touchDragged((int)getMouseX(), (int)getMouseY(), player.playerIndex); + Inputs.getProcessor().touchDragged((int) getMouseX(), (int) getMouseY(), player.playerIndex); } controlx = Mathf.clamp(controlx, 0, Gdx.graphics.getWidth()); diff --git a/core/src/io/anuke/mindustry/input/InputHandler.java b/core/src/io/anuke/mindustry/input/InputHandler.java index 689a637db1..b3f094a889 100644 --- a/core/src/io/anuke/mindustry/input/InputHandler.java +++ b/core/src/io/anuke/mindustry/input/InputHandler.java @@ -33,226 +33,307 @@ import io.anuke.ucore.util.Translator; import static io.anuke.mindustry.Vars.*; public abstract class InputHandler extends InputAdapter{ - /**Used for dropping items.*/ + /** + * Used for dropping items. + */ final static float playerSelectRange = mobile ? 17f : 11f; - /**Maximum line length.*/ - final static int maxLength = 100; + /** + * Maximum line length. + */ + final static int maxLength = 100; final static Translator stackTrns = new Translator(); - /**Distance on the back from where items originate.*/ - final static float backTrns = 3f; + /** + * Distance on the back from where items originate. + */ + final static float backTrns = 3f; - public final Player player; - public final String section; - public final OverlayFragment frag = new OverlayFragment(this); + public final Player player; + public final String section; + public final OverlayFragment frag = new OverlayFragment(this); - public Recipe recipe; - public int rotation; - public boolean droppingItem; + public Recipe recipe; + public int rotation; + public boolean droppingItem; - public InputHandler(Player player){ - this.player = player; - this.section = "player_" + (player.playerIndex + 1); - Timers.run(1f, () -> frag.build(Core.scene.getRoot())); + public InputHandler(Player player){ + this.player = player; + this.section = "player_" + (player.playerIndex + 1); + Timers.run(1f, () -> frag.build(Core.scene.getRoot())); } //methods to override - public void update(){ + @Remote(targets = Loc.client, called = Loc.server, in = In.entities) + public static void dropItem(Player player, float angle){ + if(Net.server() && !player.inventory.hasItem()){ + throw new ValidateException(player, "Player cannot drop an item."); + } - } - - public float getMouseX(){ - return control.gdxInput().getX(); - } - - public float getMouseY(){ - return control.gdxInput().getY(); + ItemDrop.create(player.inventory.getItem().item, player.inventory.getItem().amount, player.x, player.y, angle); + player.inventory.clearItem(); } - public void resetCursor(){ + @Remote(targets = Loc.both, forward = true, called = Loc.server, in = In.blocks) + public static void transferInventory(Player player, Tile tile){ + if(Net.server() && (!player.inventory.hasItem() || player.isTransferring)){ + throw new ValidateException(player, "Player cannot transfer an item."); + } - } + threads.run(() -> { + if(player == null || tile.entity == null) return; - public boolean isCursorVisible(){ - return false; - } + player.isTransferring = true; - public void buildUI(Group group){ + ItemStack stack = player.inventory.getItem(); + int accepted = tile.block().acceptStack(stack.item, stack.amount, tile, player); - } + boolean clear = stack.amount == accepted; + int sent = Mathf.clamp(accepted / 4, 1, 8); + int removed = accepted / sent; + int[] remaining = {accepted, accepted}; - public void updateController(){ + for(int i = 0; i < sent; i++){ + boolean end = i == sent - 1; + Timers.run(i * 3, () -> { + tile.block().getStackOffset(stack.item, tile, stackTrns); - } + ItemTransfer.create(stack.item, + player.x + Angles.trnsx(player.rotation + 180f, backTrns), player.y + Angles.trnsy(player.rotation + 180f, backTrns), + new Translator(tile.drawx() + stackTrns.x, tile.drawy() + stackTrns.y), () -> { - public void drawOutlined(){ + tile.block().handleStack(stack.item, removed, tile, player); + remaining[1] -= removed; - } + if(end && remaining[1] > 0){ + tile.block().handleStack(stack.item, remaining[1], tile, player); + } + }); - public void drawTop(){ + stack.amount -= removed; + remaining[0] -= removed; - } + if(end){ + stack.amount -= remaining[0]; + if(clear){ + player.inventory.clearItem(); + } + player.isTransferring = false; + } + }); + } + }); + } - public boolean isDrawing(){ - return false; - } + @Remote(targets = Loc.both, called = Loc.server, forward = true, in = In.blocks) + public static void onTileTapped(Player player, Tile tile){ + if(tile == null || player == null) return; + tile.block().tapped(tile, player); + } - /**Handles tile tap events that are not platform specific.*/ - boolean tileTapped(Tile tile){ - tile = tile.target(); + public void update(){ - boolean consumed = false, showedInventory = false, showedConsume = false; + } - //check if tapped block is configurable - if(tile.block().configurable && tile.getTeam() == player.getTeam()){ - consumed = true; - if(((!frag.config.isShown() && tile.block().shouldShowConfigure(tile, player)) //if the config fragment is hidden, show - //alternatively, the current selected block can 'agree' to switch config tiles - || (frag.config.isShown() && frag.config.getSelectedTile().block().onConfigureTileTapped(frag.config.getSelectedTile(), tile)))) { - frag.config.showConfig(tile); - } - //otherwise... - }else if(!frag.config.hasConfigMouse()){ //make sure a configuration fragment isn't on the cursor - //then, if it's shown and the current block 'agrees' to hide, hide it. - if(frag.config.isShown() && frag.config.getSelectedTile().block().onConfigureTileTapped(frag.config.getSelectedTile(), tile)) { - consumed = true; - frag.config.hideConfig(); - } - } + public float getMouseX(){ + return control.gdxInput().getX(); + } - //call tapped event - if(tile.getTeam() == player.getTeam()){ - CallBlocks.onTileTapped(player, tile); - } + public float getMouseY(){ + return control.gdxInput().getY(); + } - //consume tap event if necessary - if(tile.getTeam() == player.getTeam() && tile.block().consumesTap){ - consumed = true; - }else if(tile.getTeam() == player.getTeam() && tile.block().synthetic() && !consumed) { - if(tile.block().hasItems && tile.entity.items.total() > 0) { - frag.inv.showFor(tile); - consumed = true; - showedInventory = true; - } + public void resetCursor(){ - if(tile.block().consumes.hasAny()){ - frag.consume.show(tile); - consumed = true; - showedConsume = true; - } - } + } - if(!showedInventory){ - frag.inv.hide(); - } + public boolean isCursorVisible(){ + return false; + } + + public void buildUI(Group group){ + + } + + public void updateController(){ + + } + + public void drawOutlined(){ + + } + + public void drawTop(){ + + } + + public boolean isDrawing(){ + return false; + } + + /** + * Handles tile tap events that are not platform specific. + */ + boolean tileTapped(Tile tile){ + tile = tile.target(); + + boolean consumed = false, showedInventory = false, showedConsume = false; + + //check if tapped block is configurable + if(tile.block().configurable && tile.getTeam() == player.getTeam()){ + consumed = true; + if(((!frag.config.isShown() && tile.block().shouldShowConfigure(tile, player)) //if the config fragment is hidden, show + //alternatively, the current selected block can 'agree' to switch config tiles + || (frag.config.isShown() && frag.config.getSelectedTile().block().onConfigureTileTapped(frag.config.getSelectedTile(), tile)))){ + frag.config.showConfig(tile); + } + //otherwise... + }else if(!frag.config.hasConfigMouse()){ //make sure a configuration fragment isn't on the cursor + //then, if it's shown and the current block 'agrees' to hide, hide it. + if(frag.config.isShown() && frag.config.getSelectedTile().block().onConfigureTileTapped(frag.config.getSelectedTile(), tile)){ + consumed = true; + frag.config.hideConfig(); + } + } + + //call tapped event + if(tile.getTeam() == player.getTeam()){ + CallBlocks.onTileTapped(player, tile); + } + + //consume tap event if necessary + if(tile.getTeam() == player.getTeam() && tile.block().consumesTap){ + consumed = true; + }else if(tile.getTeam() == player.getTeam() && tile.block().synthetic() && !consumed){ + if(tile.block().hasItems && tile.entity.items.total() > 0){ + frag.inv.showFor(tile); + consumed = true; + showedInventory = true; + } + + if(tile.block().consumes.hasAny()){ + frag.consume.show(tile); + consumed = true; + showedConsume = true; + } + } + + if(!showedInventory){ + frag.inv.hide(); + } if(!showedConsume){ frag.consume.hide(); } - return consumed; - } + return consumed; + } - /**Tries to select the player to drop off items, returns true if successful.*/ - boolean tryTapPlayer(float x, float y){ - if(canTapPlayer(x, y)){ - droppingItem = true; - return true; - } - return false; - } + /** + * Tries to select the player to drop off items, returns true if successful. + */ + boolean tryTapPlayer(float x, float y){ + if(canTapPlayer(x, y)){ + droppingItem = true; + return true; + } + return false; + } - boolean canTapPlayer(float x, float y){ - return Vector2.dst(x, y, player.x, player.y) <= playerSelectRange && player.inventory.hasItem(); - } + boolean canTapPlayer(float x, float y){ + return Vector2.dst(x, y, player.x, player.y) <= playerSelectRange && player.inventory.hasItem(); + } - /**Tries to begin mining a tile, returns true if successful.*/ - boolean tryBeginMine(Tile tile){ - if(canMine(tile)){ - //if a block is clicked twice, reset it - player.setMineTile(player.getMineTile() == tile ? null : tile); - return true; - } - return false; - } + /** + * Tries to begin mining a tile, returns true if successful. + */ + boolean tryBeginMine(Tile tile){ + if(canMine(tile)){ + //if a block is clicked twice, reset it + player.setMineTile(player.getMineTile() == tile ? null : tile); + return true; + } + return false; + } - boolean canMine(Tile tile){ - return !ui.hasMouse() - && tile.floor().drops != null && tile.floor().drops.item.hardness <= player.mech.drillPower - && !tile.floor().playerUnmineable - && player.inventory.canAcceptItem(tile.floor().drops.item) - && Units.getClosestEnemy(player.getTeam(), tile.worldx(), tile.worldy(), 40f, e -> true) == null //don't being mining when an enemy is near - && tile.block() == Blocks.air && player.distanceTo(tile.worldx(), tile.worldy()) <= Player.mineDistance; - } + boolean canMine(Tile tile){ + return !ui.hasMouse() + && tile.floor().drops != null && tile.floor().drops.item.hardness <= player.mech.drillPower + && !tile.floor().playerUnmineable + && player.inventory.canAcceptItem(tile.floor().drops.item) + && Units.getClosestEnemy(player.getTeam(), tile.worldx(), tile.worldy(), 40f, e -> true) == null //don't being mining when an enemy is near + && tile.block() == Blocks.air && player.distanceTo(tile.worldx(), tile.worldy()) <= Player.mineDistance; + } - /**Returns the tile at the specified MOUSE coordinates.*/ - Tile tileAt(float x, float y){ - Vector2 vec = Graphics.world(x, y); - if(isPlacing()){ - vec.sub(recipe.result.offset(), recipe.result.offset()); - } - return world.tileWorld(vec.x, vec.y); - } + /** + * Returns the tile at the specified MOUSE coordinates. + */ + Tile tileAt(float x, float y){ + Vector2 vec = Graphics.world(x, y); + if(isPlacing()){ + vec.sub(recipe.result.offset(), recipe.result.offset()); + } + return world.tileWorld(vec.x, vec.y); + } - public boolean isPlacing(){ - return recipe != null; - } + public boolean isPlacing(){ + return recipe != null; + } - public float mouseAngle(float x, float y){ + public float mouseAngle(float x, float y){ return Graphics.world(getMouseX(), getMouseY()).sub(x, y).angle(); } - public void remove(){ - Inputs.removeProcessor(this); - frag.remove(); + public void remove(){ + Inputs.removeProcessor(this); + frag.remove(); } - public boolean canShoot(){ - return recipe == null && !ui.hasMouse() && !onConfigurable() && !isDroppingItem(); - } - - public boolean onConfigurable(){ - return false; - } + public boolean canShoot(){ + return recipe == null && !ui.hasMouse() && !onConfigurable() && !isDroppingItem(); + } - public boolean isDroppingItem(){ - return droppingItem; - } + public boolean onConfigurable(){ + return false; + } - public void tryDropItems(Tile tile, float x, float y){ - if(!droppingItem || !player.inventory.hasItem() || canTapPlayer(x, y)){ - droppingItem = false; - return; - } + public boolean isDroppingItem(){ + return droppingItem; + } - droppingItem = false; + public void tryDropItems(Tile tile, float x, float y){ + if(!droppingItem || !player.inventory.hasItem() || canTapPlayer(x, y)){ + droppingItem = false; + return; + } - ItemStack stack = player.inventory.getItem(); + droppingItem = false; - if(tile.block().acceptStack(stack.item, stack.amount, tile, player) > 0 && tile.block().hasItems){ - CallBlocks.transferInventory(player, tile); - }else{ - CallEntity.dropItem(player.angleTo(x, y)); - } - } + ItemStack stack = player.inventory.getItem(); - public boolean cursorNear(){ - return true; - } - - public void tryPlaceBlock(int x, int y){ - if(recipe != null && validPlace(x, y, recipe.result, rotation) && cursorNear()){ - placeBlock(x, y, recipe, rotation); - } - } - - public void tryBreakBlock(int x, int y){ - if(cursorNear() && validBreak(x, y)){ - breakBlock(x, y); - } - } - - public boolean validPlace(int x, int y, Block type, int rotation){ + if(tile.block().acceptStack(stack.item, stack.amount, tile, player) > 0 && tile.block().hasItems){ + CallBlocks.transferInventory(player, tile); + }else{ + CallEntity.dropItem(player.angleTo(x, y)); + } + } + + public boolean cursorNear(){ + return true; + } + + public void tryPlaceBlock(int x, int y){ + if(recipe != null && validPlace(x, y, recipe.result, rotation) && cursorNear()){ + placeBlock(x, y, recipe, rotation); + } + } + + public void tryBreakBlock(int x, int y){ + if(cursorNear() && validBreak(x, y)){ + breakBlock(x, y); + } + } + + public boolean validPlace(int x, int y, Block type, int rotation){ for(Tile tile : state.teams.get(player.getTeam()).cores){ if(tile.distanceTo(x * tilesize, y * tilesize) < coreBuildRange){ return Build.validPlace(player.getTeam(), x, y, type, rotation) && @@ -261,89 +342,22 @@ public abstract class InputHandler extends InputAdapter{ } return false; - } - - public boolean validBreak(int x, int y){ - return Build.validBreak(player.getTeam(), x, y); - } - - public void placeBlock(int x, int y, Recipe recipe, int rotation){ + } + + public boolean validBreak(int x, int y){ + return Build.validBreak(player.getTeam(), x, y); + } + + public void placeBlock(int x, int y, Recipe recipe, int rotation){ //todo multiplayer support player.addBuildRequest(new BuildRequest(x, y, rotation, recipe)); - } + } - public void breakBlock(int x, int y){ + public void breakBlock(int x, int y){ - //todo multiplayer support - Tile tile = world.tile(x, y).target(); - player.addBuildRequest(new BuildRequest(tile.x, tile.y)); - } - - @Remote(targets = Loc.client, called = Loc.server, in = In.entities) - public static void dropItem(Player player, float angle){ - if(Net.server() && !player.inventory.hasItem()){ - throw new ValidateException(player, "Player cannot drop an item."); - } - - ItemDrop.create(player.inventory.getItem().item, player.inventory.getItem().amount, player.x, player.y, angle); - player.inventory.clearItem(); - } - - @Remote(targets = Loc.both, forward = true, called = Loc.server, in = In.blocks) - public static void transferInventory(Player player, Tile tile){ - if(Net.server() && (!player.inventory.hasItem() || player.isTransferring)) { - throw new ValidateException(player, "Player cannot transfer an item."); - } - - threads.run(() -> { - if (player == null || tile.entity == null) return; - - player.isTransferring = true; - - ItemStack stack = player.inventory.getItem(); - int accepted = tile.block().acceptStack(stack.item, stack.amount, tile, player); - - boolean clear = stack.amount == accepted; - int sent = Mathf.clamp(accepted / 4, 1, 8); - int removed = accepted / sent; - int[] remaining = {accepted, accepted}; - - for (int i = 0; i < sent; i++) { - boolean end = i == sent - 1; - Timers.run(i * 3, () -> { - tile.block().getStackOffset(stack.item, tile, stackTrns); - - ItemTransfer.create(stack.item, - player.x + Angles.trnsx(player.rotation + 180f, backTrns), player.y + Angles.trnsy(player.rotation + 180f, backTrns), - new Translator(tile.drawx() + stackTrns.x, tile.drawy() + stackTrns.y), () -> { - - tile.block().handleStack(stack.item, removed, tile, player); - remaining[1] -= removed; - - if (end && remaining[1] > 0) { - tile.block().handleStack(stack.item, remaining[1], tile, player); - } - }); - - stack.amount -= removed; - remaining[0] -= removed; - - if (end) { - stack.amount -= remaining[0]; - if (clear) { - player.inventory.clearItem(); - } - player.isTransferring = false; - } - }); - } - }); - } - - @Remote(targets = Loc.both, called = Loc.server, forward = true, in = In.blocks) - public static void onTileTapped(Player player, Tile tile){ - if(tile == null || player == null) return; - tile.block().tapped(tile, player); - } + //todo multiplayer support + Tile tile = world.tile(x, y).target(); + player.addBuildRequest(new BuildRequest(tile.x, tile.y)); + } } diff --git a/core/src/io/anuke/mindustry/input/MobileInput.java b/core/src/io/anuke/mindustry/input/MobileInput.java index 9a260cf94d..4094aa118f 100644 --- a/core/src/io/anuke/mindustry/input/MobileInput.java +++ b/core/src/io/anuke/mindustry/input/MobileInput.java @@ -39,11 +39,14 @@ import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.input.PlaceMode.*; public class MobileInput extends InputHandler implements GestureListener{ - private static Rectangle r1 = new Rectangle(), r2 = new Rectangle(); - - /**Maximum speed the player can pan.*/ + /** + * Maximum speed the player can pan. + */ private static final float maxPanSpeed = 1.3f; - /**Distance to edge of screen to start panning.*/ + private static Rectangle r1 = new Rectangle(), r2 = new Rectangle(); + /** + * Distance to edge of screen to start panning. + */ private final float edgePan = io.anuke.ucore.scene.ui.layout.Unit.dp.scl(60f); //gesture data @@ -51,64 +54,92 @@ public class MobileInput extends InputHandler implements GestureListener{ private Vector2 vector = new Vector2(); private float initzoom = -1; private boolean zoomed = false; - /**Set of completed guides.*/ + /** + * Set of completed guides. + */ private ObjectSet guides = new ObjectSet<>(); - /**Position where the player started dragging a line.*/ + /** + * Position where the player started dragging a line. + */ private int lineStartX, lineStartY; - /**Animation scale for line.*/ + /** + * Animation scale for line. + */ private float lineScale; - /**Animation data for crosshair.*/ + /** + * Animation data for crosshair. + */ private float crosshairScale; private TargetTrait lastTarget; - /**List of currently selected tiles to place.*/ + /** + * List of currently selected tiles to place. + */ private Array selection = new Array<>(); - /**Place requests to be removed.*/ + /** + * Place requests to be removed. + */ private Array removals = new Array<>(); - /**Whether or not the player is currently shifting all placed tiles.*/ + /** + * Whether or not the player is currently shifting all placed tiles. + */ private boolean selecting; - /**Whether the player is currently in line-place mode.*/ + /** + * Whether the player is currently in line-place mode. + */ private boolean lineMode; - /**Current place mode.*/ + /** + * Current place mode. + */ private PlaceMode mode = none; - /**Whether no recipe was available when switching to break mode.*/ + /** + * Whether no recipe was available when switching to break mode. + */ private Recipe lastRecipe; - /**Last placed request. Used for drawing block overlay.*/ + /** + * Last placed request. Used for drawing block overlay. + */ private PlaceRequest lastPlaced; - - public MobileInput(Player player){ - super(player); - Inputs.addProcessor(new GestureDetector(20, 0.5f, 0.4f, 0.15f, this)); - } - //region utility methods + public MobileInput(Player player){ + super(player); + Inputs.addProcessor(new GestureDetector(20, 0.5f, 0.4f, 0.15f, this)); + } - /**Check and assign targets for a specific position.*/ + //region utility methods + + /** + * Check and assign targets for a specific position. + */ void checkTargets(float x, float y){ - synchronized (Entities.entityLock) { + synchronized(Entities.entityLock){ Unit unit = Units.getClosestEnemy(player.getTeam(), x, y, 20f, u -> true); - if (unit != null) { + if(unit != null){ player.target = unit; - } else { + }else{ Tile tile = world.tileWorld(x, y); - if (tile != null) tile = tile.target(); + if(tile != null) tile = tile.target(); - if (tile != null && state.teams.areEnemies(player.getTeam(), tile.getTeam())) { + if(tile != null && state.teams.areEnemies(player.getTeam(), tile.getTeam())){ player.target = tile.entity; } } } } - /**Returns whether this tile is in the list of requests, or at least colliding with one.*/ - boolean hasRequest(Tile tile){ + /** + * Returns whether this tile is in the list of requests, or at least colliding with one. + */ + boolean hasRequest(Tile tile){ return getRequest(tile) != null; } - /**Returns whether this block overlaps any selection requests.*/ + /** + * Returns whether this block overlaps any selection requests. + */ boolean checkOverlapPlacement(int x, int y, Block block){ r2.setSize(block.size * tilesize); r2.setCenter(x * tilesize + block.offset(), y * tilesize + block.offset()); @@ -125,13 +156,15 @@ public class MobileInput extends InputHandler implements GestureListener{ return true; } } - return false; + return false; } - /**Returns the selection request that overlaps this tile, or null.*/ + /** + * Returns the selection request that overlaps this tile, or null. + */ PlaceRequest getRequest(Tile tile){ - r2.setSize(tilesize); - r2.setCenter(tile.worldx(), tile.worldy()); + r2.setSize(tilesize); + r2.setCenter(tile.worldx(), tile.worldy()); for(PlaceRequest req : selection){ Tile other = req.tile(); @@ -142,15 +175,15 @@ public class MobileInput extends InputHandler implements GestureListener{ r1.setSize(req.recipe.result.size * tilesize); r1.setCenter(other.worldx() + req.recipe.result.offset(), other.worldy() + req.recipe.result.offset()); - if (r2.overlaps(r1)) { + if(r2.overlaps(r1)){ return req; } - }else { + }else{ r1.setSize(other.block().size * tilesize); r1.setCenter(other.worldx() + other.block().offset(), other.worldy() + other.block().offset()); - if (r2.overlaps(r1)) { + if(r2.overlaps(r1)){ return req; } } @@ -166,7 +199,7 @@ public class MobileInput extends InputHandler implements GestureListener{ void drawRequest(PlaceRequest request){ Tile tile = request.tile(); - if(!request.remove) { + if(!request.remove){ //draw placing request float offset = request.recipe.result.offset(); TextureRegion[] regions = request.recipe.result.getBlockIcon(); @@ -174,7 +207,7 @@ public class MobileInput extends InputHandler implements GestureListener{ Draw.alpha(Mathf.clamp((1f - request.scale) / 0.5f)); Draw.tint(Color.WHITE, Palette.breakInvalid, request.redness); - for (TextureRegion region : regions) { + for(TextureRegion region : regions){ Draw.rect(region, tile.worldx() + offset, tile.worldy() + offset, region.getRegionWidth() * request.scale, region.getRegionHeight() * request.scale, request.recipe.result.rotate ? request.rotation * 90 : 0); @@ -182,7 +215,7 @@ public class MobileInput extends InputHandler implements GestureListener{ }else{ Draw.color(Palette.remove); //draw removing request - Lines.poly(tile.drawx(), tile.drawy(), 4, tile.block().size * tilesize/2f * request.scale, 45 + 15); + Lines.poly(tile.drawx(), tile.drawy(), 4, tile.block().size * tilesize / 2f * request.scale, 45 + 15); } } @@ -207,9 +240,9 @@ public class MobileInput extends InputHandler implements GestureListener{ //region UI and drawing @Override - public void buildUI(Group group) { + public void buildUI(Group group){ - //Create confirm/cancel table + //Create confirm/cancel table new table(){{ abottom().aleft(); @@ -227,12 +260,12 @@ public class MobileInput extends InputHandler implements GestureListener{ //Add an accept button, which places everything. new imagebutton("icon-check", 16 * 2f, () -> { - for (PlaceRequest request : selection) { + for(PlaceRequest request : selection){ Tile tile = request.tile(); //actually place/break all selected blocks - if (tile != null) { - if(!request.remove) { + if(tile != null){ + if(!request.remove){ rotation = request.rotation; recipe = request.recipe; tryPlaceBlock(tile.x, tile.y); @@ -292,12 +325,12 @@ public class MobileInput extends InputHandler implements GestureListener{ } @Override - public boolean isPlacing() { + public boolean isPlacing(){ return super.isPlacing() && mode == placing; } @Override - public void drawOutlined(){ + public void drawOutlined(){ //Draw.color(Palette.placing); //Lines.poly(player.x, player.y, 100, Player.placeDistance); @@ -324,11 +357,11 @@ public class MobileInput extends InputHandler implements GestureListener{ if(tile == null) continue; - if ((!request.remove && validPlace(tile.x, tile.y, request.recipe.result, request.rotation)) - || (request.remove && validBreak(tile.x, tile.y))) { + if((!request.remove && validPlace(tile.x, tile.y, request.recipe.result, request.rotation)) + || (request.remove && validBreak(tile.x, tile.y))){ request.scale = Mathf.lerpDelta(request.scale, 1f, 0.2f); request.redness = Mathf.lerpDelta(request.redness, 0f, 0.2f); - } else { + }else{ request.scale = Mathf.lerpDelta(request.scale, 0.5f, 0.1f); request.redness = Mathf.lerpDelta(request.redness, 1f, 0.2f); } @@ -353,7 +386,7 @@ public class MobileInput extends InputHandler implements GestureListener{ if(tile != null){ //draw placing - if(mode == placing && recipe != null) { + if(mode == placing && recipe != null){ NormalizeDrawResult dresult = PlaceUtils.normalizeDrawArea(recipe.result, lineStartX, lineStartY, tile.x, tile.y, true, maxLength, lineScale); Lines.rect(dresult.x, dresult.y, dresult.x2 - dresult.x, dresult.y2 - dresult.y); @@ -361,20 +394,20 @@ public class MobileInput extends InputHandler implements GestureListener{ NormalizeResult result = PlaceUtils.normalizeArea(lineStartX, lineStartY, tile.x, tile.y, rotation, true, maxLength); //go through each cell and draw the block to place if valid - for (int i = 0; i <= result.getLength(); i += recipe.result.size) { + for(int i = 0; i <= result.getLength(); i += recipe.result.size){ int x = lineStartX + i * Mathf.sign(tile.x - lineStartX) * Mathf.bool(result.isX()); int y = lineStartY + i * Mathf.sign(tile.y - lineStartY) * Mathf.bool(!result.isX()); - if (!checkOverlapPlacement(x, y, recipe.result) && validPlace(x, y, recipe.result, result.rotation)) { + if(!checkOverlapPlacement(x, y, recipe.result) && validPlace(x, y, recipe.result, result.rotation)){ Draw.color(); TextureRegion[] regions = recipe.result.getBlockIcon(); - for (TextureRegion region : regions) { + for(TextureRegion region : regions){ Draw.rect(region, x * tilesize + recipe.result.offset(), y * tilesize + recipe.result.offset(), region.getRegionWidth() * lineScale, region.getRegionHeight() * lineScale, recipe.result.rotate ? result.rotation * 90 : 0); } - } else { + }else{ Draw.color(Palette.breakInvalid); Lines.square(x * tilesize + recipe.result.offset(), y * tilesize + recipe.result.offset(), recipe.result.size * tilesize / 2f); } @@ -390,13 +423,13 @@ public class MobileInput extends InputHandler implements GestureListener{ Draw.alpha(0.6f); Draw.alpha(1f); - for(int x = dresult.x; x <= dresult.x2; x ++){ - for(int y = dresult.y; y <= dresult.y2; y ++){ + for(int x = dresult.x; x <= dresult.x2; x++){ + for(int y = dresult.y; y <= dresult.y2; y++){ Tile other = world.tile(x, y); if(other == null || !validBreak(other.x, other.y)) continue; other = other.target(); - Lines.poly(other.drawx(), other.drawy(), 4, other.block().size * tilesize/2f, 45 + 15); + Lines.poly(other.drawx(), other.drawy(), 4, other.block().size * tilesize / 2f, 45 + 15); } } @@ -420,8 +453,8 @@ public class MobileInput extends InputHandler implements GestureListener{ float radius = Interpolation.swingIn.apply(crosshairScale); - Lines.poly(player.target.getX(), player.target.getY(), 4, 7f * radius, Timers.time()*1.5f); - Lines.spikes(player.target.getX(), player.target.getY(), 3f * radius, 6f * radius, 4, Timers.time()*1.5f); + Lines.poly(player.target.getX(), player.target.getY(), 4, 7f * radius, Timers.time() * 1.5f); + Lines.spikes(player.target.getX(), player.target.getY(), 3f * radius, 6f * radius, 4, Timers.time() * 1.5f); } Draw.reset(); @@ -431,9 +464,9 @@ public class MobileInput extends InputHandler implements GestureListener{ //region input events - @Override - public boolean touchDown(int screenX, int screenY, int pointer, int button){ - if(state.is(State.menu)) return false; + @Override + public boolean touchDown(int screenX, int screenY, int pointer, int button){ + if(state.is(State.menu)) return false; //get tile on cursor Tile cursor = tileAt(screenX, screenY); @@ -453,19 +486,19 @@ public class MobileInput extends InputHandler implements GestureListener{ } } - return false; - } + return false; + } @Override public boolean touchUp(int screenX, int screenY, int pointer, int button){ //place down a line if in line mode - if(lineMode) { + if(lineMode){ Tile tile = tileAt(screenX, screenY); - if (tile == null) return false; + if(tile == null) return false; - if(mode == placing && recipe != null) { + if(mode == placing && recipe != null){ //normalize area NormalizeResult result = PlaceUtils.normalizeArea(lineStartX, lineStartY, tile.x, tile.y, rotation, true, 100); @@ -473,11 +506,11 @@ public class MobileInput extends InputHandler implements GestureListener{ rotation = result.rotation; //place blocks on line - for (int i = 0; i <= result.getLength(); i += recipe.result.size) { + for(int i = 0; i <= result.getLength(); i += recipe.result.size){ int x = lineStartX + i * Mathf.sign(tile.x - lineStartX) * Mathf.bool(result.isX()); int y = lineStartY + i * Mathf.sign(tile.y - lineStartY) * Mathf.bool(!result.isX()); - if (!checkOverlapPlacement(x, y, recipe.result) && validPlace(x, y, recipe.result, result.rotation)) { + if(!checkOverlapPlacement(x, y, recipe.result) && validPlace(x, y, recipe.result, result.rotation)){ PlaceRequest request = new PlaceRequest(x * tilesize, y * tilesize, recipe, result.rotation); request.scale = 1f; selection.add(request); @@ -492,8 +525,8 @@ public class MobileInput extends InputHandler implements GestureListener{ NormalizeResult result = PlaceUtils.normalizeArea(lineStartX, lineStartY, tile.x, tile.y, rotation, false, maxLength); //break everything in area - for(int x = 0; x <= Math.abs(result.x2 - result.x); x ++ ){ - for(int y = 0; y <= Math.abs(result.y2 - result.y); y ++){ + for(int x = 0; x <= Math.abs(result.x2 - result.x); x++){ + for(int y = 0; y <= Math.abs(result.y2 - result.y); y++){ int wx = lineStartX + x * Mathf.sign(tile.x - lineStartX); int wy = lineStartY + y * Mathf.sign(tile.y - lineStartY); @@ -503,7 +536,7 @@ public class MobileInput extends InputHandler implements GestureListener{ tar = tar.target(); - if (!hasRequest(world.tile(tar.x, tar.y)) && validBreak(tar.x, tar.y)) { + if(!hasRequest(world.tile(tar.x, tar.y)) && validBreak(tar.x, tar.y)){ PlaceRequest request = new PlaceRequest(tar.worldx(), tar.worldy()); request.scale = 1f; selection.add(request); @@ -516,7 +549,7 @@ public class MobileInput extends InputHandler implements GestureListener{ }else{ Tile tile = tileAt(screenX, screenY); - if (tile == null) return false; + if(tile == null) return false; tryDropItems(tile.target(), Graphics.world(screenX, screenY).x, Graphics.world(screenX, screenY).y); } @@ -524,7 +557,7 @@ public class MobileInput extends InputHandler implements GestureListener{ } @Override - public boolean longPress(float x, float y) { + public boolean longPress(float x, float y){ if(state.is(State.menu) || mode == none) return false; //get tile on cursor @@ -545,11 +578,11 @@ public class MobileInput extends InputHandler implements GestureListener{ Effects.effect(Fx.tapBlock, cursor.worldx() + recipe.result.offset(), cursor.worldy() + recipe.result.offset(), recipe.result.size); } - return false; - } + return false; + } @Override - public boolean tap(float x, float y, int count, int button) { + public boolean tap(float x, float y, int count, int button){ if(state.is(State.menu) || lineMode) return false; float worldx = Graphics.world(x, y).x, worldy = Graphics.world(x, y).y; @@ -563,12 +596,12 @@ public class MobileInput extends InputHandler implements GestureListener{ if(cursor == null || ui.hasMouse(x, y)) return false; //remove if request present - if(hasRequest(cursor)) { + if(hasRequest(cursor)){ removeRequest(getRequest(cursor)); }else if(mode == placing && isPlacing() && validPlace(cursor.x, cursor.y, recipe.result, rotation) && !checkOverlapPlacement(cursor.x, cursor.y, recipe.result)){ //add to selection queue if it's a valid place position selection.add(lastPlaced = new PlaceRequest(cursor.worldx(), cursor.worldy(), recipe, rotation)); - }else if(mode == breaking && validBreak(cursor.target().x, cursor.target().y) && !hasRequest(cursor.target())) { + }else if(mode == breaking && validBreak(cursor.target().x, cursor.target().y) && !hasRequest(cursor.target())){ //add to selection queue if it's a valid BREAK position cursor = cursor.target(); selection.add(new PlaceRequest(cursor.worldx(), cursor.worldy())); @@ -588,24 +621,24 @@ public class MobileInput extends InputHandler implements GestureListener{ return false; } - @Override - public void update(){ + @Override + public void update(){ //reset state when not placing - if(mode == none){ - selecting = false; - lineMode = false; - removals.addAll(selection); - selection.clear(); + if(mode == none){ + selecting = false; + lineMode = false; + removals.addAll(selection); + selection.clear(); } if(lineMode && mode == placing && recipe == null){ - lineMode = false; + lineMode = false; } //if there is no mode and there's a recipe, switch to placing if(recipe != null && mode == none){ - mode = placing; + mode = placing; } if(recipe != null){ @@ -615,13 +648,13 @@ public class MobileInput extends InputHandler implements GestureListener{ //automatically switch to placing after a new recipe is selected if(lastRecipe != recipe && mode == breaking && recipe != null){ mode = placing; - lastRecipe = recipe; + lastRecipe = recipe; } if(lineMode){ - lineScale = Mathf.lerpDelta(lineScale, 1f, 0.1f); + lineScale = Mathf.lerpDelta(lineScale, 1f, 0.1f); - //When in line mode, pan when near screen edges automatically + //When in line mode, pan when near screen edges automatically if(Gdx.input.isTouched(0) && lineMode){ float screenX = Graphics.mouse().x, screenY = Graphics.mouse().y; @@ -651,19 +684,19 @@ public class MobileInput extends InputHandler implements GestureListener{ Core.camera.position.y += vector.y; } }else{ - lineScale = 0f; + lineScale = 0f; } //remove place requests that have disappeared - for(int i = removals.size - 1; i >= 0; i --){ + for(int i = removals.size - 1; i >= 0; i--){ PlaceRequest request = removals.get(i); if(request.scale <= 0.0001f){ removals.removeIndex(i); - i --; + i--; } } - } + } @Override public boolean pan(float x, float y, float deltaX, float deltaY){ @@ -676,14 +709,14 @@ public class MobileInput extends InputHandler implements GestureListener{ float dx = deltaX * Core.camera.zoom / Core.cameraScale, dy = deltaY * Core.camera.zoom / Core.cameraScale; - if(selecting){ //pan all requests + if(selecting){ //pan all requests for(PlaceRequest req : selection){ if(req.remove) continue; //don't shift removal requests req.x += dx; req.y -= dy; } }else{ - //pan player + //pan player Core.camera.position.x -= dx; Core.camera.position.y += dy; } @@ -692,12 +725,12 @@ public class MobileInput extends InputHandler implements GestureListener{ } @Override - public boolean panStop(float x, float y, int pointer, int button) { + public boolean panStop(float x, float y, int pointer, int button){ return false; } @Override - public boolean pinch (Vector2 initialPointer1, Vector2 initialPointer2, Vector2 pointer1, Vector2 pointer2) { + public boolean pinch(Vector2 initialPointer1, Vector2 initialPointer2, Vector2 pointer1, Vector2 pointer2){ if(pinch1.x < 0){ pinch1.set(initialPointer1); pinch2.set(initialPointer2); @@ -727,28 +760,35 @@ public class MobileInput extends InputHandler implements GestureListener{ } @Override - public void pinchStop () { + public void pinchStop(){ initzoom = -1; pinch2.set(pinch1.set(-1, -1)); zoomed = false; } - @Override public boolean touchDown(float x, float y, int pointer, int button) { return false; } - @Override public boolean fling(float velocityX, float velocityY, int button) { return false; } + @Override + public boolean touchDown(float x, float y, int pointer, int button){ + return false; + } + + @Override + public boolean fling(float velocityX, float velocityY, int button){ + return false; + } //endregion class PlaceRequest{ - float x, y; - Recipe recipe; - int rotation; - boolean remove; + float x, y; + Recipe recipe; + int rotation; + boolean remove; - //animation variables - float scale; - float redness; + //animation variables + float scale; + float redness; - PlaceRequest(float x, float y, Recipe recipe, int rotation) { + PlaceRequest(float x, float y, Recipe recipe, int rotation){ this.x = x; this.y = y; this.recipe = recipe; @@ -756,14 +796,14 @@ public class MobileInput extends InputHandler implements GestureListener{ this.remove = false; } - PlaceRequest(float x, float y) { + PlaceRequest(float x, float y){ this.x = x; this.y = y; this.remove = true; } Tile tile(){ - return world.tileWorld(x - (recipe == null ? 0 : recipe.result.offset()), y - (recipe == null ? 0 : recipe.result.offset())); + return world.tileWorld(x - (recipe == null ? 0 : recipe.result.offset()), y - (recipe == null ? 0 : recipe.result.offset())); } } } diff --git a/core/src/io/anuke/mindustry/input/PlaceUtils.java b/core/src/io/anuke/mindustry/input/PlaceUtils.java index 2d514f9506..b74b5b31a8 100644 --- a/core/src/io/anuke/mindustry/input/PlaceUtils.java +++ b/core/src/io/anuke/mindustry/input/PlaceUtils.java @@ -5,11 +5,12 @@ import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.tilesize; -public class PlaceUtils { +public class PlaceUtils{ private static final NormalizeResult result = new NormalizeResult(); private static final NormalizeDrawResult drawResult = new NormalizeDrawResult(); - /**Normalizes a placement area and returns the result, ready to be used for drawing a rectangle. + /** + * Normalizes a placement area and returns the result, ready to be used for drawing a rectangle. * Returned x2 and y2 will always be greater than x and y. * * @param block block that will be drawn @@ -30,12 +31,12 @@ public class PlaceUtils { drawResult.x2 = result.x2 * tilesize; drawResult.y2 = result.y2 * tilesize; - drawResult.x -= block.size * scaling * tilesize/2; - drawResult.x2 += block.size * scaling * tilesize/2; + drawResult.x -= block.size * scaling * tilesize / 2; + drawResult.x2 += block.size * scaling * tilesize / 2; - drawResult.y -= block.size * scaling * tilesize/2; - drawResult.y2 += block.size * scaling * tilesize/2; + drawResult.y -= block.size * scaling * tilesize / 2; + drawResult.y2 += block.size * scaling * tilesize / 2; drawResult.x += offset; drawResult.y += offset; @@ -45,7 +46,8 @@ public class PlaceUtils { return drawResult; } - /**Normalizes a placement area and returns the result. + /** + * Normalizes a placement area and returns the result. * Returned x2 and y2 will always be greater than x and y. * * @param tilex starting X coordinate @@ -58,18 +60,18 @@ public class PlaceUtils { */ public static NormalizeResult normalizeArea(int tilex, int tiley, int endx, int endy, int rotation, boolean snap, int maxLength){ - if(snap) { - if (Math.abs(tilex - endx) > Math.abs(tiley - endy)) { + if(snap){ + if(Math.abs(tilex - endx) > Math.abs(tiley - endy)){ endy = tiley; - } else { + }else{ endx = tilex; } - if (Math.abs(endx - tilex) > maxLength) { + if(Math.abs(endx - tilex) > maxLength){ endx = Mathf.sign(endx - tilex) * maxLength + tilex; } - if (Math.abs(endy - tiley) > maxLength) { + if(Math.abs(endy - tiley) > maxLength){ endy = Mathf.sign(endy - tiley) * maxLength + tiley; } } @@ -110,7 +112,7 @@ public class PlaceUtils { return result; } - static class NormalizeDrawResult { + static class NormalizeDrawResult{ float x, y, x2, y2; } @@ -121,17 +123,23 @@ public class PlaceUtils { return Math.abs(x2 - x) > Math.abs(y2 - y); } - /**Returns length of greater edge of the selection.*/ + /** + * Returns length of greater edge of the selection. + */ int getLength(){ return Math.max(x2 - x, y2 - y); } - /**Returns the X position of a specific index along this area as a line.*/ + /** + * Returns the X position of a specific index along this area as a line. + */ int getScaledX(int i){ return x + (x2 - x > y2 - y ? i : 0); } - /**Returns the Y position of a specific index along this area as a line.*/ + /** + * Returns the Y position of a specific index along this area as a line. + */ int getScaledY(int i){ return y + (x2 - x > y2 - y ? 0 : i); } diff --git a/core/src/io/anuke/mindustry/io/BundleLoader.java b/core/src/io/anuke/mindustry/io/BundleLoader.java index aa786fd9d2..bc97c089e5 100644 --- a/core/src/io/anuke/mindustry/io/BundleLoader.java +++ b/core/src/io/anuke/mindustry/io/BundleLoader.java @@ -13,7 +13,7 @@ import java.util.Locale; import static io.anuke.mindustry.Vars.headless; -public class BundleLoader { +public class BundleLoader{ public static void load(){ Settings.defaults("locale", "default"); @@ -27,10 +27,10 @@ public class BundleLoader { return Locale.getDefault(); }else{ Locale lastLocale; - if (loc.contains("_")) { + if(loc.contains("_")){ String[] split = loc.split("_"); lastLocale = new Locale(split[0], split[1]); - } else { + }else{ lastLocale = new Locale(loc); } @@ -40,7 +40,7 @@ public class BundleLoader { private static void loadBundle(){ I18NBundle.setExceptionOnMissingKey(false); - try { + try{ //try loading external bundle FileHandle handle = Gdx.files.local("bundle"); @@ -51,7 +51,7 @@ public class BundleLoader { if(!headless){ Timers.run(10f, () -> Vars.ui.showInfo("Note: You have successfully loaded an external translation bundle.")); } - }catch (Throwable e){ + }catch(Throwable e){ //no external bundle found FileHandle handle = Gdx.files.internal("bundles/bundle"); diff --git a/core/src/io/anuke/mindustry/io/Changelogs.java b/core/src/io/anuke/mindustry/io/Changelogs.java index c799647f1c..85d482ad00 100644 --- a/core/src/io/anuke/mindustry/io/Changelogs.java +++ b/core/src/io/anuke/mindustry/io/Changelogs.java @@ -8,7 +8,7 @@ import io.anuke.ucore.function.Consumer; import static io.anuke.mindustry.Vars.releasesURL; -public class Changelogs { +public class Changelogs{ public static void getChangelog(Consumer> success, Consumer fail){ Net.http(releasesURL, "GET", result -> { @@ -30,7 +30,7 @@ public class Changelogs { public final String name, description; public final int id, build; - public VersionInfo(String name, String description, int id, int build) { + public VersionInfo(String name, String description, int id, int build){ this.name = name; this.description = description; this.id = id; @@ -38,7 +38,7 @@ public class Changelogs { } @Override - public String toString() { + public String toString(){ return "VersionInfo{" + "name='" + name + '\'' + ", description='" + description + '\'' + diff --git a/core/src/io/anuke/mindustry/io/Map.java b/core/src/io/anuke/mindustry/io/Map.java index 1963995a4c..1959862c79 100644 --- a/core/src/io/anuke/mindustry/io/Map.java +++ b/core/src/io/anuke/mindustry/io/Map.java @@ -6,16 +6,26 @@ import io.anuke.ucore.function.Supplier; import java.io.InputStream; -public class Map { - /**Internal map name. This is the filename, without any extensions.*/ +public class Map{ + /** + * Internal map name. This is the filename, without any extensions. + */ public final String name; - /**Whether this is a custom map.*/ + /** + * Whether this is a custom map. + */ public final boolean custom; - /**Metadata. Author description, display name, etc.*/ + /** + * Metadata. Author description, display name, etc. + */ public final MapMeta meta; - /**Supplies a new input stream with the data of this map.*/ + /** + * Supplies a new input stream with the data of this map. + */ public final Supplier stream; - /**Preview texture.*/ + /** + * Preview texture. + */ public Texture texture; public Map(String name, MapMeta meta, boolean custom, Supplier streamSupplier){ diff --git a/core/src/io/anuke/mindustry/io/MapIO.java b/core/src/io/anuke/mindustry/io/MapIO.java index 4ff93932b9..5b10c9d7ed 100644 --- a/core/src/io/anuke/mindustry/io/MapIO.java +++ b/core/src/io/anuke/mindustry/io/MapIO.java @@ -18,8 +18,10 @@ import java.io.DataOutputStream; import java.io.IOException; import java.io.OutputStream; -/**Reads and writes map files.*/ -public class MapIO { +/** + * Reads and writes map files. + */ +public class MapIO{ private static final int version = 0; private static IntIntMap defaultBlockMap = new IntIntMap(); @@ -36,8 +38,8 @@ public class MapIO { TileDataMarker marker = data.newDataMarker(); Color color = new Color(); - for(int y = 0; y < data.height(); y ++){ - for(int x = 0; x < data.width(); x ++){ + for(int y = 0; y < data.height(); y++){ + for(int x = 0; x < data.width(); x++){ data.read(marker); Block floor = Block.getByID(marker.floor); Block wall = Block.getByID(marker.wall); @@ -45,7 +47,7 @@ public class MapIO { if(wallc == 0 && (wall.update || wall.solid || wall.breakable)) wallc = Team.all[marker.team].intColor; wallc = wallc == 0 ? ColorMapper.getBlockColor(floor) : wallc; if(marker.elevation > 0){ - float scaling = 1f + marker.elevation/8f; + float scaling = 1f + marker.elevation / 8f; color.set(wallc); color.mul(scaling, scaling, scaling, 1f); wallc = Color.rgba8888(color); @@ -62,17 +64,17 @@ public class MapIO { public static MapTileData readPixmap(Pixmap pixmap){ MapTileData data = new MapTileData(pixmap.getWidth(), pixmap.getHeight()); - for(int x = 0; x < data.width(); x ++){ - for(int y = 0; y < data.height(); y ++){ + for(int x = 0; x < data.width(); x++){ + for(int y = 0; y < data.height(); y++){ Block block = ColorMapper.getByColor(pixmap.getPixel(y, pixmap.getWidth() - 1 - x)); if(block == null){ - data.write(x, y, DataPosition.floor, (byte)Blocks.stone.id); + data.write(x, y, DataPosition.floor, (byte) Blocks.stone.id); }else{ - data.write(x, y, DataPosition.floor, (byte)block.id); + data.write(x, y, DataPosition.floor, (byte) block.id); } - data.write(x, y, DataPosition.wall, (byte)Blocks.air.id); + data.write(x, y, DataPosition.wall, (byte) Blocks.air.id); } } @@ -94,25 +96,31 @@ public class MapIO { ds.close(); } - /**Reads tile data, skipping meta.*/ - public static MapTileData readTileData(DataInputStream stream, boolean readOnly) throws IOException { + /** + * Reads tile data, skipping meta. + */ + public static MapTileData readTileData(DataInputStream stream, boolean readOnly) throws IOException{ MapMeta meta = readMapMeta(stream); return readTileData(stream, meta, readOnly); } - /**Does not skip meta. Call after reading meta.*/ - public static MapTileData readTileData(DataInputStream stream, MapMeta meta, boolean readOnly) throws IOException { + /** + * Does not skip meta. Call after reading meta. + */ + public static MapTileData readTileData(DataInputStream stream, MapMeta meta, boolean readOnly) throws IOException{ byte[] bytes = new byte[stream.available()]; stream.readFully(bytes); return new MapTileData(bytes, meta.width, meta.height, meta.blockMap, readOnly); } - /**Reads tile data, skipping meta tags.*/ + /** + * Reads tile data, skipping meta tags. + */ public static MapTileData readTileData(Map map, boolean readOnly){ - try (DataInputStream ds = new DataInputStream(map.stream.get())){ + try(DataInputStream ds = new DataInputStream(map.stream.get())){ return MapIO.readTileData(ds, readOnly); - }catch (IOException e){ + }catch(IOException e){ throw new RuntimeException(e); } } @@ -125,14 +133,14 @@ public class MapIO { byte tagAmount = stream.readByte(); - for(int i = 0; i < tagAmount; i ++){ + for(int i = 0; i < tagAmount; i++){ String name = stream.readUTF(); String value = stream.readUTF(); tags.put(name, value); } short blocks = stream.readShort(); - for(int i = 0; i < blocks; i ++){ + for(int i = 0; i < blocks; i++){ short id = stream.readShort(); String name = stream.readUTF(); Block block = Block.getByName(name); @@ -151,7 +159,7 @@ public class MapIO { public static void writeMapMeta(DataOutputStream stream, MapMeta meta) throws IOException{ stream.writeInt(meta.version); - stream.writeByte((byte)meta.tags.size); + stream.writeByte((byte) meta.tags.size); for(Entry entry : meta.tags.entries()){ stream.writeUTF(entry.key); diff --git a/core/src/io/anuke/mindustry/io/MapMeta.java b/core/src/io/anuke/mindustry/io/MapMeta.java index 7668a76933..ab554148c5 100644 --- a/core/src/io/anuke/mindustry/io/MapMeta.java +++ b/core/src/io/anuke/mindustry/io/MapMeta.java @@ -3,13 +3,13 @@ package io.anuke.mindustry.io; import com.badlogic.gdx.utils.IntIntMap; import com.badlogic.gdx.utils.ObjectMap; -public class MapMeta { +public class MapMeta{ public final int version; public final ObjectMap tags; public final int width, height; public final IntIntMap blockMap; - public MapMeta(int version, ObjectMap tags, int width, int height, IntIntMap blockMap) { + public MapMeta(int version, ObjectMap tags, int width, int height, IntIntMap blockMap){ this.version = version; this.tags = tags; this.width = width; diff --git a/core/src/io/anuke/mindustry/io/MapTileData.java b/core/src/io/anuke/mindustry/io/MapTileData.java index b3fb92e4ab..1a2d307d40 100644 --- a/core/src/io/anuke/mindustry/io/MapTileData.java +++ b/core/src/io/anuke/mindustry/io/MapTileData.java @@ -5,13 +5,15 @@ import io.anuke.ucore.util.Bits; import java.nio.ByteBuffer; -public class MapTileData { - /**Tile size: 4 bytes.
+public class MapTileData{ + /** + * Tile size: 4 bytes.
* 0: ground tile
* 1: wall tile
* 2: rotation + team
* 3: link (x/y)
- * 4: elevation
*/ + * 4: elevation
+ */ private final static int TILE_SIZE = 5; private final ByteBuffer buffer; @@ -36,7 +38,7 @@ public class MapTileData { this.readOnly = readOnly; if(mapping != null && !readOnly){ - for(int i = 0; i < width * height; i ++){ + for(int i = 0; i < width * height; i++){ TileDataMarker marker = new TileDataMarker(); read(marker); buffer.position(i * TILE_SIZE); @@ -59,28 +61,38 @@ public class MapTileData { return height; } - /**Write a byte to a specific position.*/ + /** + * Write a byte to a specific position. + */ public void write(int x, int y, DataPosition position, byte data){ buffer.put((x + width * y) * TILE_SIZE + position.ordinal(), data); } - /**Gets a byte at a specific position.*/ + /** + * Gets a byte at a specific position. + */ public byte read(int x, int y, DataPosition position){ return buffer.get((x + width * y) * TILE_SIZE + position.ordinal()); } - /**Reads and returns the next tile data.*/ + /** + * Reads and returns the next tile data. + */ public TileDataMarker read(TileDataMarker marker){ marker.read(buffer); return marker; } - /**Writes this tile data marker.*/ + /** + * Writes this tile data marker. + */ public void write(TileDataMarker marker){ marker.write(buffer); } - /**Sets read position to the specified coordinates*/ + /** + * Sets read position to the specified coordinates + */ public void position(int x, int y){ buffer.position((x + width * y) * TILE_SIZE); } @@ -93,7 +105,7 @@ public class MapTileData { floor, wall, link, rotationTeam, elevation } - public class TileDataMarker { + public class TileDataMarker{ public byte floor, wall; public byte link; public byte rotation; @@ -110,8 +122,8 @@ public class MapTileData { team = Bits.getRightByte(rt); if(map != null){ - floor = (byte)map.get(floor, floor); - wall = (byte)map.get(wall, wall); + floor = (byte) map.get(floor, floor); + wall = (byte) map.get(wall, wall); } } diff --git a/core/src/io/anuke/mindustry/io/Maps.java b/core/src/io/anuke/mindustry/io/Maps.java index 5ea9e0bf38..92ccdbd779 100644 --- a/core/src/io/anuke/mindustry/io/Maps.java +++ b/core/src/io/anuke/mindustry/io/Maps.java @@ -17,145 +17,171 @@ import java.io.*; import static io.anuke.mindustry.Vars.*; public class Maps implements Disposable{ - /**List of all built-in maps.*/ - private static final String[] defaultMapNames = {}; - /**Tile format version.*/ - private static final int version = 0; + /** + * List of all built-in maps. + */ + private static final String[] defaultMapNames = {}; + /** + * Tile format version. + */ + private static final int version = 0; - /**Maps map names to the real maps.*/ - private ObjectMap maps = new ObjectMap<>(); - /**All maps stored in an ordered array.*/ - private Array allMaps = new ThreadArray<>(); - /**Temporary array used for returning things.*/ - private Array returnArray = new ThreadArray<>(); - /**Used for storing a list of custom map names for GWT.*/ - private Array customMapNames; + /** + * Maps map names to the real maps. + */ + private ObjectMap maps = new ObjectMap<>(); + /** + * All maps stored in an ordered array. + */ + private Array allMaps = new ThreadArray<>(); + /** + * Temporary array used for returning things. + */ + private Array returnArray = new ThreadArray<>(); + /** + * Used for storing a list of custom map names for GWT. + */ + private Array customMapNames; - public Maps(){ + public Maps(){ } - /**Returns a list of all maps, including custom ones.*/ - public Array all(){ - return allMaps; - } + /** + * Returns a list of all maps, including custom ones. + */ + public Array all(){ + return allMaps; + } - /**Returns a list of only custom maps.*/ - public Array customMaps(){ - returnArray.clear(); - for(Map map : allMaps){ - if(map.custom) returnArray.add(map); - } - return returnArray; - } + /** + * Returns a list of only custom maps. + */ + public Array customMaps(){ + returnArray.clear(); + for(Map map : allMaps){ + if(map.custom) returnArray.add(map); + } + return returnArray; + } - /**Returns a list of only default maps.*/ - public Array defaultMaps(){ - returnArray.clear(); - for(Map map : allMaps){ - if(!map.custom) returnArray.add(map); - } - return returnArray; - } + /** + * Returns a list of only default maps. + */ + public Array defaultMaps(){ + returnArray.clear(); + for(Map map : allMaps){ + if(!map.custom) returnArray.add(map); + } + return returnArray; + } - /**Returns map by internal name.*/ - public Map getByName(String name){ - return maps.get(name); - } + /** + * Returns map by internal name. + */ + public Map getByName(String name){ + return maps.get(name); + } - /**Load all maps. Should be called at application start.*/ - public void load(){ - try { - for (String name : defaultMapNames) { - FileHandle file = Gdx.files.internal("maps/" + name + "." + mapExtension); - loadMap(file.nameWithoutExtension(), file::read, false); - } - }catch (IOException e){ - throw new RuntimeException(e); - } + /** + * Load all maps. Should be called at application start. + */ + public void load(){ + try{ + for(String name : defaultMapNames){ + FileHandle file = Gdx.files.internal("maps/" + name + "." + mapExtension); + loadMap(file.nameWithoutExtension(), file::read, false); + } + }catch(IOException e){ + throw new RuntimeException(e); + } - loadCustomMaps(); - } + loadCustomMaps(); + } - /**Save a map. This updates all values and stored data necessary.*/ - public void saveMap(String name, MapTileData data, ObjectMap tags){ - try { - if (!gwt) { - FileHandle file = customMapDirectory.child(name + "." + mapExtension); - MapIO.writeMap(file.write(false), tags, data); - } else { - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - MapIO.writeMap(stream, tags, data); - Settings.putString("map-data-" + name, new String(Base64Coder.encode(stream.toByteArray()))); - if(!customMapNames.contains(name, false)){ - customMapNames.add(name); - Settings.putJson("custom-maps", customMapNames); - } - Settings.save(); - } + /** + * Save a map. This updates all values and stored data necessary. + */ + public void saveMap(String name, MapTileData data, ObjectMap tags){ + try{ + if(!gwt){ + FileHandle file = customMapDirectory.child(name + "." + mapExtension); + MapIO.writeMap(file.write(false), tags, data); + }else{ + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + MapIO.writeMap(stream, tags, data); + Settings.putString("map-data-" + name, new String(Base64Coder.encode(stream.toByteArray()))); + if(!customMapNames.contains(name, false)){ + customMapNames.add(name); + Settings.putJson("custom-maps", customMapNames); + } + Settings.save(); + } - if(maps.containsKey(name)){ - if(maps.get(name).texture != null) { - maps.get(name).texture.dispose(); - maps.get(name).texture = null; - } - allMaps.removeValue(maps.get(name), true); - } + if(maps.containsKey(name)){ + if(maps.get(name).texture != null){ + maps.get(name).texture.dispose(); + maps.get(name).texture = null; + } + allMaps.removeValue(maps.get(name), true); + } - Map map = new Map(name, new MapMeta(version, tags, data.width(), data.height(), null), true, getStreamFor(name)); - if (!headless){ - map.texture = new Texture(MapIO.generatePixmap(data)); - } - allMaps.add(map); + Map map = new Map(name, new MapMeta(version, tags, data.width(), data.height(), null), true, getStreamFor(name)); + if(!headless){ + map.texture = new Texture(MapIO.generatePixmap(data)); + } + allMaps.add(map); - maps.put(name, map); - }catch (IOException e){ - throw new RuntimeException(e); - } - } + maps.put(name, map); + }catch(IOException e){ + throw new RuntimeException(e); + } + } - /**Removes a map completely.*/ - public void removeMap(Map map){ - if(map.texture != null){ - map.texture.dispose(); - map.texture = null; - } + /** + * Removes a map completely. + */ + public void removeMap(Map map){ + if(map.texture != null){ + map.texture.dispose(); + map.texture = null; + } - maps.remove(map.name); - allMaps.removeValue(map, true); + maps.remove(map.name); + allMaps.removeValue(map, true); - if (!gwt) { - customMapDirectory.child(map.name + "." + mapExtension).delete(); - } else { - customMapNames.removeValue(map.name, false); - Settings.putString("map-data-" + map.name, ""); - Settings.putJson("custom-maps", customMapNames); - Settings.save(); - } - } + if(!gwt){ + customMapDirectory.child(map.name + "." + mapExtension).delete(); + }else{ + customMapNames.removeValue(map.name, false); + Settings.putString("map-data-" + map.name, ""); + Settings.putJson("custom-maps", customMapNames); + Settings.save(); + } + } - private void loadMap(String name, Supplier supplier, boolean custom) throws IOException{ - try(DataInputStream ds = new DataInputStream(supplier.get())) { + private void loadMap(String name, Supplier supplier, boolean custom) throws IOException{ + try(DataInputStream ds = new DataInputStream(supplier.get())){ MapMeta meta = MapIO.readMapMeta(ds); Map map = new Map(name, meta, custom, supplier); - if (!headless){ - map.texture = new Texture(MapIO.generatePixmap(MapIO.readTileData(ds, meta, true))); - } + if(!headless){ + map.texture = new Texture(MapIO.generatePixmap(MapIO.readTileData(ds, meta, true))); + } maps.put(map.name, map); allMaps.add(map); } - } + } - private void loadCustomMaps(){ - if(!gwt){ + private void loadCustomMaps(){ + if(!gwt){ for(FileHandle file : customMapDirectory.list()){ try{ if(file.extension().equalsIgnoreCase(mapExtension)){ loadMap(file.nameWithoutExtension(), file::read, true); } - }catch (Exception e){ + }catch(Exception e){ Log.err("Failed to load custom map file '{0}'!", file); Log.err(e); } @@ -169,7 +195,7 @@ public class Maps implements Disposable{ String data = Settings.getString("map-data-" + name, ""); byte[] bytes = Base64Coder.decode(data); loadMap(name, () -> new ByteArrayInputStream(bytes), true); - }catch (Exception e){ + }catch(Exception e){ Log.err("Failed to load custom map '{0}'!", name); Log.err(e); } @@ -177,19 +203,21 @@ public class Maps implements Disposable{ } } - /**Returns an input stream supplier for a given map name.*/ + /** + * Returns an input stream supplier for a given map name. + */ private Supplier getStreamFor(String name){ - if(!gwt){ - return customMapDirectory.child(name + "." + mapExtension)::read; - }else{ - String data = Settings.getString("map-data-" + name, ""); - byte[] bytes = Base64Coder.decode(data); - return () -> new ByteArrayInputStream(bytes); - } - } + if(!gwt){ + return customMapDirectory.child(name + "." + mapExtension)::read; + }else{ + String data = Settings.getString("map-data-" + name, ""); + byte[] bytes = Base64Coder.decode(data); + return () -> new ByteArrayInputStream(bytes); + } + } - @Override - public void dispose() { + @Override + public void dispose(){ - } + } } diff --git a/core/src/io/anuke/mindustry/io/SaveFileVersion.java b/core/src/io/anuke/mindustry/io/SaveFileVersion.java index 1a0d94bde9..48ec0b58e8 100644 --- a/core/src/io/anuke/mindustry/io/SaveFileVersion.java +++ b/core/src/io/anuke/mindustry/io/SaveFileVersion.java @@ -6,7 +6,7 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; -public abstract class SaveFileVersion { +public abstract class SaveFileVersion{ public final int version; public SaveFileVersion(int version){ @@ -23,5 +23,6 @@ public abstract class SaveFileVersion { } public abstract void read(DataInputStream stream) throws IOException; + public abstract void write(DataOutputStream stream) throws IOException; } diff --git a/core/src/io/anuke/mindustry/io/SaveIO.java b/core/src/io/anuke/mindustry/io/SaveIO.java index 3f5397ce45..dfd21820c5 100644 --- a/core/src/io/anuke/mindustry/io/SaveIO.java +++ b/core/src/io/anuke/mindustry/io/SaveIO.java @@ -15,148 +15,148 @@ import java.util.zip.InflaterInputStream; import static io.anuke.mindustry.Vars.*; public class SaveIO{ - public static final IntMap versions = new IntMap<>(); - public static final Array versionArray = Array.with( - new Save16() - ); + public static final IntMap versions = new IntMap<>(); + public static final Array versionArray = Array.with( + new Save16() + ); - static{ - for(SaveFileVersion version : versionArray){ - versions.put(version.version, version); - } - } + static{ + for(SaveFileVersion version : versionArray){ + versions.put(version.version, version); + } + } - public static void saveToSlot(int slot){ - if(gwt){ - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - write(stream); - Settings.putString("save-"+slot+"-data", new String(Base64Coder.encode(stream.toByteArray()))); - Settings.save(); - }else{ - FileHandle file = fileFor(slot); - boolean exists = file.exists(); - if(exists) file.moveTo(file.sibling(file.name() + "-backup." + file.extension())); - try { - write(fileFor(slot)); - }catch (Exception e){ - if(exists) file.sibling(file.name() + "-backup." + file.extension()).moveTo(file); - throw new RuntimeException(e); - } - } - } - - public static void loadFromSlot(int slot){ - if(gwt){ - String string = Settings.getString("save-"+slot+"-data", ""); - ByteArrayInputStream stream = new ByteArrayInputStream(Base64Coder.decode(string)); - load(stream); - }else{ - load(fileFor(slot)); - } - } + public static void saveToSlot(int slot){ + if(gwt){ + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + write(stream); + Settings.putString("save-" + slot + "-data", new String(Base64Coder.encode(stream.toByteArray()))); + Settings.save(); + }else{ + FileHandle file = fileFor(slot); + boolean exists = file.exists(); + if(exists) file.moveTo(file.sibling(file.name() + "-backup." + file.extension())); + try{ + write(fileFor(slot)); + }catch(Exception e){ + if(exists) file.sibling(file.name() + "-backup." + file.extension()).moveTo(file); + throw new RuntimeException(e); + } + } + } - public static DataInputStream getSlotStream(int slot){ - if(gwt){ - String string = Settings.getString("save-"+slot+"-data", ""); - byte[] bytes = Base64Coder.decode(string); - return new DataInputStream(new ByteArrayInputStream(bytes)); - }else{ - return new DataInputStream(new InflaterInputStream(fileFor(slot).read())); - } - } - - public static boolean isSaveValid(int slot){ - try { - return isSaveValid(getSlotStream(slot)); - }catch (Exception e){ - return false; - } - } + public static void loadFromSlot(int slot){ + if(gwt){ + String string = Settings.getString("save-" + slot + "-data", ""); + ByteArrayInputStream stream = new ByteArrayInputStream(Base64Coder.decode(string)); + load(stream); + }else{ + load(fileFor(slot)); + } + } - public static boolean isSaveValid(FileHandle file){ - return isSaveValid(new DataInputStream(new InflaterInputStream(file.read()))); - } + public static DataInputStream getSlotStream(int slot){ + if(gwt){ + String string = Settings.getString("save-" + slot + "-data", ""); + byte[] bytes = Base64Coder.decode(string); + return new DataInputStream(new ByteArrayInputStream(bytes)); + }else{ + return new DataInputStream(new InflaterInputStream(fileFor(slot).read())); + } + } - public static boolean isSaveValid(DataInputStream stream){ + public static boolean isSaveValid(int slot){ + try{ + return isSaveValid(getSlotStream(slot)); + }catch(Exception e){ + return false; + } + } - try{ - int version = stream.readInt(); - SaveFileVersion ver = versions.get(version); - ver.getData(stream); - return true; - }catch (Exception e){ - e.printStackTrace(); - return false; - } - } + public static boolean isSaveValid(FileHandle file){ + return isSaveValid(new DataInputStream(new InflaterInputStream(file.read()))); + } - public static SaveMeta getData(int slot){ - return getData(getSlotStream(slot)); - } - - public static SaveMeta getData(DataInputStream stream){ - - try{ - int version = stream.readInt(); - SaveMeta meta = versions.get(version).getData(stream); - stream.close(); - return meta; - }catch (IOException e){ - throw new RuntimeException(e); - } - } - - public static FileHandle fileFor(int slot){ - return saveDirectory.child(slot + "." + Vars.saveExtension); - } + public static boolean isSaveValid(DataInputStream stream){ - public static void write(FileHandle file){ - write(file.write(false)); - } + try{ + int version = stream.readInt(); + SaveFileVersion ver = versions.get(version); + ver.getData(stream); + return true; + }catch(Exception e){ + e.printStackTrace(); + return false; + } + } - public static void write(OutputStream os){ - DataOutputStream stream; - - try{ - stream = new DataOutputStream(new DeflaterOutputStream(os)); - getVersion().write(stream); - stream.close(); - }catch (Exception e){ - throw new RuntimeException(e); - } - } + public static SaveMeta getData(int slot){ + return getData(getSlotStream(slot)); + } - public static void load(FileHandle file){ - try { - load(new InflaterInputStream(file.read())); - }catch (RuntimeException e){ - e.printStackTrace(); - FileHandle backup = file.sibling(file.name() + "-backup." + file.extension()); - if(backup.exists()){ - load(new InflaterInputStream(backup.read())); - } - } - } + public static SaveMeta getData(DataInputStream stream){ - public static void load(InputStream is){ - logic.reset(); + try{ + int version = stream.readInt(); + SaveMeta meta = versions.get(version).getData(stream); + stream.close(); + return meta; + }catch(IOException e){ + throw new RuntimeException(e); + } + } - DataInputStream stream; - - try{ - stream = new DataInputStream(is); - int version = stream.readInt(); - SaveFileVersion ver = versions.get(version); + public static FileHandle fileFor(int slot){ + return saveDirectory.child(slot + "." + Vars.saveExtension); + } - ver.read(stream); + public static void write(FileHandle file){ + write(file.write(false)); + } - stream.close(); - }catch (Exception e){ - throw new RuntimeException(e); - } - } + public static void write(OutputStream os){ + DataOutputStream stream; - public static SaveFileVersion getVersion(){ - return versionArray.peek(); - } + try{ + stream = new DataOutputStream(new DeflaterOutputStream(os)); + getVersion().write(stream); + stream.close(); + }catch(Exception e){ + throw new RuntimeException(e); + } + } + + public static void load(FileHandle file){ + try{ + load(new InflaterInputStream(file.read())); + }catch(RuntimeException e){ + e.printStackTrace(); + FileHandle backup = file.sibling(file.name() + "-backup." + file.extension()); + if(backup.exists()){ + load(new InflaterInputStream(backup.read())); + } + } + } + + public static void load(InputStream is){ + logic.reset(); + + DataInputStream stream; + + try{ + stream = new DataInputStream(is); + int version = stream.readInt(); + SaveFileVersion ver = versions.get(version); + + ver.read(stream); + + stream.close(); + }catch(Exception e){ + throw new RuntimeException(e); + } + } + + public static SaveFileVersion getVersion(){ + return versionArray.peek(); + } } diff --git a/core/src/io/anuke/mindustry/io/SaveMeta.java b/core/src/io/anuke/mindustry/io/SaveMeta.java index f241f8870e..5fd655f6b2 100644 --- a/core/src/io/anuke/mindustry/io/SaveMeta.java +++ b/core/src/io/anuke/mindustry/io/SaveMeta.java @@ -8,7 +8,7 @@ import java.util.Date; import static io.anuke.mindustry.Vars.world; -public class SaveMeta { +public class SaveMeta{ public int version; public String date; public GameMode mode; diff --git a/core/src/io/anuke/mindustry/io/Saves.java b/core/src/io/anuke/mindustry/io/Saves.java index 2e09aa311d..79b5756936 100644 --- a/core/src/io/anuke/mindustry/io/Saves.java +++ b/core/src/io/anuke/mindustry/io/Saves.java @@ -13,7 +13,7 @@ import java.io.IOException; import static io.anuke.mindustry.Vars.*; -public class Saves { +public class Saves{ private int nextSlot; private Array saves = new ThreadArray<>(); private SaveSlot current; @@ -22,7 +22,7 @@ public class Saves { public void load(){ saves.clear(); - for(int i = 0; i < saveSlots; i ++){ + for(int i = 0; i < saveSlots; i++){ if(SaveIO.isSaveValid(i)){ SaveSlot slot = new SaveSlot(i); saves.add(slot); @@ -32,7 +32,7 @@ public class Saves { } } - public SaveSlot getCurrent() { + public SaveSlot getCurrent(){ return current; } @@ -43,14 +43,14 @@ public class Saves { if(!state.is(State.menu) && !state.gameOver && current != null && current.isAutosave()){ time += Timers.delta(); - if(time > Settings.getInt("saveinterval")*60) { + if(time > Settings.getInt("saveinterval") * 60){ saving = true; Timers.run(2f, () -> { - try { + try{ SaveIO.saveToSlot(current.index); current.meta = SaveIO.getData(current.index); - }catch (Exception e){ + }catch(Exception e){ e.printStackTrace(); } saving = false; @@ -77,7 +77,7 @@ public class Saves { public void addSave(String name){ SaveSlot slot = new SaveSlot(nextSlot); - nextSlot ++; + nextSlot++; slot.setName(name); saves.add(slot); SaveIO.saveToSlot(slot.index); @@ -88,7 +88,7 @@ public class Saves { public SaveSlot importSave(FileHandle file) throws IOException{ SaveSlot slot = new SaveSlot(nextSlot); slot.importFile(file); - nextSlot ++; + nextSlot++; slot.setName(file.nameWithoutExtension()); saves.add(slot); slot.meta = SaveIO.getData(slot.index); @@ -129,11 +129,11 @@ public class Saves { } public String getName(){ - return Settings.getString("save-"+index+"-name", "untittled"); + return Settings.getString("save-" + index + "-name", "untittled"); } public void setName(String name){ - Settings.putString("save-"+index+"-name", name); + Settings.putString("save-" + index + "-name", name); Settings.save(); } @@ -150,18 +150,18 @@ public class Saves { } public boolean isAutosave(){ - return Settings.getBool("save-"+index+"-autosave", !gwt); + return Settings.getBool("save-" + index + "-autosave", !gwt); } public void setAutosave(boolean save){ - Settings.putBool("save-"+index + "-autosave", save); + Settings.putBool("save-" + index + "-autosave", save); Settings.save(); } public void importFile(FileHandle file) throws IOException{ try{ file.copyTo(SaveIO.fileFor(index)); - }catch (Exception e){ + }catch(Exception e){ throw new IOException(e); } } @@ -172,7 +172,7 @@ public class Saves { file = file.parent().child(file.nameWithoutExtension() + "." + saveExtension); } SaveIO.fileFor(index).copyTo(file); - }catch (Exception e){ + }catch(Exception e){ throw new IOException(e); } } diff --git a/core/src/io/anuke/mindustry/io/TypeIO.java b/core/src/io/anuke/mindustry/io/TypeIO.java index 152a72bc20..34475643ea 100644 --- a/core/src/io/anuke/mindustry/io/TypeIO.java +++ b/core/src/io/anuke/mindustry/io/TypeIO.java @@ -27,14 +27,16 @@ import java.nio.ByteBuffer; import static io.anuke.mindustry.Vars.*; -/**Class for specifying read/write methods for code generation.*/ -public class TypeIO { +/** + * Class for specifying read/write methods for code generation. + */ +public class TypeIO{ @WriteClass(Player.class) public static void writePlayer(ByteBuffer buffer, Player player){ if(player == null){ buffer.putInt(-1); - }else { + }else{ buffer.putInt(player.id); } } @@ -47,7 +49,7 @@ public class TypeIO { @WriteClass(Unit.class) public static void writeUnit(ByteBuffer buffer, Unit unit){ - buffer.put((byte)unit.getGroup().getID()); + buffer.put((byte) unit.getGroup().getID()); buffer.putInt(unit.getID()); } @@ -55,12 +57,12 @@ public class TypeIO { public static Unit readUnit(ByteBuffer buffer){ byte gid = buffer.get(); int id = buffer.getInt(); - return (Unit)Entities.getGroup(gid).getByID(id); + return (Unit) Entities.getGroup(gid).getByID(id); } @WriteClass(ShooterTrait.class) public static void writeShooter(ByteBuffer buffer, ShooterTrait trait){ - buffer.put((byte)trait.getGroup().getID()); + buffer.put((byte) trait.getGroup().getID()); buffer.putInt(trait.getID()); } @@ -85,10 +87,10 @@ public class TypeIO { @WriteClass(CarriableTrait.class) public static void writeCarriable(ByteBuffer buffer, CarriableTrait unit){ if(unit == null){ - buffer.put((byte)-1); + buffer.put((byte) -1); return; } - buffer.put((byte)unit.getGroup().getID()); + buffer.put((byte) unit.getGroup().getID()); buffer.putInt(unit.getID()); } @@ -99,16 +101,16 @@ public class TypeIO { return null; } int id = buffer.getInt(); - return (CarriableTrait)Entities.getGroup(gid).getByID(id); + return (CarriableTrait) Entities.getGroup(gid).getByID(id); } @WriteClass(CarryTrait.class) public static void writeCarry(ByteBuffer buffer, CarryTrait unit){ if(unit == null){ - buffer.put((byte)-1); + buffer.put((byte) -1); return; } - buffer.put((byte)unit.getGroup().getID()); + buffer.put((byte) unit.getGroup().getID()); buffer.putInt(unit.getID()); } @@ -119,12 +121,12 @@ public class TypeIO { return null; } int id = buffer.getInt(); - return (CarryTrait)Entities.getGroup(gid).getByID(id); + return (CarryTrait) Entities.getGroup(gid).getByID(id); } @WriteClass(BaseUnit.class) public static void writeBaseUnit(ByteBuffer buffer, BaseUnit unit){ - buffer.put((byte)unitGroups[unit.getTeam().ordinal()].getID()); + buffer.put((byte) unitGroups[unit.getTeam().ordinal()].getID()); buffer.putInt(unit.getID()); } @@ -132,7 +134,7 @@ public class TypeIO { public static BaseUnit writeBaseUnit(ByteBuffer buffer){ byte gid = buffer.get(); int id = buffer.getInt(); - return (BaseUnit)Entities.getGroup(gid).getByID(id); + return (BaseUnit) Entities.getGroup(gid).getByID(id); } @WriteClass(Tile.class) @@ -147,7 +149,7 @@ public class TypeIO { @WriteClass(Block.class) public static void writeBlock(ByteBuffer buffer, Block block){ - buffer.put((byte)block.id); + buffer.put((byte) block.id); } @ReadClass(Block.class) @@ -157,7 +159,7 @@ public class TypeIO { @WriteClass(KickReason.class) public static void writeKick(ByteBuffer buffer, KickReason reason){ - buffer.put((byte)reason.ordinal()); + buffer.put((byte) reason.ordinal()); } @ReadClass(KickReason.class) @@ -167,7 +169,7 @@ public class TypeIO { @WriteClass(Team.class) public static void writeTeam(ByteBuffer buffer, Team reason){ - buffer.put((byte)reason.ordinal()); + buffer.put((byte) reason.ordinal()); } @ReadClass(Team.class) @@ -177,7 +179,7 @@ public class TypeIO { @WriteClass(AdminAction.class) public static void writeAction(ByteBuffer buffer, AdminAction reason){ - buffer.put((byte)reason.ordinal()); + buffer.put((byte) reason.ordinal()); } @ReadClass(AdminAction.class) @@ -187,7 +189,7 @@ public class TypeIO { @WriteClass(Effect.class) public static void writeEffect(ByteBuffer buffer, Effect effect){ - buffer.putShort((short)effect.id); + buffer.putShort((short) effect.id); } @ReadClass(Effect.class) @@ -227,7 +229,7 @@ public class TypeIO { @WriteClass(Liquid.class) public static void writeLiquid(ByteBuffer buffer, Liquid liquid){ - buffer.put((byte)liquid.id); + buffer.put((byte) liquid.id); } @ReadClass(Liquid.class) @@ -247,7 +249,7 @@ public class TypeIO { @WriteClass(BulletType.class) public static void writeBulletType(ByteBuffer buffer, BulletType type){ - buffer.put((byte)type.id); + buffer.put((byte) type.id); } @ReadClass(BulletType.class) @@ -257,7 +259,7 @@ public class TypeIO { @WriteClass(Item.class) public static void writeItem(ByteBuffer buffer, Item item){ - buffer.put((byte)item.id); + buffer.put((byte) item.id); } @ReadClass(Item.class) @@ -267,7 +269,7 @@ public class TypeIO { @WriteClass(Recipe.class) public static void writeRecipe(ByteBuffer buffer, Recipe recipe){ - buffer.put((byte)recipe.id); + buffer.put((byte) recipe.id); } @ReadClass(Recipe.class) @@ -277,19 +279,19 @@ public class TypeIO { @WriteClass(String.class) public static void writeString(ByteBuffer buffer, String string){ - if(string != null) { + if(string != null){ byte[] bytes = string.getBytes(); buffer.putShort((short) bytes.length); buffer.put(bytes); }else{ - buffer.putShort((short)-1); + buffer.putShort((short) -1); } } @ReadClass(String.class) public static String readString(ByteBuffer buffer){ short length = buffer.getShort(); - if(length != -1) { + if(length != -1){ byte[] bytes = new byte[length]; buffer.get(bytes); return new String(bytes); @@ -300,7 +302,7 @@ public class TypeIO { @WriteClass(byte[].class) public static void writeBytes(ByteBuffer buffer, byte[] bytes){ - buffer.putShort((short)bytes.length); + buffer.putShort((short) bytes.length); buffer.put(bytes); } @@ -315,10 +317,10 @@ public class TypeIO { @WriteClass(TraceInfo.class) public static void writeTrace(ByteBuffer buffer, TraceInfo info){ buffer.putInt(info.playerid); - buffer.putShort((short)info.ip.getBytes().length); + buffer.putShort((short) info.ip.getBytes().length); buffer.put(info.ip.getBytes()); - buffer.put(info.modclient ? (byte)1 : 0); - buffer.put(info.android ? (byte)1 : 0); + buffer.put(info.modclient ? (byte) 1 : 0); + buffer.put(info.android ? (byte) 1 : 0); buffer.putInt(info.totalBlocksBroken); buffer.putInt(info.structureBlocksBroken); diff --git a/core/src/io/anuke/mindustry/io/Version.java b/core/src/io/anuke/mindustry/io/Version.java index ea5cd6d542..8bd816fb89 100644 --- a/core/src/io/anuke/mindustry/io/Version.java +++ b/core/src/io/anuke/mindustry/io/Version.java @@ -8,7 +8,7 @@ import io.anuke.ucore.util.Strings; import java.io.IOException; -public class Version { +public class Version{ public static String name; public static String type; public static String code; @@ -16,7 +16,7 @@ public class Version { public static String buildName; public static void init(){ - try { + try{ FileHandle file = Gdx.files.internal("version.properties"); ObjectMap map = new ObjectMap<>(); @@ -28,7 +28,7 @@ public class Version { build = Strings.canParseInt(map.get("build")) ? Integer.parseInt(map.get("build")) : -1; buildName = build == -1 ? map.get("build") : "build " + build; - }catch (IOException e){ + }catch(IOException e){ throw new RuntimeException(e); } } diff --git a/core/src/io/anuke/mindustry/io/versions/Save16.java b/core/src/io/anuke/mindustry/io/versions/Save16.java index b116b627cc..ece1178776 100644 --- a/core/src/io/anuke/mindustry/io/versions/Save16.java +++ b/core/src/io/anuke/mindustry/io/versions/Save16.java @@ -27,14 +27,14 @@ import java.io.IOException; import static io.anuke.mindustry.Vars.state; import static io.anuke.mindustry.Vars.world; -public class Save16 extends SaveFileVersion { +public class Save16 extends SaveFileVersion{ public Save16(){ super(16); } @Override - public void read(DataInputStream stream) throws IOException { + public void read(DataInputStream stream) throws IOException{ /*long loadTime = */ stream.readLong(); @@ -61,7 +61,7 @@ public class Save16 extends SaveFileVersion { IntMap blockMap = new IntMap<>(); - for(int i = 0; i < blocksize; i ++){ + for(int i = 0; i < blocksize; i++){ String name = stream.readUTF(); int id = stream.readShort(); @@ -72,9 +72,9 @@ public class Save16 extends SaveFileVersion { byte groups = stream.readByte(); - for (int i = 0; i < groups; i++) { + for(int i = 0; i < groups; i++){ int amount = stream.readInt(); - for (int j = 0; j < amount; j++) { + for(int j = 0; j < amount; j++){ byte typeid = stream.readByte(); SaveTrait trait = (SaveTrait) TypeTrait.getTypeByID(typeid).get(); trait.readSave(stream); @@ -94,8 +94,8 @@ public class Save16 extends SaveFileVersion { Tile[][] tiles = world.createTiles(width, height); - for (int i = 0; i < width * height; i++) { - int x = i % width, y = i /width; + for(int i = 0; i < width * height; i++){ + int x = i % width, y = i / width; byte floorid = stream.readByte(); byte wallid = stream.readByte(); byte elevation = stream.readByte(); @@ -103,9 +103,9 @@ public class Save16 extends SaveFileVersion { Tile tile = new Tile(x, y, floorid, wallid); tile.elevation = elevation; - if (wallid == Blocks.blockpart.id) { + if(wallid == Blocks.blockpart.id){ tile.link = stream.readByte(); - }else if (tile.entity != null) { + }else if(tile.entity != null){ byte tr = stream.readByte(); short health = stream.readShort(); @@ -118,10 +118,10 @@ public class Save16 extends SaveFileVersion { tile.entity.health = health; tile.setRotation(rotation); - if (tile.entity.items != null) tile.entity.items.read(stream); - if (tile.entity.power != null) tile.entity.power.read(stream); - if (tile.entity.liquids != null) tile.entity.liquids.read(stream); - if (tile.entity.cons != null) tile.entity.cons.read(stream); + if(tile.entity.items != null) tile.entity.items.read(stream); + if(tile.entity.power != null) tile.entity.power.read(stream); + if(tile.entity.liquids != null) tile.entity.liquids.read(stream); + if(tile.entity.cons != null) tile.entity.cons.read(stream); tile.entity.read(stream); @@ -132,7 +132,7 @@ public class Save16 extends SaveFileVersion { }else if(wallid == 0){ int consecutives = stream.readUnsignedByte(); - for (int j = i + 1; j < i + 1 + consecutives; j++) { + for(int j = i + 1; j < i + 1 + consecutives; j++){ int newx = j % width, newy = j / width; Tile newTile = new Tile(newx, newy, floorid, wallid); newTile.elevation = elevation; @@ -149,7 +149,7 @@ public class Save16 extends SaveFileVersion { } @Override - public void write(DataOutputStream stream) throws IOException { + public void write(DataOutputStream stream) throws IOException{ //--META-- stream.writeInt(version); //version id stream.writeLong(TimeUtils.millis()); //last saved @@ -168,7 +168,7 @@ public class Save16 extends SaveFileVersion { stream.writeInt(Block.all().size); - for(int i = 0; i < Block.all().size; i ++){ + for(int i = 0; i < Block.all().size; i++){ Block block = Block.all().get(i); stream.writeUTF(block.name); stream.writeShort(block.id); @@ -181,7 +181,7 @@ public class Save16 extends SaveFileVersion { for(EntityGroup group : Entities.getAllGroups()){ if(!group.isEmpty() && group.all().get(0) instanceof SaveTrait){ - groups ++; + groups++; } } @@ -191,8 +191,8 @@ public class Save16 extends SaveFileVersion { if(!group.isEmpty() && group.all().get(0) instanceof SaveTrait){ stream.writeInt(group.size()); for(Entity entity : group.all()){ - stream.writeByte(((SaveTrait)entity).getTypeID()); - ((SaveTrait)entity).writeSave(stream); + stream.writeByte(((SaveTrait) entity).getTypeID()); + ((SaveTrait) entity).writeSave(stream); } } } @@ -205,7 +205,7 @@ public class Save16 extends SaveFileVersion { stream.writeShort(world.width()); stream.writeShort(world.height()); - for (int i = 0; i < world.width() * world.height(); i++) { + for(int i = 0; i < world.width() * world.height(); i++){ Tile tile = world.tile(i); stream.writeByte(tile.getFloorID()); @@ -216,7 +216,7 @@ public class Save16 extends SaveFileVersion { stream.writeByte(tile.link); }else if(tile.entity != null){ stream.writeByte(Bits.packByte(tile.getTeamID(), tile.getRotation())); //team + rotation - stream.writeShort((short)tile.entity.health); //health + stream.writeShort((short) tile.entity.health); //health if(tile.entity.items != null) tile.entity.items.write(stream); if(tile.entity.power != null) tile.entity.power.write(stream); @@ -227,14 +227,14 @@ public class Save16 extends SaveFileVersion { }else if(tile.getWallID() == 0){ int consecutives = 0; - for (int j = i + 1; j < world.width() * world.height() && consecutives < 255; j++) { + for(int j = i + 1; j < world.width() * world.height() && consecutives < 255; j++){ Tile nextTile = world.tile(j); if(nextTile.getFloorID() != tile.getFloorID() || nextTile.getWallID() != 0 || nextTile.elevation != tile.elevation){ break; } - consecutives ++; + consecutives++; } stream.writeByte(consecutives); diff --git a/core/src/io/anuke/mindustry/net/Administration.java b/core/src/io/anuke/mindustry/net/Administration.java index c63f628c2b..bb838d4afd 100644 --- a/core/src/io/anuke/mindustry/net/Administration.java +++ b/core/src/io/anuke/mindustry/net/Administration.java @@ -15,24 +15,30 @@ import io.anuke.ucore.core.Settings; import static io.anuke.mindustry.Vars.headless; import static io.anuke.mindustry.Vars.world; -public class Administration { +public class Administration{ public static final int defaultMaxBrokenBlocks = 15; - public static final int defaultBreakCooldown = 1000*15; + public static final int defaultBreakCooldown = 1000 * 15; - /**All player info. Maps UUIDs to info. This persists throughout restarts.*/ + /** + * All player info. Maps UUIDs to info. This persists throughout restarts. + */ private ObjectMap playerInfo = new ObjectMap<>(); - /**Maps UUIDs to trace infos. This is wiped when a player logs off.*/ + /** + * Maps UUIDs to trace infos. This is wiped when a player logs off. + */ private ObjectMap traceInfo = new ObjectMap<>(); - /**Maps packed coordinates to logs for that coordinate */ + /** + * Maps packed coordinates to logs for that coordinate + */ private IntMap> editLogs = new IntMap<>(); private Array bannedIPs = new Array<>(); public Administration(){ Settings.defaultList( - "antigrief", false, - "antigrief-max", defaultMaxBrokenBlocks, - "antigrief-cooldown", defaultBreakCooldown + "antigrief", false, + "antigrief-max", defaultMaxBrokenBlocks, + "antigrief-cooldown", defaultBreakCooldown ); load(); @@ -42,6 +48,11 @@ public class Administration { return Settings.getBool("antigrief"); } + public void setAntiGrief(boolean antiGrief){ + Settings.putBool("antigrief", antiGrief); + Settings.save(); + } + public boolean allowsCustomClients(){ return Settings.getBool("allow-custom", !headless); } @@ -55,31 +66,26 @@ public class Administration { return false; } - public void setAntiGrief(boolean antiGrief){ - Settings.putBool("antigrief", antiGrief); - Settings.save(); - } - public void setAntiGriefParams(int maxBreak, int cooldown){ Settings.putInt("antigrief-max", maxBreak); Settings.putInt("antigrief-cooldown", cooldown); Settings.save(); } - public IntMap> getEditLogs() { + public IntMap> getEditLogs(){ return editLogs; } - public void logEdit(int x, int y, Player player, Block block, int rotation, EditLog.EditAction action) { - if(block instanceof BlockPart || block instanceof Rock || block instanceof Floor || block instanceof StaticBlock) return; - if(editLogs.containsKey(x + y * world.width())) { - editLogs.get(x + y * world.width()).add(new EditLog(player.name, block, rotation, action)); - } - else { - Array logs = new Array<>(); - logs.add(new EditLog(player.name, block, rotation, action)); - editLogs.put(x + y * world.width(), logs); - } + public void logEdit(int x, int y, Player player, Block block, int rotation, EditLog.EditAction action){ + if(block instanceof BlockPart || block instanceof Rock || block instanceof Floor || block instanceof StaticBlock) + return; + if(editLogs.containsKey(x + y * world.width())){ + editLogs.get(x + y * world.width()).add(new EditLog(player.name, block, rotation, action)); + }else{ + Array logs = new Array<>(); + logs.add(new EditLog(player.name, block, rotation, action)); + editLogs.put(x + y * world.width(), logs); + } } /* @@ -143,18 +149,18 @@ public class Administration { long[] breaks = info.lastBroken; int shiftBy = 0; - for(int i = 0; i < breaks.length && breaks[i] != 0; i ++){ + for(int i = 0; i < breaks.length && breaks[i] != 0; i++){ if(TimeUtils.timeSinceMillis(breaks[i]) >= Settings.getInt("antigrief-cooldown")){ shiftBy = i; } } - for (int i = 0; i < breaks.length; i++) { + for(int i = 0; i < breaks.length; i++){ breaks[i] = (i + shiftBy >= breaks.length) ? 0 : breaks[i + shiftBy]; } int remaining = 0; - for(int i = 0; i < breaks.length; i ++){ + for(int i = 0; i < breaks.length; i++){ if(breaks[i] == 0){ remaining = breaks.length - i; break; @@ -167,17 +173,21 @@ public class Administration { return true; } - /**Call when a player joins to update their information here.*/ + /** + * Call when a player joins to update their information here. + */ public void updatePlayerJoined(String id, String ip, String name){ PlayerInfo info = getCreateInfo(id); info.lastName = name; info.lastIP = ip; - info.timesJoined ++; + info.timesJoined++; if(!info.names.contains(name, false)) info.names.add(name); if(!info.ips.contains(ip, false)) info.ips.add(ip); } - /**Returns trace info by IP.*/ + /** + * Returns trace info by IP. + */ public TraceInfo getTraceByID(String uuid){ if(!traceInfo.containsKey(uuid)) traceInfo.put(uuid, new TraceInfo(uuid)); @@ -188,8 +198,10 @@ public class Administration { traceInfo.clear(); } - /**Bans a player by IP; returns whether this player was already banned. - * If there are players who at any point had this IP, they will be UUID banned as well.*/ + /** + * Bans a player by IP; returns whether this player was already banned. + * If there are players who at any point had this IP, they will be UUID banned as well. + */ public boolean banPlayerIP(String ip){ if(bannedIPs.contains(ip, false)) return false; @@ -206,7 +218,9 @@ public class Administration { return true; } - /**Bans a player by UUID; returns whether this player was already banned.*/ + /** + * Bans a player by UUID; returns whether this player was already banned. + */ public boolean banPlayerID(String id){ if(playerInfo.containsKey(id) && playerInfo.get(id).banned) return false; @@ -218,8 +232,10 @@ public class Administration { return true; } - /**Unbans a player by IP; returns whether this player was banned in the first place. - * This method also unbans any player that was banned and had this IP.*/ + /** + * Unbans a player by IP; returns whether this player was banned in the first place. + * This method also unbans any player that was banned and had this IP. + */ public boolean unbanPlayerIP(String ip){ boolean found = bannedIPs.contains(ip, false); @@ -237,8 +253,10 @@ public class Administration { return found; } - /**Unbans a player by ID; returns whether this player was banned in the first place. - * This also unbans all IPs the player used.*/ + /** + * Unbans a player by ID; returns whether this player was banned in the first place. + * This also unbans all IPs the player used. + */ public boolean unbanPlayerID(String id){ PlayerInfo info = getCreateInfo(id); @@ -252,7 +270,9 @@ public class Administration { return true; } - /**Returns list of all players with admin status*/ + /** + * Returns list of all players with admin status + */ public Array getAdmins(){ Array result = new Array<>(); for(PlayerInfo info : playerInfo.values()){ @@ -263,7 +283,9 @@ public class Administration { return result; } - /**Returns list of all players with admin status*/ + /** + * Returns list of all players with admin status + */ public Array getBanned(){ Array result = new Array<>(); for(PlayerInfo info : playerInfo.values()){ @@ -274,12 +296,16 @@ public class Administration { return result; } - /**Returns all banned IPs. This does not include the IPs of ID-banned players.*/ + /** + * Returns all banned IPs. This does not include the IPs of ID-banned players. + */ public Array getBannedIPs(){ return bannedIPs; } - /**Makes a player an admin. Returns whether this player was already an admin.*/ + /** + * Makes a player an admin. Returns whether this player was already an admin. + */ public boolean adminPlayer(String id, String usid){ PlayerInfo info = getCreateInfo(id); @@ -293,7 +319,9 @@ public class Administration { return true; } - /**Makes a player no longer an admin. Returns whether this player was an admin in the first place.*/ + /** + * Makes a player no longer an admin. Returns whether this player was an admin in the first place. + */ public boolean unAdminPlayer(String id){ PlayerInfo info = getCreateInfo(id); @@ -401,7 +429,8 @@ public class Administration { this.id = id; } - private PlayerInfo(){} + private PlayerInfo(){ + } } } diff --git a/core/src/io/anuke/mindustry/net/EditLog.java b/core/src/io/anuke/mindustry/net/EditLog.java index 33d1eb42e1..ab922ae8e0 100644 --- a/core/src/io/anuke/mindustry/net/EditLog.java +++ b/core/src/io/anuke/mindustry/net/EditLog.java @@ -2,20 +2,20 @@ package io.anuke.mindustry.net; import io.anuke.mindustry.world.Block; -public class EditLog { - public String playername; - public Block block; - public int rotation; - public EditAction action; - - EditLog(String playername, Block block, int rotation, EditAction action) { - this.playername = playername; - this.block = block; - this.rotation = rotation; - this.action = action; - } - - public enum EditAction { - PLACE, BREAK +public class EditLog{ + public String playername; + public Block block; + public int rotation; + public EditAction action; + + EditLog(String playername, Block block, int rotation, EditAction action){ + this.playername = playername; + this.block = block; + this.rotation = rotation; + this.action = action; + } + + public enum EditAction{ + PLACE, BREAK } } diff --git a/core/src/io/anuke/mindustry/net/Host.java b/core/src/io/anuke/mindustry/net/Host.java index 631f74a726..36b5a5ecb9 100644 --- a/core/src/io/anuke/mindustry/net/Host.java +++ b/core/src/io/anuke/mindustry/net/Host.java @@ -1,6 +1,6 @@ package io.anuke.mindustry.net; -public class Host { +public class Host{ public final String name; public final String address; public final String mapname; diff --git a/core/src/io/anuke/mindustry/net/In.java b/core/src/io/anuke/mindustry/net/In.java index 712eec04bb..d00e0aba41 100644 --- a/core/src/io/anuke/mindustry/net/In.java +++ b/core/src/io/anuke/mindustry/net/In.java @@ -1,7 +1,9 @@ package io.anuke.mindustry.net; -/**Stores class nameas for remote method invocation for consistency's sake.*/ -public class In { +/** + * Stores class nameas for remote method invocation for consistency's sake. + */ +public class In{ public static final String normal = "Call"; public static final String entities = "CallEntity"; public static final String blocks = "CallBlocks"; diff --git a/core/src/io/anuke/mindustry/net/Interpolator.java b/core/src/io/anuke/mindustry/net/Interpolator.java index ed983bbbf0..9748544b28 100644 --- a/core/src/io/anuke/mindustry/net/Interpolator.java +++ b/core/src/io/anuke/mindustry/net/Interpolator.java @@ -5,7 +5,7 @@ import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.TimeUtils; import io.anuke.ucore.util.Mathf; -public class Interpolator { +public class Interpolator{ //used for movement public Vector2 target = new Vector2(); public Vector2 last = new Vector2(); @@ -55,7 +55,7 @@ public class Interpolator { values = new float[targets.length]; } - for (int i = 0; i < values.length; i++) { + for(int i = 0; i < values.length; i++){ values[i] = Mathf.slerp(values[i], targets[i], alpha); } }else{ diff --git a/core/src/io/anuke/mindustry/net/Net.java b/core/src/io/anuke/mindustry/net/Net.java index 41d5abc494..bd15fc6614 100644 --- a/core/src/io/anuke/mindustry/net/Net.java +++ b/core/src/io/anuke/mindustry/net/Net.java @@ -25,289 +25,393 @@ import static io.anuke.mindustry.Vars.headless; import static io.anuke.mindustry.Vars.ui; public class Net{ - public static final Object packetPoolLock = new Object(); + public static final Object packetPoolLock = new Object(); - private static boolean server; - private static boolean active; - private static boolean clientLoaded; - private static Array packetQueue = new Array<>(); - private static ObjectMap, Consumer> clientListeners = new ObjectMap<>(); - private static ObjectMap, BiConsumer> serverListeners = new ObjectMap<>(); - private static ClientProvider clientProvider; - private static ServerProvider serverProvider; + private static boolean server; + private static boolean active; + private static boolean clientLoaded; + private static Array packetQueue = new Array<>(); + private static ObjectMap, Consumer> clientListeners = new ObjectMap<>(); + private static ObjectMap, BiConsumer> serverListeners = new ObjectMap<>(); + private static ClientProvider clientProvider; + private static ServerProvider serverProvider; - private static IntMap streams = new IntMap<>(); + private static IntMap streams = new IntMap<>(); - /**Display a network error.*/ - public static void showError(String text){ - if(!headless){ - ui.showError(text); - }else{ - Log.err(text); - } - } + /** + * Display a network error. + */ + public static void showError(String text){ + if(!headless){ + ui.showError(text); + }else{ + Log.err(text); + } + } - /**Sets the client loaded status, or whether it will recieve normal packets from the server.*/ - public static void setClientLoaded(boolean loaded){ - clientLoaded = loaded; + /** + * Sets the client loaded status, or whether it will recieve normal packets from the server. + */ + public static void setClientLoaded(boolean loaded){ + clientLoaded = loaded; - if(loaded){ - //handle all packets that were skipped while loading - for(int i = 0; i < packetQueue.size; i ++){ + if(loaded){ + //handle all packets that were skipped while loading + for(int i = 0; i < packetQueue.size; i++){ Log.info("Processing {0} packet post-load.", ClassReflection.getSimpleName(packetQueue.get(i).getClass())); - handleClientReceived(packetQueue.get(i)); - } - } - //clear inbound packet queue - packetQueue.clear(); - } - - /**Connect to an address.*/ - public static void connect(String ip, int port) throws IOException{ - if(!active) { - clientProvider.connect(ip, port); - active = true; - server = false; - }else{ - throw new IOException("Already connected!"); - } - } + handleClientReceived(packetQueue.get(i)); + } + } + //clear inbound packet queue + packetQueue.clear(); + } - /**Host a server at an address*/ - public static void host(int port) throws IOException{ - serverProvider.host(port); - active = true; - server = true; + /** + * Connect to an address. + */ + public static void connect(String ip, int port) throws IOException{ + if(!active){ + clientProvider.connect(ip, port); + active = true; + server = false; + }else{ + throw new IOException("Already connected!"); + } + } - Timers.runTask(60f, Platform.instance::updateRPC); - } + /** + * Host a server at an address + */ + public static void host(int port) throws IOException{ + serverProvider.host(port); + active = true; + server = true; - /**Closes the server.*/ - public static void closeServer(){ + Timers.runTask(60f, Platform.instance::updateRPC); + } + + /** + * Closes the server. + */ + public static void closeServer(){ serverProvider.close(); server = false; active = false; } public static void disconnect(){ - clientProvider.disconnect(); - server = false; - active = false; - } + clientProvider.disconnect(); + server = false; + active = false; + } - /**Starts discovering servers on a different thread. Does not work with GWT. - * Callback is run on the main libGDX thread.*/ - public static void discoverServers(Consumer> cons){ - clientProvider.discover(cons); - } + /** + * Starts discovering servers on a different thread. Does not work with GWT. + * Callback is run on the main libGDX thread. + */ + public static void discoverServers(Consumer> cons){ + clientProvider.discover(cons); + } - /**Returns a list of all connections IDs.*/ - public static Array getConnections(){ - return (Array)serverProvider.getConnections(); - } + /** + * Returns a list of all connections IDs. + */ + public static Array getConnections(){ + return (Array) serverProvider.getConnections(); + } - /**Returns a connection by ID*/ - public static NetConnection getConnection(int id){ - return serverProvider.getByID(id); - } - - /**Send an object to all connected clients, or to the server if this is a client.*/ - public static void send(Object object, SendMode mode){ - if(server){ - if(serverProvider != null) serverProvider.send(object, mode); - }else { - if(clientProvider != null) clientProvider.send(object, mode); - } - } + /** + * Returns a connection by ID + */ + public static NetConnection getConnection(int id){ + return serverProvider.getByID(id); + } - /**Send an object to a certain client. Server-side only*/ - public static void sendTo(int id, Object object, SendMode mode){ - serverProvider.sendTo(id, object, mode); - } + /** + * Send an object to all connected clients, or to the server if this is a client. + */ + public static void send(Object object, SendMode mode){ + if(server){ + if(serverProvider != null) serverProvider.send(object, mode); + }else{ + if(clientProvider != null) clientProvider.send(object, mode); + } + } - /**Send an object to everyone EXCEPT certain client. Server-side only*/ - public static void sendExcept(int id, Object object, SendMode mode){ - serverProvider.sendExcept(id, object, mode); - } + /** + * Send an object to a certain client. Server-side only + */ + public static void sendTo(int id, Object object, SendMode mode){ + serverProvider.sendTo(id, object, mode); + } - /**Send a stream to a specific client. Server-side only.*/ - public static void sendStream(int id, Streamable stream){ - serverProvider.sendStream(id, stream); - } - - /**Sets the net clientProvider, e.g. what handles sending, recieving and connecting to a server.*/ - public static void setClientProvider(ClientProvider provider){ - Net.clientProvider = provider; - } + /** + * Send an object to everyone EXCEPT certain client. Server-side only + */ + public static void sendExcept(int id, Object object, SendMode mode){ + serverProvider.sendExcept(id, object, mode); + } - /**Sets the net serverProvider, e.g. what handles hosting a server.*/ - public static void setServerProvider(ServerProvider provider){ - Net.serverProvider = provider; - } + /** + * Send a stream to a specific client. Server-side only. + */ + public static void sendStream(int id, Streamable stream){ + serverProvider.sendStream(id, stream); + } - /**Registers a client listener for when an object is recieved.*/ - public static void handleClient(Class type, Consumer listener){ - clientListeners.put(type, listener); - } + /** + * Sets the net clientProvider, e.g. what handles sending, recieving and connecting to a server. + */ + public static void setClientProvider(ClientProvider provider){ + Net.clientProvider = provider; + } - /**Registers a server listener for when an object is recieved.*/ - public static void handleServer(Class type, BiConsumer listener){ - serverListeners.put(type, (BiConsumer) listener); - } - - /**Call to handle a packet being recieved for the client.*/ - public static void handleClientReceived(Object object){ + /** + * Sets the net serverProvider, e.g. what handles hosting a server. + */ + public static void setServerProvider(ServerProvider provider){ + Net.serverProvider = provider; + } - if(object instanceof StreamBegin) { - StreamBegin b = (StreamBegin) object; - streams.put(b.id, new StreamBuilder(b)); - }else if(object instanceof StreamChunk) { - StreamChunk c = (StreamChunk)object; - StreamBuilder builder = streams.get(c.id); - if(builder == null){ - throw new RuntimeException("Recieved stream chunk without a StreamBegin beforehand!"); - } - builder.add(c.data); - if(builder.isDone()){ - streams.remove(builder.id); - handleClientReceived(builder.build()); - } - }else if(clientListeners.get(object.getClass()) != null){ + /** + * Registers a client listener for when an object is recieved. + */ + public static void handleClient(Class type, Consumer listener){ + clientListeners.put(type, listener); + } - if(clientLoaded || ((object instanceof Packet) && ((Packet) object).isImportant())){ - if(clientListeners.get(object.getClass()) != null) clientListeners.get(object.getClass()).accept(object); - synchronized (packetPoolLock) { - Pooling.free(object); - } - }else if(!((object instanceof Packet) && ((Packet) object).isUnimportant())){ - packetQueue.add(object); - Log.info("Queuing packet {0}.", ClassReflection.getSimpleName(object.getClass())); - }else{ - synchronized (packetPoolLock) { - Pooling.free(object); - } - } - }else{ - Log.err("Unhandled packet type: '{0}'!", ClassReflection.getSimpleName(object.getClass())); - } - } + /** + * Registers a server listener for when an object is recieved. + */ + public static void handleServer(Class type, BiConsumer listener){ + serverListeners.put(type, (BiConsumer) listener); + } - /**Call to handle a packet being recieved for the server.*/ - public static void handleServerReceived(int connection, Object object){ + /** + * Call to handle a packet being recieved for the client. + */ + public static void handleClientReceived(Object object){ - if(serverListeners.get(object.getClass()) != null){ - if(serverListeners.get(object.getClass()) != null) serverListeners.get(object.getClass()).accept(connection, object); - synchronized (packetPoolLock) { - Pooling.free(object); - } - }else{ - Log.err("Unhandled packet type: '{0}'!", ClassReflection.getSimpleName(object.getClass())); - } - } + if(object instanceof StreamBegin){ + StreamBegin b = (StreamBegin) object; + streams.put(b.id, new StreamBuilder(b)); + }else if(object instanceof StreamChunk){ + StreamChunk c = (StreamChunk) object; + StreamBuilder builder = streams.get(c.id); + if(builder == null){ + throw new RuntimeException("Recieved stream chunk without a StreamBegin beforehand!"); + } + builder.add(c.data); + if(builder.isDone()){ + streams.remove(builder.id); + handleClientReceived(builder.build()); + } + }else if(clientListeners.get(object.getClass()) != null){ - /**Pings a host in an new thread. If an error occured, failed() should be called with the exception. */ - public static void pingHost(String address, int port, Consumer valid, Consumer failed){ - clientProvider.pingHost(address, port, valid, failed); - } + if(clientLoaded || ((object instanceof Packet) && ((Packet) object).isImportant())){ + if(clientListeners.get(object.getClass()) != null) + clientListeners.get(object.getClass()).accept(object); + synchronized(packetPoolLock){ + Pooling.free(object); + } + }else if(!((object instanceof Packet) && ((Packet) object).isUnimportant())){ + packetQueue.add(object); + Log.info("Queuing packet {0}.", ClassReflection.getSimpleName(object.getClass())); + }else{ + synchronized(packetPoolLock){ + Pooling.free(object); + } + } + }else{ + Log.err("Unhandled packet type: '{0}'!", ClassReflection.getSimpleName(object.getClass())); + } + } - /**Update client ping.*/ - public static void updatePing(){ - clientProvider.updatePing(); - } + /** + * Call to handle a packet being recieved for the server. + */ + public static void handleServerReceived(int connection, Object object){ - /**Get the client ping. Only valid after updatePing().*/ - public static int getPing(){ - return server() ? 0 : clientProvider.getPing(); - } - - /**Whether the net is active, e.g. whether this is a multiplayer game.*/ - public static boolean active(){ - return active; - } - - /**Whether this is a server or not.*/ - public static boolean server(){ - return server && active; - } + if(serverListeners.get(object.getClass()) != null){ + if(serverListeners.get(object.getClass()) != null) + serverListeners.get(object.getClass()).accept(connection, object); + synchronized(packetPoolLock){ + Pooling.free(object); + } + }else{ + Log.err("Unhandled packet type: '{0}'!", ClassReflection.getSimpleName(object.getClass())); + } + } - /**Whether this is a client or not.*/ - public static boolean client(){ - return !server && active; - } + /** + * Pings a host in an new thread. If an error occured, failed() should be called with the exception. + */ + public static void pingHost(String address, int port, Consumer valid, Consumer failed){ + clientProvider.pingHost(address, port, valid, failed); + } - public static void dispose(){ - if(clientProvider != null) clientProvider.dispose(); - if(serverProvider != null) serverProvider.dispose(); - clientProvider = null; - serverProvider = null; - server = false; - active = false; - } + /** + * Update client ping. + */ + public static void updatePing(){ + clientProvider.updatePing(); + } - public static void http(String url, String method, Consumer listener, Consumer failure){ - HttpRequest req = new HttpRequestBuilder().newRequest() - .method(method).url(url).build(); + /** + * Get the client ping. Only valid after updatePing(). + */ + public static int getPing(){ + return server() ? 0 : clientProvider.getPing(); + } - Gdx.net.sendHttpRequest(req, new HttpResponseListener() { - @Override - public void handleHttpResponse(HttpResponse httpResponse) { - listener.accept(httpResponse.getResultAsString()); - } + /** + * Whether the net is active, e.g. whether this is a multiplayer game. + */ + public static boolean active(){ + return active; + } - @Override - public void failed(Throwable t) { - failure.accept(t); - } + /** + * Whether this is a server or not. + */ + public static boolean server(){ + return server && active; + } - @Override - public void cancelled() {} - }); - } + /** + * Whether this is a client or not. + */ + public static boolean client(){ + return !server && active; + } - /**Client implementation.*/ - public interface ClientProvider { - /**Connect to a server.*/ - void connect(String ip, int port) throws IOException; - /**Send an object to the server.*/ - void send(Object object, SendMode mode); - /**Update the ping. Should be done every second or so.*/ - void updatePing(); - /**Get ping in milliseconds. Will only be valid after a call to updatePing.*/ - int getPing(); - /**Disconnect from the server.*/ - void disconnect(); - /**Discover servers. This should run the callback regardless of whether any servers are found. Should not block. - * Callback should be run on libGDX main thread.*/ + public static void dispose(){ + if(clientProvider != null) clientProvider.dispose(); + if(serverProvider != null) serverProvider.dispose(); + clientProvider = null; + serverProvider = null; + server = false; + active = false; + } + + public static void http(String url, String method, Consumer listener, Consumer failure){ + HttpRequest req = new HttpRequestBuilder().newRequest() + .method(method).url(url).build(); + + Gdx.net.sendHttpRequest(req, new HttpResponseListener(){ + @Override + public void handleHttpResponse(HttpResponse httpResponse){ + listener.accept(httpResponse.getResultAsString()); + } + + @Override + public void failed(Throwable t){ + failure.accept(t); + } + + @Override + public void cancelled(){ + } + }); + } + + public enum SendMode{ + tcp, udp + } + + /** + * Client implementation. + */ + public interface ClientProvider{ + /** + * Connect to a server. + */ + void connect(String ip, int port) throws IOException; + + /** + * Send an object to the server. + */ + void send(Object object, SendMode mode); + + /** + * Update the ping. Should be done every second or so. + */ + void updatePing(); + + /** + * Get ping in milliseconds. Will only be valid after a call to updatePing. + */ + int getPing(); + + /** + * Disconnect from the server. + */ + void disconnect(); + + /** + * Discover servers. This should run the callback regardless of whether any servers are found. Should not block. + * Callback should be run on libGDX main thread. + */ void discover(Consumer> callback); - /**Ping a host. If an error occured, failed() should be called with the exception. */ + + /** + * Ping a host. If an error occured, failed() should be called with the exception. + */ void pingHost(String address, int port, Consumer valid, Consumer failed); - /**Close all connections.*/ - void dispose(); - } - /**Server implementation.*/ - public interface ServerProvider { - /**Host a server at specified port.*/ - void host(int port) throws IOException; - /**Sends a large stream of data to a specific client.*/ - void sendStream(int id, Streamable stream); - /**Send an object to everyone connected.*/ - void send(Object object, SendMode mode); - /**Send an object to a specific client ID.*/ - void sendTo(int id, Object object, SendMode mode); - /**Send an object to everyone except a client ID.*/ - void sendExcept(int id, Object object, SendMode mode); - /**Close the server connection.*/ - void close(); - /**Return all connected users.*/ - Array getConnections(); - /**Returns a connection by ID.*/ - NetConnection getByID(int id); - /**Close all connections.*/ - void dispose(); - } + /** + * Close all connections. + */ + void dispose(); + } - public enum SendMode{ - tcp, udp - } + /** + * Server implementation. + */ + public interface ServerProvider{ + /** + * Host a server at specified port. + */ + void host(int port) throws IOException; + + /** + * Sends a large stream of data to a specific client. + */ + void sendStream(int id, Streamable stream); + + /** + * Send an object to everyone connected. + */ + void send(Object object, SendMode mode); + + /** + * Send an object to a specific client ID. + */ + void sendTo(int id, Object object, SendMode mode); + + /** + * Send an object to everyone except a client ID. + */ + void sendExcept(int id, Object object, SendMode mode); + + /** + * Close the server connection. + */ + void close(); + + /** + * Return all connected users. + */ + Array getConnections(); + + /** + * Returns a connection by ID. + */ + NetConnection getByID(int id); + + /** + * Close all connections. + */ + void dispose(); + } } diff --git a/core/src/io/anuke/mindustry/net/NetConnection.java b/core/src/io/anuke/mindustry/net/NetConnection.java index b4b25a76be..9c66726434 100644 --- a/core/src/io/anuke/mindustry/net/NetConnection.java +++ b/core/src/io/anuke/mindustry/net/NetConnection.java @@ -2,14 +2,18 @@ package io.anuke.mindustry.net; import io.anuke.mindustry.net.Net.SendMode; -public abstract class NetConnection { +public abstract class NetConnection{ public final int id; public final String address; - /**The current base snapshot that the client is absolutely confirmed to have recieved. - * All sent snapshots should be taking the diff from this base snapshot, if it isn't null.*/ + /** + * The current base snapshot that the client is absolutely confirmed to have recieved. + * All sent snapshots should be taking the diff from this base snapshot, if it isn't null. + */ public byte[] currentBaseSnapshot; - /**ID of the current base snapshot.*/ + /** + * ID of the current base snapshot. + */ public int currentBaseID = -1; public int lastSentBase = -1; @@ -17,9 +21,13 @@ public abstract class NetConnection { public byte[] lastSentRawSnapshot; public int lastSentSnapshotID = -1; - /**ID of last recieved client snapshot.*/ + /** + * ID of last recieved client snapshot. + */ public int lastRecievedClientSnapshot = -1; - /**Timestamp of last recieved snapshot.*/ + /** + * Timestamp of last recieved snapshot. + */ public long lastRecievedClientTime; public boolean hasConnected = false; @@ -34,5 +42,6 @@ public abstract class NetConnection { } public abstract void send(Object object, SendMode mode); + public abstract void close(); } diff --git a/core/src/io/anuke/mindustry/net/NetEvents.java b/core/src/io/anuke/mindustry/net/NetEvents.java index 749513a3a4..01dbfe5b90 100644 --- a/core/src/io/anuke/mindustry/net/NetEvents.java +++ b/core/src/io/anuke/mindustry/net/NetEvents.java @@ -9,7 +9,7 @@ import io.anuke.mindustry.entities.Player; import static io.anuke.mindustry.Vars.maxTextLength; import static io.anuke.mindustry.Vars.playerGroup; -public class NetEvents { +public class NetEvents{ @Remote(called = Loc.server, targets = Loc.both, forward = true) public static void sendMessage(Player player, String message){ diff --git a/core/src/io/anuke/mindustry/net/NetworkIO.java b/core/src/io/anuke/mindustry/net/NetworkIO.java index 1625079e2e..8ece7638a3 100644 --- a/core/src/io/anuke/mindustry/net/NetworkIO.java +++ b/core/src/io/anuke/mindustry/net/NetworkIO.java @@ -24,7 +24,7 @@ import java.nio.ByteBuffer; import static io.anuke.mindustry.Vars.*; -public class NetworkIO { +public class NetworkIO{ public static void writeWorld(Player player, OutputStream os){ @@ -59,7 +59,7 @@ public class NetworkIO { stream.writeShort(world.width()); stream.writeShort(world.height()); - for (int i = 0; i < world.width() * world.height(); i++) { + for(int i = 0; i < world.width() * world.height(); i++){ Tile tile = world.tile(i); stream.writeByte(tile.getFloorID()); @@ -70,7 +70,7 @@ public class NetworkIO { stream.writeByte(tile.link); }else if(tile.entity != null){ stream.writeByte(Bits.packByte(tile.getTeamID(), tile.getRotation())); //team + rotation - stream.writeShort((short)tile.entity.health); //health + stream.writeShort((short) tile.entity.health); //health if(tile.entity.items != null) tile.entity.items.write(stream); if(tile.entity.power != null) tile.entity.power.write(stream); @@ -81,14 +81,14 @@ public class NetworkIO { }else if(tile.getWallID() == 0){ int consecutives = 0; - for (int j = i + 1; j < world.width() * world.height() && consecutives < 255; j++) { + for(int j = i + 1; j < world.width() * world.height() && consecutives < 255; j++){ Tile nextTile = world.tile(j); if(nextTile.getFloorID() != tile.getFloorID() || nextTile.getWallID() != 0 || nextTile.elevation != tile.elevation){ break; } - consecutives ++; + consecutives++; } stream.writeByte(consecutives); @@ -107,12 +107,14 @@ public class NetworkIO { } } - }catch (IOException e){ + }catch(IOException e){ throw new RuntimeException(e); } } - /**Return whether a custom map is expected, and thus whether the client should wait for additional data.*/ + /** + * Return whether a custom map is expected, and thus whether the client should wait for additional data. + */ public static void loadWorld(InputStream is){ Player player = players[0]; @@ -132,7 +134,7 @@ public class NetworkIO { ObjectMap tags = new ObjectMap<>(); byte tagSize = stream.readByte(); - for (int i = 0; i < tagSize; i++) { + for(int i = 0; i < tagSize; i++){ String key = stream.readUTF(); String value = stream.readUTF(); tags.put(key, value); @@ -169,8 +171,8 @@ public class NetworkIO { Tile[][] tiles = world.createTiles(width, height); - for (int i = 0; i < width * height; i++) { - int x = i % width, y = i /width; + for(int i = 0; i < width * height; i++){ + int x = i % width, y = i / width; byte floorid = stream.readByte(); byte wallid = stream.readByte(); byte elevation = stream.readByte(); @@ -178,9 +180,9 @@ public class NetworkIO { Tile tile = new Tile(x, y, floorid, wallid); tile.elevation = elevation; - if (wallid == Blocks.blockpart.id) { + if(wallid == Blocks.blockpart.id){ tile.link = stream.readByte(); - }else if (tile.entity != null) { + }else if(tile.entity != null){ byte tr = stream.readByte(); short health = stream.readShort(); @@ -191,16 +193,16 @@ public class NetworkIO { tile.entity.health = health; tile.setRotation(rotation); - if (tile.entity.items != null) tile.entity.items.read(stream); - if (tile.entity.power != null) tile.entity.power.read(stream); - if (tile.entity.liquids != null) tile.entity.liquids.read(stream); - if (tile.entity.cons != null) tile.entity.cons.read(stream); + if(tile.entity.items != null) tile.entity.items.read(stream); + if(tile.entity.power != null) tile.entity.power.read(stream); + if(tile.entity.liquids != null) tile.entity.liquids.read(stream); + if(tile.entity.cons != null) tile.entity.cons.read(stream); tile.entity.read(stream); }else if(wallid == 0){ int consecutives = stream.readUnsignedByte(); - for (int j = i + 1; j < i + 1 + consecutives; j++) { + for(int j = i + 1; j < i + 1 + consecutives; j++){ int newx = j % width, newy = j / width; Tile newTile = new Tile(newx, newy, floorid, wallid); newTile.elevation = elevation; @@ -217,13 +219,13 @@ public class NetworkIO { state.teams = new TeamInfo(); byte teams = stream.readByte(); - for (int i = 0; i < teams; i++) { + for(int i = 0; i < teams; i++){ Team team = Team.all[stream.readByte()]; boolean ally = stream.readBoolean(); short cores = stream.readShort(); state.teams.add(team, ally); - for (int j = 0; j < cores; j++) { + for(int j = 0; j < cores; j++){ state.teams.get(team).cores.add(world.tile(stream.readInt())); } @@ -234,7 +236,7 @@ public class NetworkIO { world.endMapLoad(); - }catch (IOException e){ + }catch(IOException e){ throw new RuntimeException(e); } } @@ -250,10 +252,10 @@ public class NetworkIO { ByteBuffer buffer = ByteBuffer.allocate(128); - buffer.put((byte)host.getBytes().length); + buffer.put((byte) host.getBytes().length); buffer.put(host.getBytes()); - buffer.put((byte)map.getBytes().length); + buffer.put((byte) map.getBytes().length); buffer.put(map.getBytes()); buffer.putInt(playerGroup.size()); diff --git a/core/src/io/anuke/mindustry/net/Packet.java b/core/src/io/anuke/mindustry/net/Packet.java index 91f9b3a7de..ef34666dbb 100644 --- a/core/src/io/anuke/mindustry/net/Packet.java +++ b/core/src/io/anuke/mindustry/net/Packet.java @@ -5,10 +5,14 @@ import com.badlogic.gdx.utils.Pool.Poolable; import java.nio.ByteBuffer; public interface Packet extends Poolable{ - default void read(ByteBuffer buffer){} - default void write(ByteBuffer buffer){} + default void read(ByteBuffer buffer){ + } - default void reset() {} + default void write(ByteBuffer buffer){ + } + + default void reset(){ + } default boolean isImportant(){ return false; diff --git a/core/src/io/anuke/mindustry/net/Packets.java b/core/src/io/anuke/mindustry/net/Packets.java index 7ba866677f..bcadd4c5cc 100644 --- a/core/src/io/anuke/mindustry/net/Packets.java +++ b/core/src/io/anuke/mindustry/net/Packets.java @@ -16,15 +16,34 @@ import java.nio.ByteBuffer; import static io.anuke.mindustry.Vars.world; -/**Class for storing all packets.*/ -public class Packets { +/** + * Class for storing all packets. + */ +public class Packets{ + + public enum KickReason{ + kick, invalidPassword, clientOutdated, serverOutdated, banned, gameover(true), recentKick, nameInUse, idInUse, fastShoot, nameEmpty, customClient; + public final boolean quiet; + + KickReason(){ + quiet = false; + } + + KickReason(boolean quiet){ + this.quiet = quiet; + } + } + + public enum AdminAction{ + kick, ban, trace, wave + } public static class Connect implements Packet{ public int id; public String addressTCP; @Override - public boolean isImportant() { + public boolean isImportant(){ return true; } } @@ -33,7 +52,7 @@ public class Packets { public int id; @Override - public boolean isImportant() { + public boolean isImportant(){ return true; } } @@ -49,17 +68,17 @@ public class Packets { public int color; @Override - public void write(ByteBuffer buffer) { + public void write(ByteBuffer buffer){ buffer.putInt(Version.build); IOUtils.writeString(buffer, name); IOUtils.writeString(buffer, usid); - buffer.put(mobile ? (byte)1 : 0); + buffer.put(mobile ? (byte) 1 : 0); buffer.putInt(color); buffer.put(Base64Coder.decode(uuid)); } @Override - public void read(ByteBuffer buffer) { + public void read(ByteBuffer buffer){ version = buffer.getInt(); name = IOUtils.readString(buffer); usid = IOUtils.readString(buffer); @@ -78,7 +97,7 @@ public class Packets { public int writeLength; @Override - public void read(ByteBuffer buffer) { + public void read(ByteBuffer buffer){ type = buffer.get(); priority = buffer.get(); writeLength = buffer.getShort(); @@ -88,29 +107,29 @@ public class Packets { } @Override - public void write(ByteBuffer buffer) { + public void write(ByteBuffer buffer){ buffer.put(type); buffer.put(priority); - buffer.putShort((short)writeLength); + buffer.putShort((short) writeLength); writeBuffer.position(0); - for(int i = 0; i < writeLength; i ++){ + for(int i = 0; i < writeLength; i++){ buffer.put(writeBuffer.get()); } } @Override - public void reset() { + public void reset(){ priority = 0; } @Override - public boolean isImportant() { + public boolean isImportant(){ return priority == 1; } @Override - public boolean isUnimportant() { + public boolean isUnimportant(){ return priority == 2; } } @@ -127,7 +146,7 @@ public class Packets { public BuildRequest currentRequest; @Override - public void write(ByteBuffer buffer) { + public void write(ByteBuffer buffer){ Player player = Vars.players[0]; buffer.putInt(lastSnapshot); @@ -138,33 +157,33 @@ public class Packets { buffer.putFloat(player.y); buffer.putFloat(player.pointerX); buffer.putFloat(player.pointerY); - buffer.put(player.isBoosting ? (byte)1 : 0); - buffer.put(player.isShooting ? (byte)1 : 0); + buffer.put(player.isBoosting ? (byte) 1 : 0); + buffer.put(player.isShooting ? (byte) 1 : 0); - buffer.put((byte)(Mathf.clamp(player.getVelocity().x, -Unit.maxAbsVelocity, Unit.maxAbsVelocity) * Unit.velocityPercision)); - buffer.put((byte)(Mathf.clamp(player.getVelocity().y, -Unit.maxAbsVelocity, Unit.maxAbsVelocity) * Unit.velocityPercision)); + buffer.put((byte) (Mathf.clamp(player.getVelocity().x, -Unit.maxAbsVelocity, Unit.maxAbsVelocity) * Unit.velocityPercision)); + buffer.put((byte) (Mathf.clamp(player.getVelocity().y, -Unit.maxAbsVelocity, Unit.maxAbsVelocity) * Unit.velocityPercision)); //saving 4 bytes, yay? - buffer.putShort((short)(player.rotation*2)); - buffer.putShort((short)(player.baseRotation*2)); + buffer.putShort((short) (player.rotation * 2)); + buffer.putShort((short) (player.baseRotation * 2)); buffer.putInt(player.getMineTile() == null ? -1 : player.getMineTile().packedPosition()); BuildRequest request = player.getCurrentRequest(); if(request != null){ - buffer.put(request.remove ? (byte)1 : 0); + buffer.put(request.remove ? (byte) 1 : 0); buffer.putInt(world.toPacked(request.x, request.y)); if(!request.remove){ - buffer.put((byte)request.recipe.id); - buffer.put((byte)request.rotation); + buffer.put((byte) request.recipe.id); + buffer.put((byte) request.rotation); } }else{ - buffer.put((byte)-1); + buffer.put((byte) -1); } } @Override - public void read(ByteBuffer buffer) { + public void read(ByteBuffer buffer){ lastSnapshot = buffer.getInt(); snapid = buffer.getInt(); timeSent = buffer.getLong(); @@ -177,17 +196,17 @@ public class Packets { shooting = buffer.get() == 1; xv = buffer.get() / Unit.velocityPercision; yv = buffer.get() / Unit.velocityPercision; - rotation = buffer.getShort()/2f; - baseRotation = buffer.getShort()/2f; + rotation = buffer.getShort() / 2f; + baseRotation = buffer.getShort() / 2f; mining = world.tile(buffer.getInt()); byte type = buffer.get(); - if (type != -1) { + if(type != -1){ int position = buffer.getInt(); - if (type == 1) { //remove + if(type == 1){ //remove currentRequest = new BuildRequest(position % world.width(), position / world.width()); - } else { //place + }else{ //place byte recipe = buffer.get(); byte rotation = buffer.get(); currentRequest = new BuildRequest(position % world.width(), position / world.width(), rotation, Recipe.getByID(recipe)); @@ -198,41 +217,28 @@ public class Packets { } } - public enum KickReason{ - kick, invalidPassword, clientOutdated, serverOutdated, banned, gameover(true), recentKick, nameInUse, idInUse, fastShoot, nameEmpty, customClient; - public final boolean quiet; - - KickReason(){ quiet = false; } - - KickReason(boolean quiet){ - this.quiet = quiet; - } - } - - public enum AdminAction{ - kick, ban, trace, wave - } - - /**Marks the beginning of a stream.*/ + /** + * Marks the beginning of a stream. + */ public static class StreamBegin implements Packet{ private static int lastid; - public int id = lastid ++; + public int id = lastid++; public int total; public Class type; @Override - public void write(ByteBuffer buffer) { + public void write(ByteBuffer buffer){ buffer.putInt(id); buffer.putInt(total); buffer.put(Registrator.getID(type)); } @Override - public void read(ByteBuffer buffer) { + public void read(ByteBuffer buffer){ id = buffer.getInt(); total = buffer.getInt(); - type = (Class)Registrator.getByID(buffer.get()); + type = (Class) Registrator.getByID(buffer.get()); } } @@ -241,14 +247,14 @@ public class Packets { public byte[] data; @Override - public void write(ByteBuffer buffer) { + public void write(ByteBuffer buffer){ buffer.putInt(id); - buffer.putShort((short)data.length); + buffer.putShort((short) data.length); buffer.put(data); } @Override - public void read(ByteBuffer buffer) { + public void read(ByteBuffer buffer){ id = buffer.getInt(); data = new byte[buffer.getShort()]; buffer.get(data); diff --git a/core/src/io/anuke/mindustry/net/Registrator.java b/core/src/io/anuke/mindustry/net/Registrator.java index f35a991d50..6dbabdcc15 100644 --- a/core/src/io/anuke/mindustry/net/Registrator.java +++ b/core/src/io/anuke/mindustry/net/Registrator.java @@ -3,25 +3,24 @@ package io.anuke.mindustry.net; import com.badlogic.gdx.utils.ObjectIntMap; import com.badlogic.gdx.utils.reflect.ClassReflection; import io.anuke.mindustry.net.Packets.*; -import io.anuke.mindustry.net.Packets.StreamBegin; -import io.anuke.mindustry.net.Packets.StreamChunk; -public class Registrator { +public class Registrator{ private static Class[] classes = { - StreamBegin.class, - StreamChunk.class, - WorldStream.class, - ConnectPacket.class, - ClientSnapshotPacket.class, - InvokePacket.class + StreamBegin.class, + StreamChunk.class, + WorldStream.class, + ConnectPacket.class, + ClientSnapshotPacket.class, + InvokePacket.class }; private static ObjectIntMap> ids = new ObjectIntMap<>(); static{ if(classes.length > 127) throw new RuntimeException("Can't have more than 127 registered classes!"); - for(int i = 0; i < classes.length; i ++){ + for(int i = 0; i < classes.length; i++){ if(!ClassReflection.isAssignableFrom(Packet.class, classes[i]) && - !ClassReflection.isAssignableFrom(Streamable.class, classes[i])) throw new RuntimeException("Not a packet: " + classes[i]); + !ClassReflection.isAssignableFrom(Streamable.class, classes[i])) + throw new RuntimeException("Not a packet: " + classes[i]); ids.put(classes[i], i); } } @@ -31,7 +30,7 @@ public class Registrator { } public static byte getID(Class type){ - return (byte)ids.get(type, -1); + return (byte) ids.get(type, -1); } public static Class[] getClasses(){ diff --git a/core/src/io/anuke/mindustry/net/Streamable.java b/core/src/io/anuke/mindustry/net/Streamable.java index 5815fdd845..a27ea42ced 100644 --- a/core/src/io/anuke/mindustry/net/Streamable.java +++ b/core/src/io/anuke/mindustry/net/Streamable.java @@ -11,6 +11,11 @@ import java.io.IOException; public class Streamable implements Packet{ public transient ByteArrayInputStream stream; + @Override + public boolean isImportant(){ + return true; + } + public static class StreamBuilder{ public final int id; public final Class type; @@ -25,15 +30,15 @@ public class Streamable implements Packet{ } public void add(byte[] bytes){ - try { + try{ stream.write(bytes); - }catch (IOException e){ + }catch(IOException e){ throw new RuntimeException(e); } } public Streamable build(){ - try { + try{ Streamable s = ClassReflection.newInstance(type); s.stream = new ByteArrayInputStream(stream.toByteArray()); return s; @@ -46,9 +51,4 @@ public class Streamable implements Packet{ return stream.size() >= total; } } - - @Override - public boolean isImportant() { - return true; - } } diff --git a/core/src/io/anuke/mindustry/net/TraceInfo.java b/core/src/io/anuke/mindustry/net/TraceInfo.java index 996363e1a7..512c8e85ff 100644 --- a/core/src/io/anuke/mindustry/net/TraceInfo.java +++ b/core/src/io/anuke/mindustry/net/TraceInfo.java @@ -1,10 +1,10 @@ package io.anuke.mindustry.net; import com.badlogic.gdx.utils.IntIntMap; -import io.anuke.mindustry.world.Block; import io.anuke.mindustry.content.blocks.Blocks; +import io.anuke.mindustry.world.Block; -public class TraceInfo { +public class TraceInfo{ public int playerid; public String ip; public boolean modclient; diff --git a/core/src/io/anuke/mindustry/net/ValidateException.java b/core/src/io/anuke/mindustry/net/ValidateException.java index 35fe5d6114..89923702de 100644 --- a/core/src/io/anuke/mindustry/net/ValidateException.java +++ b/core/src/io/anuke/mindustry/net/ValidateException.java @@ -2,11 +2,13 @@ package io.anuke.mindustry.net; import io.anuke.mindustry.entities.Player; -/**Thrown when a client sends invalid information.*/ +/** + * Thrown when a client sends invalid information. + */ public class ValidateException extends RuntimeException{ public final Player player; - public ValidateException(Player player, String s) { + public ValidateException(Player player, String s){ super(s); this.player = player; } diff --git a/core/src/io/anuke/mindustry/type/AmmoEntry.java b/core/src/io/anuke/mindustry/type/AmmoEntry.java index fc14db1cce..a4e0559df1 100644 --- a/core/src/io/anuke/mindustry/type/AmmoEntry.java +++ b/core/src/io/anuke/mindustry/type/AmmoEntry.java @@ -1,11 +1,13 @@ package io.anuke.mindustry.type; -/**Used to store ammo amounts in units and turrets.*/ +/** + * Used to store ammo amounts in units and turrets. + */ public class AmmoEntry{ public AmmoType type; public int amount; - public AmmoEntry(AmmoType type, int amount) { + public AmmoEntry(AmmoType type, int amount){ this.type = type; this.amount = amount; } diff --git a/core/src/io/anuke/mindustry/type/AmmoType.java b/core/src/io/anuke/mindustry/type/AmmoType.java index 88ad721a9e..90a5eb0601 100644 --- a/core/src/io/anuke/mindustry/type/AmmoType.java +++ b/core/src/io/anuke/mindustry/type/AmmoType.java @@ -11,32 +11,52 @@ public class AmmoType implements Content{ private static Array allTypes = new Array<>(32); public final byte id; - /**The item used. Always null if liquid isn't.*/ + /** + * The item used. Always null if liquid isn't. + */ public final Item item; - /**The liquid used. Always null if item isn't.*/ + /** + * The liquid used. Always null if item isn't. + */ public final Liquid liquid; - /**The resulting bullet. Never null.*/ + /** + * The resulting bullet. Never null. + */ public final BulletType bullet; - /**For item ammo, this is amount given per ammo item. - * For liquid ammo, this is amount used per shot.*/ + /** + * For item ammo, this is amount given per ammo item. + * For liquid ammo, this is amount used per shot. + */ public final float quantityMultiplier; - /**Reload speed multiplier.*/ + /** + * Reload speed multiplier. + */ public float reloadMultiplier = 1f; - /**Bullet recoil strength.*/ + /** + * Bullet recoil strength. + */ public float recoil = 0f; - /**Additional inaccuracy in degrees.*/ + /** + * Additional inaccuracy in degrees. + */ public float inaccuracy; - /**Effect created when shooting.*/ + /** + * Effect created when shooting. + */ public Effect shootEffect = Fx.none; - /**Extra smoke effect created when shooting.*/ + /** + * Extra smoke effect created when shooting. + */ public Effect smokeEffect = Fx.none; { - this.id = (byte)(lastID++); + this.id = (byte) (lastID++); allTypes.add(this); } - /**Creates an AmmoType with no liquid or item. Used for power-based ammo.*/ + /** + * Creates an AmmoType with no liquid or item. Used for power-based ammo. + */ public AmmoType(BulletType result){ this.item = null; this.liquid = null; @@ -45,7 +65,9 @@ public class AmmoType implements Content{ this.reloadMultiplier = 1f; } - /**Creates an AmmoType with an item.*/ + /** + * Creates an AmmoType with an item. + */ public AmmoType(Item item, BulletType result, float multiplier){ this.item = item; this.liquid = null; @@ -53,7 +75,9 @@ public class AmmoType implements Content{ this.quantityMultiplier = multiplier; } - /**Creates an AmmoType with a liquid.*/ + /** + * Creates an AmmoType with a liquid. + */ public AmmoType(Liquid liquid, BulletType result, float multiplier){ this.item = null; this.liquid = liquid; @@ -61,26 +85,28 @@ public class AmmoType implements Content{ this.quantityMultiplier = multiplier; } - /**Returns maximum distance the bullet this ammo type has can travel.*/ - public float getRange(){ - return bullet.speed * bullet.lifetime; - } - - @Override - public String getContentTypeName() { - return "ammotype"; - } - - @Override - public Array getAll() { - return allTypes; - } - - public static Array all() { + public static Array all(){ return allTypes; } public static AmmoType getByID(int id){ return allTypes.get(id); } + + /** + * Returns maximum distance the bullet this ammo type has can travel. + */ + public float getRange(){ + return bullet.speed * bullet.lifetime; + } + + @Override + public String getContentTypeName(){ + return "ammotype"; + } + + @Override + public Array getAll(){ + return allTypes; + } } diff --git a/core/src/io/anuke/mindustry/type/Category.java b/core/src/io/anuke/mindustry/type/Category.java index 58ccdb9015..6d75054b2f 100644 --- a/core/src/io/anuke/mindustry/type/Category.java +++ b/core/src/io/anuke/mindustry/type/Category.java @@ -1,5 +1,5 @@ package io.anuke.mindustry.type; -public enum Category { - weapon, production, distribution, liquid, power, defense, crafting, units +public enum Category{ + weapon, production, distribution, liquid, power, defense, crafting, units } diff --git a/core/src/io/anuke/mindustry/type/ContentList.java b/core/src/io/anuke/mindustry/type/ContentList.java index dc288f21ef..edeb482dca 100644 --- a/core/src/io/anuke/mindustry/type/ContentList.java +++ b/core/src/io/anuke/mindustry/type/ContentList.java @@ -3,11 +3,17 @@ package io.anuke.mindustry.type; import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.game.Content; -/**Interface for a list of content to be loaded in {@link io.anuke.mindustry.core.ContentLoader}.*/ -public interface ContentList { - /**This method should create all the content.*/ +/** + * Interface for a list of content to be loaded in {@link io.anuke.mindustry.core.ContentLoader}. + */ +public interface ContentList{ + /** + * This method should create all the content. + */ void load(); - /**This method should return the list of the content of this type, for further loading.*/ + /** + * This method should return the list of the content of this type, for further loading. + */ Array getAll(); } diff --git a/core/src/io/anuke/mindustry/type/Item.java b/core/src/io/anuke/mindustry/type/Item.java index 31c66b51ba..18653372c6 100644 --- a/core/src/io/anuke/mindustry/type/Item.java +++ b/core/src/io/anuke/mindustry/type/Item.java @@ -15,95 +15,111 @@ import io.anuke.ucore.util.Strings; import io.anuke.ucore.util.ThreadArray; public class Item implements Comparable, UnlockableContent{ - private static final ThreadArray items = new ThreadArray<>(); + private static final ThreadArray items = new ThreadArray<>(); - public final int id; - public final String name; - public final String description; - public final Color color; - public TextureRegion region; + public final int id; + public final String name; + public final String description; + public final Color color; + public TextureRegion region; - /**type of the item; used for tabs and core acceptance. default value is {@link ItemType#resource}.*/ - public ItemType type = ItemType.resource; - /**how explosive this item is.*/ - public float explosiveness = 0f; - /**flammability above 0.3 makes this eleigible for item burners.*/ - public float flammability = 0f; - /**how radioactive this item is. 0=none, 1=chernobyl ground zero*/ - public float radioactivity; - /**how effective this item is as flux for smelting. 0 = not a flux, 0.5 = normal flux, 1 = very good*/ - public float fluxiness = 0f; - /**drill hardness of the item*/ - public int hardness = 0; - /**the burning color of this item*/ - public Color flameColor = Palette.darkFlame.cpy(); - /**base material cost of this item, used for calculating place times - * 1 cost = 1 tick added to build time*/ - public float cost = 3f; + /** + * type of the item; used for tabs and core acceptance. default value is {@link ItemType#resource}. + */ + public ItemType type = ItemType.resource; + /** + * how explosive this item is. + */ + public float explosiveness = 0f; + /** + * flammability above 0.3 makes this eleigible for item burners. + */ + public float flammability = 0f; + /** + * how radioactive this item is. 0=none, 1=chernobyl ground zero + */ + public float radioactivity; + /** + * how effective this item is as flux for smelting. 0 = not a flux, 0.5 = normal flux, 1 = very good + */ + public float fluxiness = 0f; + /** + * drill hardness of the item + */ + public int hardness = 0; + /** + * the burning color of this item + */ + public Color flameColor = Palette.darkFlame.cpy(); + /** + * base material cost of this item, used for calculating place times + * 1 cost = 1 tick added to build time + */ + public float cost = 3f; - public Item(String name, Color color) { - this.id = items.size; - this.name = name; - this.color = color; - this.description = Bundles.getOrNull("item." + this.name + ".description"); + public Item(String name, Color color){ + this.id = items.size; + this.name = name; + this.color = color; + this.description = Bundles.getOrNull("item." + this.name + ".description"); - items.add(this); + items.add(this); - if(!Bundles.has("item." + this.name + ".name")){ + if(!Bundles.has("item." + this.name + ".name")){ Log.err("Warning: item '" + name + "' is missing a localized name. Add the follow to bundle.properties:"); Log.err("item." + this.name + ".name=" + Strings.capitalize(name.replace('-', '_'))); } - } + } - public void load(){ - this.region = Draw.region("item-" + name); - } + public static Array all(){ + return Item.items; + } - @Override - public void displayInfo(Table table) { - ContentDisplay.displayItem(table, this); - } + public static Item getByID(int id){ + return items.get(id); + } - @Override - public String localizedName(){ - return Bundles.get("item." + this.name + ".name"); - } + public void load(){ + this.region = Draw.region("item-" + name); + } - @Override - public TextureRegion getContentIcon() { - return region; - } + @Override + public void displayInfo(Table table){ + ContentDisplay.displayItem(table, this); + } - @Override - public String toString() { - return localizedName(); - } + @Override + public String localizedName(){ + return Bundles.get("item." + this.name + ".name"); + } - @Override - public int compareTo(Item item) { - return Integer.compare(id, item.id); - } + @Override + public TextureRegion getContentIcon(){ + return region; + } - @Override - public String getContentName() { - return name; - } + @Override + public String toString(){ + return localizedName(); + } - @Override - public String getContentTypeName() { - return "item"; - } + @Override + public int compareTo(Item item){ + return Integer.compare(id, item.id); + } - @Override - public Array getAll() { - return all(); - } + @Override + public String getContentName(){ + return name; + } - public static Array all() { - return Item.items; - } + @Override + public String getContentTypeName(){ + return "item"; + } - public static Item getByID(int id){ - return items.get(id); - } + @Override + public Array getAll(){ + return all(); + } } diff --git a/core/src/io/anuke/mindustry/type/ItemStack.java b/core/src/io/anuke/mindustry/type/ItemStack.java index 6ab73ca5af..5714050602 100644 --- a/core/src/io/anuke/mindustry/type/ItemStack.java +++ b/core/src/io/anuke/mindustry/type/ItemStack.java @@ -1,15 +1,15 @@ package io.anuke.mindustry.type; public class ItemStack{ - public io.anuke.mindustry.type.Item item; - public int amount; - - public ItemStack(io.anuke.mindustry.type.Item item, int amount){ - this.item = item; - this.amount = amount; - } + public io.anuke.mindustry.type.Item item; + public int amount; - public boolean equals(ItemStack other){ - return other != null && other.item == item && other.amount == amount; - } + public ItemStack(io.anuke.mindustry.type.Item item, int amount){ + this.item = item; + this.amount = amount; + } + + public boolean equals(ItemStack other){ + return other != null && other.item == item && other.amount == amount; + } } diff --git a/core/src/io/anuke/mindustry/type/ItemType.java b/core/src/io/anuke/mindustry/type/ItemType.java index 5a80183522..fb676443bb 100644 --- a/core/src/io/anuke/mindustry/type/ItemType.java +++ b/core/src/io/anuke/mindustry/type/ItemType.java @@ -1,10 +1,16 @@ package io.anuke.mindustry.type; -public enum ItemType { - /**Not used for anything besides crafting inside blocks.*/ +public enum ItemType{ + /** + * Not used for anything besides crafting inside blocks. + */ resource, - /**Can be used for constructing blocks. Only materials are accepted into the core.*/ + /** + * Can be used for constructing blocks. Only materials are accepted into the core. + */ material, - /**Only used as ammo for turrets.*/ + /** + * Only used as ammo for turrets. + */ ammo } diff --git a/core/src/io/anuke/mindustry/type/Liquid.java b/core/src/io/anuke/mindustry/type/Liquid.java index 4672c529d4..20410304c1 100644 --- a/core/src/io/anuke/mindustry/type/Liquid.java +++ b/core/src/io/anuke/mindustry/type/Liquid.java @@ -13,87 +13,105 @@ import io.anuke.ucore.util.Bundles; import io.anuke.ucore.util.ThreadArray; public class Liquid implements UnlockableContent{ - private static final Array liquids = new ThreadArray<>(); + private static final Array liquids = new ThreadArray<>(); - public final Color color; - public final String name; - public final String description; - public final int id; + public final Color color; + public final String name; + public final String description; + public final int id; - /**0-1, 0 is completely inflammable, anything above that may catch fire when exposed to heat, 0.5+ is very flammable.*/ - public float flammability; - /**temperature: 0.5 is 'room' temperature, 0 is very cold, 1 is molten hot*/ - public float temperature = 0.5f; - /**how much heat this liquid can store. 0.75=water (high), anything lower is probably less dense and bad at cooling.*/ - public float heatCapacity = 0.5f; - /**how thick this liquid is. 0.5=water (relatively viscous), 1 would be something like tar (very slow)*/ - public float viscosity = 0.5f; - /**how prone to exploding this liquid is, when heated. 0 = nothing, 1 = nuke*/ - public float explosiveness; - /**the burning color of this liquid*/ - public Color flameColor = Color.valueOf("ffb763"); - /**The associated status effect.*/ - public StatusEffect effect = StatusEffects.none; - /**Pump tier. Controls which pumps can use this liquid.*/ - public int tier; - /**Displayed icon.*/ - public TextureRegion iconRegion; - - public Liquid(String name, Color color) { - this.name = name; - this.color = new Color(color); + /** + * 0-1, 0 is completely inflammable, anything above that may catch fire when exposed to heat, 0.5+ is very flammable. + */ + public float flammability; + /** + * temperature: 0.5 is 'room' temperature, 0 is very cold, 1 is molten hot + */ + public float temperature = 0.5f; + /** + * how much heat this liquid can store. 0.75=water (high), anything lower is probably less dense and bad at cooling. + */ + public float heatCapacity = 0.5f; + /** + * how thick this liquid is. 0.5=water (relatively viscous), 1 would be something like tar (very slow) + */ + public float viscosity = 0.5f; + /** + * how prone to exploding this liquid is, when heated. 0 = nothing, 1 = nuke + */ + public float explosiveness; + /** + * the burning color of this liquid + */ + public Color flameColor = Color.valueOf("ffb763"); + /** + * The associated status effect. + */ + public StatusEffect effect = StatusEffects.none; + /** + * Pump tier. Controls which pumps can use this liquid. + */ + public int tier; + /** + * Displayed icon. + */ + public TextureRegion iconRegion; - this.id = liquids.size; - this.description = Bundles.getOrNull("liquid." + name + ".description"); + public Liquid(String name, Color color){ + this.name = name; + this.color = new Color(color); - Liquid.liquids.add(this); - } + this.id = liquids.size; + this.description = Bundles.getOrNull("liquid." + name + ".description"); - @Override - public void load() { - iconRegion = Draw.region("liquid-icon-" + name); - } + Liquid.liquids.add(this); + } - @Override - public void displayInfo(Table table) { - ContentDisplay.displayLiquid(table, this); - } + public static Array all(){ + return Liquid.liquids; + } - @Override - public String localizedName(){ - return Bundles.get("liquid."+ this.name + ".name"); - } + public static Liquid getByID(int id){ + return liquids.get(id); + } - @Override - public TextureRegion getContentIcon() { - return iconRegion; - } + @Override + public void load(){ + iconRegion = Draw.region("liquid-icon-" + name); + } - @Override - public String toString(){ - return localizedName(); - } + @Override + public void displayInfo(Table table){ + ContentDisplay.displayLiquid(table, this); + } - @Override - public String getContentName() { - return name; - } + @Override + public String localizedName(){ + return Bundles.get("liquid." + this.name + ".name"); + } - @Override - public String getContentTypeName() { - return "liquid"; - } + @Override + public TextureRegion getContentIcon(){ + return iconRegion; + } - @Override - public Array getAll() { - return all(); - } + @Override + public String toString(){ + return localizedName(); + } - public static Array all() { - return Liquid.liquids; - } + @Override + public String getContentName(){ + return name; + } - public static Liquid getByID(int id){ - return liquids.get(id); - } + @Override + public String getContentTypeName(){ + return "liquid"; + } + + @Override + public Array getAll(){ + return all(); + } } diff --git a/core/src/io/anuke/mindustry/type/Mech.java b/core/src/io/anuke/mindustry/type/Mech.java index c2397535ff..98640fe292 100644 --- a/core/src/io/anuke/mindustry/type/Mech.java +++ b/core/src/io/anuke/mindustry/type/Mech.java @@ -10,64 +10,64 @@ import io.anuke.ucore.scene.ui.layout.Table; //TODO merge unit type with mech public class Mech extends Upgrade implements UnlockableContent{ - public boolean flying; + public boolean flying; - public float speed = 1.1f; - public float maxSpeed = 1.1f; - public float boostSpeed = 0.75f; - public float drag = 0.4f; - public float mass = 1f; - public float armor = 1f; + public float speed = 1.1f; + public float maxSpeed = 1.1f; + public float boostSpeed = 0.75f; + public float drag = 0.4f; + public float mass = 1f; + public float armor = 1f; - public float mineSpeed = 1f; - public int drillPower = -1; - public float carryWeight = 10f; - public float buildPower = 1f; - public boolean canRepair = false; - public Color trailColor = Color.valueOf("ffd37f"); + public float mineSpeed = 1f; + public int drillPower = -1; + public float carryWeight = 10f; + public float buildPower = 1f; + public boolean canRepair = false; + public Color trailColor = Color.valueOf("ffd37f"); - public float weaponOffsetX, weaponOffsetY; + public float weaponOffsetX, weaponOffsetY; - public Weapon weapon = Weapons.blaster; + public Weapon weapon = Weapons.blaster; - public int itemCapacity = 30; - public int ammoCapacity = 100; + public int itemCapacity = 30; + public int ammoCapacity = 100; - public TextureRegion baseRegion, legRegion, region, iconRegion; + public TextureRegion baseRegion, legRegion, region, iconRegion; - public Mech(String name, boolean flying){ - super(name); - this.flying = flying; - } - - @Override - public void displayInfo(Table table) { - ContentDisplay.displayMech(table, this); - } - - @Override - public TextureRegion getContentIcon() { - return iconRegion; - } + public Mech(String name, boolean flying){ + super(name); + this.flying = flying; + } @Override - public String getContentName() { + public void displayInfo(Table table){ + ContentDisplay.displayMech(table, this); + } + + @Override + public TextureRegion getContentIcon(){ + return iconRegion; + } + + @Override + public String getContentName(){ return name; } @Override - public String getContentTypeName() { + public String getContentTypeName(){ return "mech"; } - @Override - public void load() { - if (!flying){ - legRegion = Draw.region(name + "-leg"); - baseRegion = Draw.region(name + "-base"); - } + @Override + public void load(){ + if(!flying){ + legRegion = Draw.region(name + "-leg"); + baseRegion = Draw.region(name + "-base"); + } - region = Draw.region(name); - iconRegion = Draw.region("mech-icon-"+ name); - } + region = Draw.region(name); + iconRegion = Draw.region("mech-icon-" + name); + } } diff --git a/core/src/io/anuke/mindustry/type/Recipe.java b/core/src/io/anuke/mindustry/type/Recipe.java index ccfba98f21..36b5e4bca6 100644 --- a/core/src/io/anuke/mindustry/type/Recipe.java +++ b/core/src/io/anuke/mindustry/type/Recipe.java @@ -19,9 +19,7 @@ import io.anuke.ucore.util.Strings; import java.util.Arrays; -import static io.anuke.mindustry.Vars.control; -import static io.anuke.mindustry.Vars.debug; -import static io.anuke.mindustry.Vars.headless; +import static io.anuke.mindustry.Vars.*; public class Recipe implements UnlockableContent{ private static int lastid; @@ -40,7 +38,7 @@ public class Recipe implements UnlockableContent{ private Recipe[] recipeDependencies; public Recipe(Category category, Block result, ItemStack... requirements){ - this.id = lastid ++; + this.id = lastid++; this.result = result; this.requirements = requirements; this.category = category; @@ -58,96 +56,10 @@ public class Recipe implements UnlockableContent{ recipeMap.put(result, this); } - public Recipe setDependencies(Block... blocks){ - this.dependencies = blocks; - return this; - } - - public Recipe setDesktop(){ - desktopOnly = true; - return this; - } - - public Recipe setDebug(){ - debugOnly = true; - return this; - } - - @Override - public boolean isHidden() { - return debugOnly; - } - - @Override - public void displayInfo(Table table) { - ContentDisplay.displayRecipe(table, this); - } - - @Override - public String localizedName() { - return result.formalName; - } - - @Override - public TextureRegion getContentIcon() { - return result.getEditorIcon(); - } - - @Override - public void init() { - if(!Bundles.has("block." + result.name + ".name")) { - Log.err("WARNING: Recipe block '{0}' does not have a formal name defined. Add the following to bundle.properties:", result.name); - Log.err("block.{0}.name={1}", result.name, Strings.capitalize(result.name.replace('-', '_'))); - }/*else if(result.fullDescription == null){ - Log.err("WARNING: Recipe block '{0}' does not have a description defined.", result.name); - }*/ - } - - @Override - public String getContentName() { - return result.name; - } - - @Override - public String getContentTypeName() { - return "recipe"; - } - - @Override - public void onUnlock() { - for(OrderedMap map : result.stats.toMap().values()){ - for(StatValue value : map.values()){ - if(value instanceof ContentStatValue){ - ContentStatValue stat = (ContentStatValue)value; - UnlockableContent[] content = stat.getValueContent(); - for(UnlockableContent c : content){ - control.database().unlockContent(c); - } - } - } - } - } - - @Override - public UnlockableContent[] getDependencies() { - if(dependencies == null){ - return null; - }else if(recipeDependencies == null){ - recipeDependencies = new Recipe[dependencies.length]; - for (int i = 0; i < recipeDependencies.length; i++) { - recipeDependencies[i] = Recipe.getByResult(dependencies[i]); - } - } - return recipeDependencies; - } - - @Override - public Array getAll() { - return allRecipes; - } - - /**Returns unlocked recipes in a category. - * Do not call on the server backend, as unlocking does not exist!*/ + /** + * Returns unlocked recipes in a category. + * Do not call on the server backend, as unlocking does not exist! + */ public static void getUnlockedByCategory(Category category, Array r){ if(headless){ throw new RuntimeException("Not enabled on the headless backend!"); @@ -155,17 +67,19 @@ public class Recipe implements UnlockableContent{ r.clear(); for(Recipe recipe : allRecipes){ - if(recipe.category == category && (Vars.control.database().isUnlocked(recipe) || (debug && recipe.debugOnly))) { + if(recipe.category == category && (Vars.control.database().isUnlocked(recipe) || (debug && recipe.debugOnly))){ r.add(recipe); } } } - /**Returns all recipes in a category.*/ + /** + * Returns all recipes in a category. + */ public static void getByCategory(Category category, Array r){ r.clear(); for(Recipe recipe : allRecipes){ - if(recipe.category == category) { + if(recipe.category == category){ r.add(recipe); } } @@ -186,4 +100,92 @@ public class Recipe implements UnlockableContent{ return allRecipes.get(id); } } + + public Recipe setDesktop(){ + desktopOnly = true; + return this; + } + + public Recipe setDebug(){ + debugOnly = true; + return this; + } + + @Override + public boolean isHidden(){ + return debugOnly; + } + + @Override + public void displayInfo(Table table){ + ContentDisplay.displayRecipe(table, this); + } + + @Override + public String localizedName(){ + return result.formalName; + } + + @Override + public TextureRegion getContentIcon(){ + return result.getEditorIcon(); + } + + @Override + public void init(){ + if(!Bundles.has("block." + result.name + ".name")){ + Log.err("WARNING: Recipe block '{0}' does not have a formal name defined. Add the following to bundle.properties:", result.name); + Log.err("block.{0}.name={1}", result.name, Strings.capitalize(result.name.replace('-', '_'))); + }/*else if(result.fullDescription == null){ + Log.err("WARNING: Recipe block '{0}' does not have a description defined.", result.name); + }*/ + } + + @Override + public String getContentName(){ + return result.name; + } + + @Override + public String getContentTypeName(){ + return "recipe"; + } + + @Override + public void onUnlock(){ + for(OrderedMap map : result.stats.toMap().values()){ + for(StatValue value : map.values()){ + if(value instanceof ContentStatValue){ + ContentStatValue stat = (ContentStatValue) value; + UnlockableContent[] content = stat.getValueContent(); + for(UnlockableContent c : content){ + control.database().unlockContent(c); + } + } + } + } + } + + @Override + public UnlockableContent[] getDependencies(){ + if(dependencies == null){ + return null; + }else if(recipeDependencies == null){ + recipeDependencies = new Recipe[dependencies.length]; + for(int i = 0; i < recipeDependencies.length; i++){ + recipeDependencies[i] = Recipe.getByResult(dependencies[i]); + } + } + return recipeDependencies; + } + + public Recipe setDependencies(Block... blocks){ + this.dependencies = blocks; + return this; + } + + @Override + public Array getAll(){ + return allRecipes; + } } diff --git a/core/src/io/anuke/mindustry/type/StatusEffect.java b/core/src/io/anuke/mindustry/type/StatusEffect.java index 17a04881de..fa9bcab529 100644 --- a/core/src/io/anuke/mindustry/type/StatusEffect.java +++ b/core/src/io/anuke/mindustry/type/StatusEffect.java @@ -7,75 +7,90 @@ import io.anuke.mindustry.entities.Unit; import io.anuke.mindustry.game.Content; public class StatusEffect implements Content{ - private static final Array array = new Array<>(); - private static int lastid; + private static final Array array = new Array<>(); + private static int lastid; - /**Duration of this status effect in ticks at maximum power.*/ - public final float baseDuration; - public final int id; + /** + * Duration of this status effect in ticks at maximum power. + */ + public final float baseDuration; + public final int id; - public float damageMultiplier = 1f; //damage dealt - public float armorMultiplier = 1f; //armor points - public float speedMultiplier = 1f; //speed + public float damageMultiplier = 1f; //damage dealt + public float armorMultiplier = 1f; //armor points + public float speedMultiplier = 1f; //speed - /**Set of 'opposite' effects, which will decrease the duration of this effect when applied.*/ - protected ObjectSet opposites = new ObjectSet<>(); - /**The strength of time decrease when met with an opposite effect, as a fraction of the other's duration.*/ - protected float oppositeScale = 0.5f; + /** + * Set of 'opposite' effects, which will decrease the duration of this effect when applied. + */ + protected ObjectSet opposites = new ObjectSet<>(); + /** + * The strength of time decrease when met with an opposite effect, as a fraction of the other's duration. + */ + protected float oppositeScale = 0.5f; - public StatusEffect(float baseDuration){ - this.baseDuration = baseDuration; + public StatusEffect(float baseDuration){ + this.baseDuration = baseDuration; - id = lastid++; - array.add(this); - } + id = lastid++; + array.add(this); + } - /**Runs every tick on the affected unit while time is greater than 0.*/ - public void update(Unit unit, float time){} + public static StatusEffect getByID(int id){ + return array.get(id); + } - /**Called when transitioning between two status effects. - * @param to The state to transition to - * @param time The current status effect time - * @param newTime The time that the new status effect will last*/ - public StatusEntry getTransition(Unit unit, StatusEffect to, float time, float newTime, StatusEntry result){ - if(opposites.contains(to)){ - time -= newTime*oppositeScale; - if(time > 0) { - return result.set(this, time); - } - } + public static Array all(){ + return array; + } - return result.set(to, newTime); - } + /** + * Runs every tick on the affected unit while time is greater than 0. + */ + public void update(Unit unit, float time){ + } - /**Called when this effect transitions to a new status effect.*/ - public void onTransition(Unit unit, StatusEffect to){} + /** + * Called when transitioning between two status effects. + * + * @param to The state to transition to + * @param time The current status effect time + * @param newTime The time that the new status effect will last + */ + public StatusEntry getTransition(Unit unit, StatusEffect to, float time, float newTime, StatusEntry result){ + if(opposites.contains(to)){ + time -= newTime * oppositeScale; + if(time > 0){ + return result.set(this, time); + } + } - public boolean isOpposite(StatusEffect other){ - return opposites.size > 0 && opposites.contains(other); - } + return result.set(to, newTime); + } - public void setOpposites(StatusEffect... effects){ - for(StatusEffect e : effects){ - opposites.add(e); - } - } + /** + * Called when this effect transitions to a new status effect. + */ + public void onTransition(Unit unit, StatusEffect to){ + } - @Override - public String getContentTypeName() { - return "statuseffect"; - } + public boolean isOpposite(StatusEffect other){ + return opposites.size > 0 && opposites.contains(other); + } - @Override - public Array getAll() { - return null; - } + public void setOpposites(StatusEffect... effects){ + for(StatusEffect e : effects){ + opposites.add(e); + } + } - public static StatusEffect getByID(int id){ - return array.get(id); - } + @Override + public String getContentTypeName(){ + return "statuseffect"; + } - public static Array all(){ - return array; - } + @Override + public Array getAll(){ + return null; + } } diff --git a/core/src/io/anuke/mindustry/type/Upgrade.java b/core/src/io/anuke/mindustry/type/Upgrade.java index 192e6ced1c..49157843ec 100644 --- a/core/src/io/anuke/mindustry/type/Upgrade.java +++ b/core/src/io/anuke/mindustry/type/Upgrade.java @@ -15,13 +15,29 @@ public abstract class Upgrade implements Content{ public final String description; public Upgrade(String name){ - this.id = lastid ++; + this.id = lastid++; this.name = name; - this.description = Bundles.get("upgrade."+name+".description"); + this.description = Bundles.get("upgrade." + name + ".description"); upgrades.add(this); } + public static void forEach(Consumer type, Predicate pred){ + for(Upgrade u : upgrades){ + if(pred.test(u)){ + type.accept((T) u); + } + } + } + + public static Array all(){ + return upgrades; + } + + public static T getByID(byte id){ + return (T) upgrades.get(id); + } + public String localizedName(){ return Bundles.get("upgrade." + name + ".name"); } @@ -32,23 +48,7 @@ public abstract class Upgrade implements Content{ } @Override - public Array getAll() { + public Array getAll(){ return all(); } - - public static void forEach(Consumer type, Predicate pred){ - for(Upgrade u : upgrades){ - if(pred.test(u)){ - type.accept((T)u); - } - } - } - - public static Array all() { - return upgrades; - } - - public static T getByID(byte id){ - return (T)upgrades.get(id); - } } diff --git a/core/src/io/anuke/mindustry/type/Weapon.java b/core/src/io/anuke/mindustry/type/Weapon.java index cfb8f8eeb1..a5d3610048 100644 --- a/core/src/io/anuke/mindustry/type/Weapon.java +++ b/core/src/io/anuke/mindustry/type/Weapon.java @@ -19,164 +19,191 @@ import io.anuke.ucore.util.Angles; import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Translator; -public class Weapon extends Upgrade { - /**minimum cursor distance from player, fixes 'cross-eyed' shooting.*/ - protected static float minPlayerDist = 20f; - /**ammo type map. set with setAmmo()*/ - protected OrderedMap ammoMap = new OrderedMap<>(); - /**shell ejection effect*/ - protected Effect ejectEffect = Fx.none; - /**weapon reload in frames*/ - protected float reload; - /**amount of shots per fire*/ - protected int shots = 1; - /**spacing in degrees between multiple shots, if applicable*/ - protected float spacing = 12f; - /**inaccuracy of degrees of each shot*/ - protected float inaccuracy = 0f; - /**intensity and duration of each shot's screen shake*/ - protected float shake = 0f; - /**visual weapon knockback.*/ - protected float recoil = 1.5f; - /**shoot barrel y offset*/ - protected float length = 3f; - /**shoot barrel x offset.*/ - protected float width = 4f; - /**fraction of velocity that is random*/ - protected float velocityRnd = 0f; - /**whether to shoot the weapons in different arms one after another, rather than all at once*/ - protected boolean roundrobin = false; - /**translator for vector calulations*/ - protected Translator tr = new Translator(); +public class Weapon extends Upgrade{ + /** + * minimum cursor distance from player, fixes 'cross-eyed' shooting. + */ + protected static float minPlayerDist = 20f; + public TextureRegion equipRegion, region; + /** + * ammo type map. set with setAmmo() + */ + protected OrderedMap ammoMap = new OrderedMap<>(); + /** + * shell ejection effect + */ + protected Effect ejectEffect = Fx.none; + /** + * weapon reload in frames + */ + protected float reload; + /** + * amount of shots per fire + */ + protected int shots = 1; + /** + * spacing in degrees between multiple shots, if applicable + */ + protected float spacing = 12f; + /** + * inaccuracy of degrees of each shot + */ + protected float inaccuracy = 0f; + /** + * intensity and duration of each shot's screen shake + */ + protected float shake = 0f; + /** + * visual weapon knockback. + */ + protected float recoil = 1.5f; + /** + * shoot barrel y offset + */ + protected float length = 3f; + /** + * shoot barrel x offset. + */ + protected float width = 4f; + /** + * fraction of velocity that is random + */ + protected float velocityRnd = 0f; + /** + * whether to shoot the weapons in different arms one after another, rather than all at once + */ + protected boolean roundrobin = false; + /** + * translator for vector calulations + */ + protected Translator tr = new Translator(); - public TextureRegion equipRegion, region; + protected Weapon(String name){ + super(name); + } - protected Weapon(String name){ - super(name); - } + @Remote(targets = Loc.server, called = Loc.both, in = In.entities, unreliable = true) + public static void onPlayerShootWeapon(Player player, float x, float y, float rotation, boolean left){ + if(player == null) return; + //clients do not see their own shoot events: they are simulated completely clientside to prevent laggy visuals + //messing with the firerate or any other stats does not affect the server (take that, script kiddies!) + if(Net.client() && player == Vars.players[0]){ + return; + } - @Override - public void load() { - equipRegion = Draw.region(name + "-equip"); - region = Draw.region(name); - } + shootDirect(player, x, y, rotation, left); + } - @Override - public String getContentTypeName() { - return "weapon"; - } + @Remote(targets = Loc.server, called = Loc.both, in = In.entities, unreliable = true) + public static void onGenericShootWeapon(ShooterTrait shooter, float x, float y, float rotation, boolean left){ + if(shooter == null) return; + shootDirect(shooter, x, y, rotation, left); + } - public void update(ShooterTrait shooter, float pointerX, float pointerY){ + public static void shootDirect(ShooterTrait shooter, float x, float y, float rotation, boolean left){ + Weapon weapon = shooter.getWeapon(); + + Angles.shotgun(weapon.shots, weapon.spacing, rotation, f -> weapon.bullet(shooter, x, y, f + Mathf.range(weapon.inaccuracy))); + + AmmoType type = shooter.getInventory().getAmmo(); + + if(type == null) return; + + weapon.tr.trns(rotation + 180f, type.recoil); + + shooter.getVelocity().add(weapon.tr); + + weapon.tr.trns(rotation, 3f); + + Effects.shake(weapon.shake, weapon.shake, x, y); + Effects.effect(weapon.ejectEffect, x, y, rotation * -Mathf.sign(left)); + Effects.effect(type.shootEffect, x + weapon.tr.x, y + weapon.tr.y, rotation, shooter); + Effects.effect(type.smokeEffect, x + weapon.tr.x, y + weapon.tr.y, rotation, shooter); + + //reset timer for remote players + shooter.getTimer().get(shooter.getShootTimer(left), weapon.reload); + } + + @Override + public void load(){ + equipRegion = Draw.region(name + "-equip"); + region = Draw.region(name); + } + + @Override + public String getContentTypeName(){ + return "weapon"; + } + + public void update(ShooterTrait shooter, float pointerX, float pointerY){ update(shooter, true, pointerX, pointerY); update(shooter, false, pointerX, pointerY); } - private void update(ShooterTrait shooter, boolean left, float pointerX, float pointerY){ - if(shooter.getInventory().hasAmmo() && shooter.getTimer().get(shooter.getShootTimer(left), reload)){ - if(roundrobin){ - shooter.getTimer().reset(shooter.getShootTimer(!left), reload/2f); - } + private void update(ShooterTrait shooter, boolean left, float pointerX, float pointerY){ + if(shooter.getInventory().hasAmmo() && shooter.getTimer().get(shooter.getShootTimer(left), reload)){ + if(roundrobin){ + shooter.getTimer().reset(shooter.getShootTimer(!left), reload / 2f); + } - tr.set(pointerX, pointerY).sub(shooter.getX(), shooter.getY()); - if(tr.len() < minPlayerDist) tr.setLength(minPlayerDist); + tr.set(pointerX, pointerY).sub(shooter.getX(), shooter.getY()); + if(tr.len() < minPlayerDist) tr.setLength(minPlayerDist); - float cx = tr.x + shooter.getX(), cy = tr.y + shooter.getY(); + float cx = tr.x + shooter.getX(), cy = tr.y + shooter.getY(); - float ang = tr.angle(); - tr.trns(ang - 90, width * Mathf.sign(left), length); + float ang = tr.angle(); + tr.trns(ang - 90, width * Mathf.sign(left), length); - shoot(shooter, shooter.getX() + tr.x, shooter.getY() + tr.y, Angles.angle(shooter.getX() + tr.x, shooter.getY() + tr.y, cx, cy), left); - } - } + shoot(shooter, shooter.getX() + tr.x, shooter.getY() + tr.y, Angles.angle(shooter.getX() + tr.x, shooter.getY() + tr.y, cx, cy), left); + } + } - public float getRecoil(ShooterTrait player, boolean left){ - return (1f-Mathf.clamp(player.getTimer().getTime(player.getShootTimer(left))/reload))*recoil; - } + public float getRecoil(ShooterTrait player, boolean left){ + return (1f - Mathf.clamp(player.getTimer().getTime(player.getShootTimer(left)) / reload)) * recoil; + } - public float getRecoil() { - return recoil; - } + public float getRecoil(){ + return recoil; + } - public float getReload(){ - return reload; - } + public float getReload(){ + return reload; + } - public void shoot(ShooterTrait p, float x, float y, float angle, boolean left){ - if(Net.client()){ - //call it directly, don't invoke on server - shootDirect(p, x, y, angle, left); - }else{ - if(p instanceof Player){ //players need special weapon handling logic - CallEntity.onPlayerShootWeapon((Player)p, x, y, angle, left); + public void shoot(ShooterTrait p, float x, float y, float angle, boolean left){ + if(Net.client()){ + //call it directly, don't invoke on server + shootDirect(p, x, y, angle, left); + }else{ + if(p instanceof Player){ //players need special weapon handling logic + CallEntity.onPlayerShootWeapon((Player) p, x, y, angle, left); }else{ CallEntity.onGenericShootWeapon(p, x, y, angle, left); } - } + } - p.getInventory().useAmmo(); - } - - public Iterable getAcceptedItems(){ - return ammoMap.orderedKeys(); - } - - public AmmoType getAmmoType(Item item){ - return ammoMap.get(item); - } - - protected void setAmmo(AmmoType... types){ - for(AmmoType type : types){ - ammoMap.put(type.item, type); - } - } - - void bullet(ShooterTrait owner, float x, float y, float angle){ - if(owner == null || !owner.getInventory().hasAmmo()) return; - - tr.trns(angle, 3f); - Bullet.create(owner.getInventory().getAmmo().bullet, - owner, owner.getTeam(), x + tr.x, y + tr.y, angle, (1f-velocityRnd) + Mathf.random(velocityRnd)); - } - - @Remote(targets = Loc.server, called = Loc.both, in = In.entities, unreliable = true) - public static void onPlayerShootWeapon(Player player, float x, float y, float rotation, boolean left){ - if(player == null) return; - //clients do not see their own shoot events: they are simulated completely clientside to prevent laggy visuals - //messing with the firerate or any other stats does not affect the server (take that, script kiddies!) - if(Net.client() && player == Vars.players[0]){ - return; - } - - shootDirect(player, x, y, rotation, left); - } - - @Remote(targets = Loc.server, called = Loc.both, in = In.entities, unreliable = true) - public static void onGenericShootWeapon(ShooterTrait shooter, float x, float y, float rotation, boolean left){ - if(shooter == null) return; - shootDirect(shooter, x, y, rotation, left); + p.getInventory().useAmmo(); } - public static void shootDirect(ShooterTrait shooter, float x, float y, float rotation, boolean left){ - Weapon weapon = shooter.getWeapon(); + public Iterable getAcceptedItems(){ + return ammoMap.orderedKeys(); + } - Angles.shotgun(weapon.shots, weapon.spacing, rotation, f -> weapon.bullet(shooter, x, y, f + Mathf.range(weapon.inaccuracy))); + public AmmoType getAmmoType(Item item){ + return ammoMap.get(item); + } - AmmoType type = shooter.getInventory().getAmmo(); + protected void setAmmo(AmmoType... types){ + for(AmmoType type : types){ + ammoMap.put(type.item, type); + } + } - if(type == null) return; + void bullet(ShooterTrait owner, float x, float y, float angle){ + if(owner == null || !owner.getInventory().hasAmmo()) return; - weapon.tr.trns(rotation + 180f, type.recoil); - - shooter.getVelocity().add(weapon.tr); - - weapon.tr.trns(rotation, 3f); - - Effects.shake(weapon.shake, weapon.shake, x, y); - Effects.effect(weapon.ejectEffect, x, y, rotation * -Mathf.sign(left)); - Effects.effect(type.shootEffect, x + weapon.tr.x, y + weapon.tr.y, rotation, shooter); - Effects.effect(type.smokeEffect, x + weapon.tr.x, y + weapon.tr.y, rotation, shooter); - - //reset timer for remote players - shooter.getTimer().get(shooter.getShootTimer(left), weapon.reload); - } + tr.trns(angle, 3f); + Bullet.create(owner.getInventory().getAmmo().bullet, + owner, owner.getTeam(), x + tr.x, y + tr.y, angle, (1f - velocityRnd) + Mathf.random(velocityRnd)); + } } diff --git a/core/src/io/anuke/mindustry/type/WeatherEvent.java b/core/src/io/anuke/mindustry/type/WeatherEvent.java index 24577af6b9..66871cc439 100644 --- a/core/src/io/anuke/mindustry/type/WeatherEvent.java +++ b/core/src/io/anuke/mindustry/type/WeatherEvent.java @@ -12,22 +12,12 @@ public class WeatherEvent implements Content{ public final String name; public WeatherEvent(String name){ - this.id = lastid ++; + this.id = lastid++; this.name = name; all.add(this); } - @Override - public String getContentTypeName() { - return "weatherevent"; - } - - @Override - public Array getAll() { - return all(); - } - public static Array all(){ return all; } @@ -35,4 +25,14 @@ public class WeatherEvent implements Content{ public static WeatherEvent getByID(int id){ return all.get(id); } + + @Override + public String getContentTypeName(){ + return "weatherevent"; + } + + @Override + public Array getAll(){ + return all(); + } } diff --git a/core/src/io/anuke/mindustry/ui/BorderImage.java b/core/src/io/anuke/mindustry/ui/BorderImage.java index ab6e1c6b86..bc9ed30002 100644 --- a/core/src/io/anuke/mindustry/ui/BorderImage.java +++ b/core/src/io/anuke/mindustry/ui/BorderImage.java @@ -10,34 +10,35 @@ import io.anuke.ucore.scene.ui.Image; import io.anuke.ucore.scene.ui.layout.Unit; public class BorderImage extends Image{ - private float thickness = 3f; - - public BorderImage(){} - - public BorderImage(Texture texture){ - super(texture); - } - - public BorderImage(Texture texture, float thick){ - super(texture); - thickness = thick; - } + private float thickness = 3f; - public BorderImage(TextureRegion region, float thick){ - super(region); - thickness = thick; - } - - @Override - public void draw(Batch batch, float alpha){ - super.draw(batch, alpha); - - float scaleX = getScaleX(); - float scaleY = getScaleY(); - - Draw.color(Palette.accent); - Lines.stroke(Unit.dp.scl(thickness)); - Lines.rect(x + imageX, y + imageY, imageWidth * scaleX, imageHeight * scaleY); - Draw.reset(); - } + public BorderImage(){ + } + + public BorderImage(Texture texture){ + super(texture); + } + + public BorderImage(Texture texture, float thick){ + super(texture); + thickness = thick; + } + + public BorderImage(TextureRegion region, float thick){ + super(region); + thickness = thick; + } + + @Override + public void draw(Batch batch, float alpha){ + super.draw(batch, alpha); + + float scaleX = getScaleX(); + float scaleY = getScaleY(); + + Draw.color(Palette.accent); + Lines.stroke(Unit.dp.scl(thickness)); + Lines.rect(x + imageX, y + imageY, imageWidth * scaleX, imageHeight * scaleY); + Draw.reset(); + } } diff --git a/core/src/io/anuke/mindustry/ui/ContentDisplay.java b/core/src/io/anuke/mindustry/ui/ContentDisplay.java index 916654b314..181e5704f1 100644 --- a/core/src/io/anuke/mindustry/ui/ContentDisplay.java +++ b/core/src/io/anuke/mindustry/ui/ContentDisplay.java @@ -18,16 +18,16 @@ import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.util.Bundles; -public class ContentDisplay { +public class ContentDisplay{ public static void displayRecipe(Table table, Recipe recipe){ Block block = recipe.result; table.table(title -> { - int size = 8*6; + int size = 8 * 6; if(block instanceof Turret){ - size = (8 * block.size + 2) * (7 - block.size*2); + size = (8 * block.size + 2) * (7 - block.size * 2); } title.addImage(Draw.region("block-icon-" + block.name)).size(size); @@ -58,7 +58,7 @@ public class ContentDisplay { table.add("$text.category." + cat.name()).color(Palette.accent).fillX(); table.row(); - for (BlockStat stat : map.keys()){ + for(BlockStat stat : map.keys()){ table.table(inset -> { inset.left(); inset.add("[LIGHT_GRAY]" + stat.localized() + ":[] "); @@ -92,13 +92,13 @@ public class ContentDisplay { table.left().defaults().fillX(); - table.add(Bundles.format("text.item.explosiveness", (int)(item.explosiveness * 100))); + table.add(Bundles.format("text.item.explosiveness", (int) (item.explosiveness * 100))); table.row(); - table.add(Bundles.format("text.item.flammability", (int)(item.flammability * 100))); + table.add(Bundles.format("text.item.flammability", (int) (item.flammability * 100))); table.row(); - table.add(Bundles.format("text.item.radioactivity", (int)(item.radioactivity * 100))); + table.add(Bundles.format("text.item.radioactivity", (int) (item.radioactivity * 100))); table.row(); - table.add(Bundles.format("text.item.fluxiness", (int)(item.fluxiness * 100))); + table.add(Bundles.format("text.item.fluxiness", (int) (item.fluxiness * 100))); table.row(); table.add(Bundles.format("text.item.hardness", item.hardness)); table.row(); @@ -127,15 +127,15 @@ public class ContentDisplay { table.left().defaults().fillX(); - table.add(Bundles.format("text.item.explosiveness", (int)(liquid.explosiveness * 100))); + table.add(Bundles.format("text.item.explosiveness", (int) (liquid.explosiveness * 100))); table.row(); - table.add(Bundles.format("text.item.flammability", (int)(liquid.flammability * 100))); + table.add(Bundles.format("text.item.flammability", (int) (liquid.flammability * 100))); table.row(); - table.add(Bundles.format("text.liquid.heatcapacity", (int)(liquid.heatCapacity * 100))); + table.add(Bundles.format("text.liquid.heatcapacity", (int) (liquid.heatCapacity * 100))); table.row(); - table.add(Bundles.format("text.liquid.temperature", (int)(liquid.temperature * 100))); + table.add(Bundles.format("text.liquid.temperature", (int) (liquid.temperature * 100))); table.row(); - table.add(Bundles.format("text.liquid.viscosity", (int)(liquid.viscosity * 100))); + table.add(Bundles.format("text.liquid.viscosity", (int) (liquid.viscosity * 100))); table.row(); } diff --git a/core/src/io/anuke/mindustry/ui/GridImage.java b/core/src/io/anuke/mindustry/ui/GridImage.java index 13d2c175b0..01792f5fbb 100644 --- a/core/src/io/anuke/mindustry/ui/GridImage.java +++ b/core/src/io/anuke/mindustry/ui/GridImage.java @@ -2,41 +2,40 @@ package io.anuke.mindustry.ui; import com.badlogic.gdx.graphics.g2d.Batch; import com.badlogic.gdx.graphics.g2d.TextureRegion; - import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.scene.Element; public class GridImage extends Element{ - private int imageWidth, imageHeight; - - public GridImage(int w, int h){ - this.imageWidth = w; - this.imageHeight = h; - } + private int imageWidth, imageHeight; - public void draw(Batch batch, float alpha){ - TextureRegion blank = Draw.region("white"); - - float xspace = (getWidth() / imageWidth); - float yspace = (getHeight() / imageHeight); - float s = 1f; + public GridImage(int w, int h){ + this.imageWidth = w; + this.imageHeight = h; + } - int minspace = 10; + public void draw(Batch batch, float alpha){ + TextureRegion blank = Draw.region("white"); - int jumpx = (int)(Math.max(minspace, xspace) / xspace); - int jumpy = (int)(Math.max(minspace, yspace)/ yspace); - - for(int x = 0; x <= imageWidth; x += jumpx){ - batch.draw(blank, (int)(getX() + xspace * x - s), getY() - s, 2, getHeight()+ (x == imageWidth ? 1: 0)); - } - - for(int y = 0; y <= imageHeight; y += jumpy){ - batch.draw(blank, getX() - s, (int)(getY() + y * yspace - s), getWidth(), 2); - } - } - - public void setImageSize(int w, int h){ - this.imageWidth = w; - this.imageHeight = h; - } + float xspace = (getWidth() / imageWidth); + float yspace = (getHeight() / imageHeight); + float s = 1f; + + int minspace = 10; + + int jumpx = (int) (Math.max(minspace, xspace) / xspace); + int jumpy = (int) (Math.max(minspace, yspace) / yspace); + + for(int x = 0; x <= imageWidth; x += jumpx){ + batch.draw(blank, (int) (getX() + xspace * x - s), getY() - s, 2, getHeight() + (x == imageWidth ? 1 : 0)); + } + + for(int y = 0; y <= imageHeight; y += jumpy){ + batch.draw(blank, getX() - s, (int) (getY() + y * yspace - s), getWidth(), 2); + } + } + + public void setImageSize(int w, int h){ + this.imageWidth = w; + this.imageHeight = h; + } } diff --git a/core/src/io/anuke/mindustry/ui/IntFormat.java b/core/src/io/anuke/mindustry/ui/IntFormat.java index ad753bd871..6c4431a4b0 100644 --- a/core/src/io/anuke/mindustry/ui/IntFormat.java +++ b/core/src/io/anuke/mindustry/ui/IntFormat.java @@ -2,13 +2,15 @@ package io.anuke.mindustry.ui; import io.anuke.ucore.util.Bundles; -/**A low-garbage way to format bundle strings.*/ -public class IntFormat { +/** + * A low-garbage way to format bundle strings. + */ +public class IntFormat{ private final StringBuilder builder = new StringBuilder(); private final String text; private int lastValue = Integer.MIN_VALUE; - public IntFormat(String text) { + public IntFormat(String text){ this.text = text; } diff --git a/core/src/io/anuke/mindustry/ui/ItemImage.java b/core/src/io/anuke/mindustry/ui/ItemImage.java index 0786016780..5dab85a67d 100644 --- a/core/src/io/anuke/mindustry/ui/ItemImage.java +++ b/core/src/io/anuke/mindustry/ui/ItemImage.java @@ -9,9 +9,9 @@ import io.anuke.ucore.scene.ui.layout.Stack; import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.scene.ui.layout.Unit; -public class ItemImage extends Stack { +public class ItemImage extends Stack{ - public ItemImage(TextureRegion region, Supplier text) { + public ItemImage(TextureRegion region, Supplier text){ Table t = new Table().left().bottom(); t.label(text).color(Color.DARK_GRAY).padBottom(-22).get().setFontScale(Unit.dp.scl(0.5f)); @@ -22,7 +22,7 @@ public class ItemImage extends Stack { add(t); } - public ItemImage(ItemStack stack) { + public ItemImage(ItemStack stack){ Table t = new Table().left().bottom(); t.add(stack.amount + "").color(Color.DARK_GRAY).padBottom(-22).get().setFontScale(Unit.dp.scl(0.5f)); diff --git a/core/src/io/anuke/mindustry/ui/Links.java b/core/src/io/anuke/mindustry/ui/Links.java index 517083b91f..09ebd501d8 100644 --- a/core/src/io/anuke/mindustry/ui/Links.java +++ b/core/src/io/anuke/mindustry/ui/Links.java @@ -3,18 +3,18 @@ package io.anuke.mindustry.ui; import com.badlogic.gdx.graphics.Color; import io.anuke.ucore.util.Bundles; -public class Links { +public class Links{ private static LinkEntry[] links; private static void createLinks(){ links = new LinkEntry[]{ - new LinkEntry("discord", "https://discord.gg/BKADYds", Color.valueOf("7289da")), - new LinkEntry("trello", "https://trello.com/b/aE2tcUwF", Color.valueOf("026aa7")), - new LinkEntry("wiki", "http://mindustry.wikia.com/wiki/Mindustry_Wiki", Color.valueOf("0f142f")), - new LinkEntry("itch.io", "https://anuke.itch.io/mindustry", Color.valueOf("fa5c5c")), - new LinkEntry("google-play", "https://play.google.com/store/apps/details?id=io.anuke.mindustry", Color.valueOf("689f38")), - new LinkEntry("github", "https://github.com/Anuken/Mindustry/", Color.valueOf("24292e")), - new LinkEntry("dev-builds", "https://github.com/Anuken/Mindustry/wiki", Color.valueOf("fafbfc")) + new LinkEntry("discord", "https://discord.gg/BKADYds", Color.valueOf("7289da")), + new LinkEntry("trello", "https://trello.com/b/aE2tcUwF", Color.valueOf("026aa7")), + new LinkEntry("wiki", "http://mindustry.wikia.com/wiki/Mindustry_Wiki", Color.valueOf("0f142f")), + new LinkEntry("itch.io", "https://anuke.itch.io/mindustry", Color.valueOf("fa5c5c")), + new LinkEntry("google-play", "https://play.google.com/store/apps/details?id=io.anuke.mindustry", Color.valueOf("689f38")), + new LinkEntry("github", "https://github.com/Anuken/Mindustry/", Color.valueOf("24292e")), + new LinkEntry("dev-builds", "https://github.com/Anuken/Mindustry/wiki", Color.valueOf("fafbfc")) }; } @@ -30,10 +30,10 @@ public class Links { public final String name, description, link; public final Color color; - public LinkEntry(String name, String link, Color color) { + public LinkEntry(String name, String link, Color color){ this.name = name; this.color = color; - this.description = Bundles.getNotNull("text.link." + name +".description"); + this.description = Bundles.getNotNull("text.link." + name + ".description"); this.link = link; } } diff --git a/core/src/io/anuke/mindustry/ui/MenuButton.java b/core/src/io/anuke/mindustry/ui/MenuButton.java index 5bce02d2b1..ec3b273d39 100644 --- a/core/src/io/anuke/mindustry/ui/MenuButton.java +++ b/core/src/io/anuke/mindustry/ui/MenuButton.java @@ -7,32 +7,32 @@ import io.anuke.ucore.scene.ui.TextButton; public class MenuButton extends TextButton{ - public MenuButton(String icon, String text, Listenable clicked){ - this(icon, text, null, clicked); - } - - public MenuButton(String icon, String text, String description, Listenable clicked){ - super("default"); - float s = 66f; + public MenuButton(String icon, String text, Listenable clicked){ + this(icon, text, null, clicked); + } - clicked(clicked); + public MenuButton(String icon, String text, String description, Listenable clicked){ + super("default"); + float s = 66f; - clearChildren(); + clicked(clicked); - margin(0); + clearChildren(); - table(t -> { - t.addImage(icon).size(14*3); - t.update(() -> t.setBackground(getClickListener().isOver() || getClickListener().isVisualPressed() ? "button-over" : "button")); - }).size(s - 5, s); + margin(0); + + table(t -> { + t.addImage(icon).size(14 * 3); + t.update(() -> t.setBackground(getClickListener().isOver() || getClickListener().isVisualPressed() ? "button-over" : "button")); + }).size(s - 5, s); - table(t -> { - t.add(text).wrap().growX().get().setAlignment(Align.center, Align.left); - if(description != null){ - t.row(); - t.add(description).color(Color.LIGHT_GRAY); - } - }).padLeft(5).growX(); - } + table(t -> { + t.add(text).wrap().growX().get().setAlignment(Align.center, Align.left); + if(description != null){ + t.row(); + t.add(description).color(Color.LIGHT_GRAY); + } + }).padLeft(5).growX(); + } } diff --git a/core/src/io/anuke/mindustry/ui/Minimap.java b/core/src/io/anuke/mindustry/ui/Minimap.java index 9e469bac1f..1b0f563cf6 100644 --- a/core/src/io/anuke/mindustry/ui/Minimap.java +++ b/core/src/io/anuke/mindustry/ui/Minimap.java @@ -16,7 +16,7 @@ import io.anuke.ucore.scene.ui.layout.Table; import static io.anuke.mindustry.Vars.renderer; import static io.anuke.mindustry.Vars.showFog; -public class Minimap extends Table { +public class Minimap extends Table{ public Minimap(){ super("button"); @@ -26,17 +26,17 @@ public class Minimap extends Table { Image image = new Image(new TextureRegionDrawable(new TextureRegion())){ @Override - public void draw(Batch batch, float parentAlpha) { + public void draw(Batch batch, float parentAlpha){ if(renderer.minimap().getRegion() == null) return; - TextureRegionDrawable draw = (TextureRegionDrawable)getDrawable(); + TextureRegionDrawable draw = (TextureRegionDrawable) getDrawable(); draw.getRegion().setRegion(renderer.minimap().getRegion()); super.draw(batch, parentAlpha); if(renderer.minimap().getTexture() != null){ renderer.minimap().drawEntities(x, y, width, height); } - if(showFog) { + if(showFog){ renderer.fog().getTexture().setFilter(TextureFilter.Nearest, TextureFilter.Nearest); draw.getRegion().setTexture(renderer.fog().getTexture()); @@ -53,7 +53,7 @@ public class Minimap extends Table { }; addListener(new InputListener(){ - public boolean scrolled (InputEvent event, float x, float y, int amount) { + public boolean scrolled(InputEvent event, float x, float y, int amount){ renderer.minimap().zoomBy(amount); return true; } diff --git a/core/src/io/anuke/mindustry/ui/MobileButton.java b/core/src/io/anuke/mindustry/ui/MobileButton.java index c2d7585c80..dfbf1b161c 100644 --- a/core/src/io/anuke/mindustry/ui/MobileButton.java +++ b/core/src/io/anuke/mindustry/ui/MobileButton.java @@ -4,9 +4,9 @@ import com.badlogic.gdx.utils.Align; import io.anuke.ucore.function.Listenable; import io.anuke.ucore.scene.ui.ImageButton; -public class MobileButton extends ImageButton { +public class MobileButton extends ImageButton{ - public MobileButton(String icon, float isize, String text, Listenable listener) { + public MobileButton(String icon, float isize, String text, Listenable listener){ super(icon); resizeImage(isize); clicked(listener); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java index 027f595892..ed489a0630 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java @@ -16,7 +16,7 @@ import io.anuke.ucore.util.OS; import static io.anuke.mindustry.Vars.ios; import static io.anuke.mindustry.Vars.ui; -public class AboutDialog extends FloatingDialog { +public class AboutDialog extends FloatingDialog{ private static ObjectSet bannedItems = ObjectSet.with("google-play", "itch.io", "dev-builds", "trello"); public AboutDialog(){ @@ -51,21 +51,21 @@ public class AboutDialog extends FloatingDialog { table.table(i -> { i.background("button"); - i.addImage("icon-" + link.name).size(14*3f); - }).size(h-5, h); + i.addImage("icon-" + link.name).size(14 * 3f); + }).size(h - 5, h); table.table(inset -> { - inset.add("[accent]"+link.name.replace("-", " ")).growX().left(); + inset.add("[accent]" + link.name.replace("-", " ")).growX().left(); inset.row(); inset.labelWrap(link.description).width(w - 100f).color(Color.LIGHT_GRAY).growX(); }).padLeft(8); - table.addImageButton("icon-link", 14*3, () -> { + table.addImageButton("icon-link", 14 * 3, () -> { if(!Gdx.net.openURI(link.link)){ ui.showError("$text.linkfail"); Gdx.app.getClipboard().setContents(link.link); } - }).size(h-5, h); + }).size(h - 5, h); in.add(table).size(w, h).padTop(5).row(); } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/AdminsDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/AdminsDialog.java index c95577232f..dbfd1273f6 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/AdminsDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/AdminsDialog.java @@ -7,7 +7,7 @@ import io.anuke.ucore.scene.ui.layout.Table; import static io.anuke.mindustry.Vars.*; -public class AdminsDialog extends FloatingDialog { +public class AdminsDialog extends FloatingDialog{ public AdminsDialog(){ super("$text.server.admins"); @@ -40,7 +40,7 @@ public class AdminsDialog extends FloatingDialog { res.labelWrap("[LIGHT_GRAY]" + info.lastName).width(w - h - 24f); res.add().growX(); - res.addImageButton("icon-cancel", 14*3, () -> { + res.addImageButton("icon-cancel", 14 * 3, () -> { ui.showConfirm("$text.confirm", "$text.confirmunadmin", () -> { netServer.admins.unAdminPlayer(info.id); for(Player player : playerGroup.all()){ diff --git a/core/src/io/anuke/mindustry/ui/dialogs/BansDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/BansDialog.java index d8165c0ae6..012bbe6ee1 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/BansDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/BansDialog.java @@ -6,7 +6,7 @@ import io.anuke.ucore.scene.ui.layout.Table; import static io.anuke.mindustry.Vars.*; -public class BansDialog extends FloatingDialog { +public class BansDialog extends FloatingDialog{ public BansDialog(){ super("$text.server.bans"); @@ -40,7 +40,7 @@ public class BansDialog extends FloatingDialog { res.labelWrap("IP: [LIGHT_GRAY]" + info.lastIP + "\n[]Name: [LIGHT_GRAY]" + info.lastName).width(w - h - 24f); res.add().growX(); - res.addImageButton("icon-cancel", 14*3, () -> { + res.addImageButton("icon-cancel", 14 * 3, () -> { ui.showConfirm("$text.confirm", "$text.confirmunban", () -> { netServer.admins.unbanPlayerID(info.id); setup(); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/ChangelogDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/ChangelogDialog.java index b525117aa9..62c3aa646f 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/ChangelogDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/ChangelogDialog.java @@ -25,7 +25,7 @@ public class ChangelogDialog extends FloatingDialog{ content().add("$text.changelog.loading"); - if(!ios && !OS.isMac) { + if(!ios && !OS.isMac){ Changelogs.getChangelog(result -> { versions = result; Gdx.app.postRunnable(this::setup); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/ColorPickDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/ColorPickDialog.java index 8b8db3f845..5a06b32a73 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/ColorPickDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/ColorPickDialog.java @@ -22,7 +22,7 @@ public class ColorPickDialog extends Dialog{ Table table = new Table(); content().add(table); - for(int i = 0; i < playerColors.length; i ++){ + for(int i = 0; i < playerColors.length; i++){ Color color = playerColors[i]; ImageButton button = table.addImageButton("white", "toggle", 34, () -> { @@ -32,12 +32,12 @@ public class ColorPickDialog extends Dialog{ button.setChecked(players[0].color.equals(color)); button.getStyle().imageUpColor = color; - if(i%4 == 3){ + if(i % 4 == 3){ table.row(); } } - keyDown(key->{ + keyDown(key -> { if(key == Keys.ESCAPE || key == Keys.BACK) hide(); }); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/ContentInfoDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/ContentInfoDialog.java index 2e1a0973d9..fe791c4030 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/ContentInfoDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/ContentInfoDialog.java @@ -4,7 +4,7 @@ import io.anuke.mindustry.game.UnlockableContent; import io.anuke.ucore.scene.ui.ScrollPane; import io.anuke.ucore.scene.ui.layout.Table; -public class ContentInfoDialog extends FloatingDialog { +public class ContentInfoDialog extends FloatingDialog{ public ContentInfoDialog(){ super("$text.info.title"); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/ControlsDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/ControlsDialog.java index 987866200a..c9c2901a6b 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/ControlsDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/ControlsDialog.java @@ -7,24 +7,24 @@ import io.anuke.ucore.scene.ui.Image; import io.anuke.ucore.scene.ui.KeybindDialog; public class ControlsDialog extends KeybindDialog{ - - public ControlsDialog(){ - setDialog(); - - setFillParent(true); - title().setAlignment(Align.center); - getTitleTable().row(); - getTitleTable().add(new Image("white")) - .growX().height(3f).pad(4f).get().setColor(Palette.accent); - } - - @Override - public void addCloseButton(){ - buttons().addImageTextButton("$text.back", "icon-arrow-left", 30f, this::hide).size(230f, 64f); - - keyDown(key->{ - if(key == Keys.ESCAPE || key == Keys.BACK) - hide(); - }); - } + + public ControlsDialog(){ + setDialog(); + + setFillParent(true); + title().setAlignment(Align.center); + getTitleTable().row(); + getTitleTable().add(new Image("white")) + .growX().height(3f).pad(4f).get().setColor(Palette.accent); + } + + @Override + public void addCloseButton(){ + buttons().addImageTextButton("$text.back", "icon-arrow-left", 30f, this::hide).size(230f, 64f); + + keyDown(key -> { + if(key == Keys.ESCAPE || key == Keys.BACK) + hide(); + }); + } } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/DiscordDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/DiscordDialog.java index 19e889b863..e4571b2447 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/DiscordDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/DiscordDialog.java @@ -8,7 +8,7 @@ import io.anuke.ucore.scene.ui.Dialog; import static io.anuke.mindustry.Vars.discordURL; import static io.anuke.mindustry.Vars.ui; -public class DiscordDialog extends Dialog { +public class DiscordDialog extends Dialog{ public DiscordDialog(){ super("", "dialog"); @@ -39,10 +39,10 @@ public class DiscordDialog extends Dialog { buttons().defaults().size(170f, 50); buttons().addButton("$text.back", this::hide); - buttons().addButton("$text.copylink", () ->{ + buttons().addButton("$text.copylink", () -> { Gdx.app.getClipboard().setContents(discordURL); }); - buttons().addButton("$text.openlink", () ->{ + buttons().addButton("$text.openlink", () -> { if(!Gdx.net.openURI(discordURL)){ ui.showError("$text.linkfail"); Gdx.app.getClipboard().setContents(discordURL); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/FileChooser.java b/core/src/io/anuke/mindustry/ui/dialogs/FileChooser.java index 2e48a60898..c61ac8d4bd 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/FileChooser.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/FileChooser.java @@ -23,320 +23,319 @@ import java.util.Arrays; import static io.anuke.mindustry.Vars.gwt; -public class FileChooser extends FloatingDialog { - private Table files; - private FileHandle homeDirectory = gwt ? Gdx.files.internal("") : Gdx.files.absolute(OS.isMac ? OS.getProperty("user.home") + "/Downloads/" : +public class FileChooser extends FloatingDialog{ + public static Predicate pngFilter = file -> file.extension().equalsIgnoreCase("png"); + public static Predicate mapFilter = file -> file.extension().equalsIgnoreCase(Vars.mapExtension); + public static Predicate jpegFilter = file -> file.extension().equalsIgnoreCase("png") || file.extension().equalsIgnoreCase("jpg") || file.extension().equalsIgnoreCase("jpeg"); + public static Predicate defaultFilter = file -> true; + private Table files; + private FileHandle homeDirectory = gwt ? Gdx.files.internal("") : Gdx.files.absolute(OS.isMac ? OS.getProperty("user.home") + "/Downloads/" : Gdx.files.getExternalStoragePath()); - private FileHandle directory = homeDirectory; - private ScrollPane pane; - private TextField navigation, filefield; - private TextButton ok; - private FileHistory stack = new FileHistory(); - private Predicate filter; - private Consumer selectListener; - private boolean open; - - public FileChooser(String title, boolean open, Consumer result){ - this(title, defaultFilter, open, result); - } + private FileHandle directory = homeDirectory; + private ScrollPane pane; + private TextField navigation, filefield; + private TextButton ok; + private FileHistory stack = new FileHistory(); + private Predicate filter; + private Consumer selectListener; + private boolean open; - public FileChooser(String title, Predicate filter, boolean open, Consumer result){ - super(title); - this.open = open; - this.filter = filter; - this.selectListener = result; - } + public FileChooser(String title, boolean open, Consumer result){ + this(title, defaultFilter, open, result); + } - private void setupWidgets(){ - //getCell(content()).maxWidth(UIUtils.portrait() ? Gdx.graphics.getWidth() : Gdx.graphics.getWidth()/Unit.dp.scl(2f)); - content().margin(-10); - - Table content = new Table(); - - filefield = new TextField(); - filefield.setOnlyFontChars(false); - if(!open) Platform.instance.addDialog(filefield); - filefield.setDisabled(open); + public FileChooser(String title, Predicate filter, boolean open, Consumer result){ + super(title); + this.open = open; + this.filter = filter; + this.selectListener = result; + } - ok = new TextButton(open ? "$text.load" : "$text.save"); - - ok.clicked(() -> { - if(ok.isDisabled()) return; - if(selectListener != null) - selectListener.accept(directory.child(filefield.getText())); - hide(); - }); - - filefield.changed(() -> { - ok.setDisabled(filefield.getText().replace(" ", "").isEmpty()); - }); - - filefield.change(); - - TextButton cancel = new TextButton("$text.cancel"); - cancel.clicked(this::hide); + private void setupWidgets(){ + //getCell(content()).maxWidth(UIUtils.portrait() ? Gdx.graphics.getWidth() : Gdx.graphics.getWidth()/Unit.dp.scl(2f)); + content().margin(-10); - navigation = new TextField(""); - navigation.setTouchable(Touchable.disabled); + Table content = new Table(); - files = new Table(); - files.marginRight(10); - files.marginLeft(3); + filefield = new TextField(); + filefield.setOnlyFontChars(false); + if(!open) Platform.instance.addDialog(filefield); + filefield.setDisabled(open); - pane = new ScrollPane(files){ - public float getPrefHeight(){ - return Gdx.graphics.getHeight(); - } - }; - pane.setOverscroll(false, false); - pane.setFadeScrollBars(false); + ok = new TextButton(open ? "$text.load" : "$text.save"); - updateFiles(true); + ok.clicked(() -> { + if(ok.isDisabled()) return; + if(selectListener != null) + selectListener.accept(directory.child(filefield.getText())); + hide(); + }); - Table icontable = new Table(); - - float isize = 14*2; + filefield.changed(() -> { + ok.setDisabled(filefield.getText().replace(" ", "").isEmpty()); + }); - ImageButton up = new ImageButton("icon-folder-parent"); - up.resizeImage(isize); - up.clicked(()->{ - directory = directory.parent(); - updateFiles(true); - }); + filefield.change(); - //Macs are confined to the Downloads/ directory - if(OS.isMac){ - up.setDisabled(true); - } + TextButton cancel = new TextButton("$text.cancel"); + cancel.clicked(this::hide); - ImageButton back = new ImageButton("icon-arrow-left"); - back.resizeImage(isize); - - ImageButton forward = new ImageButton("icon-arrow-right"); - forward.resizeImage(isize); - - forward.clicked(()-> stack.forward()); - - back.clicked(()-> stack.back()); - - ImageButton home = new ImageButton("icon-home"); - home.resizeImage(isize); - home.clicked(()->{ - directory = homeDirectory; - updateFiles(true); - }); - - icontable.defaults().height(50).growX().uniform(); - icontable.add(home); - icontable.add(back); - icontable.add(forward); - icontable.add(up); - - Table fieldcontent = new Table(); - fieldcontent.bottom().left().add(new Label("File Name:")); - fieldcontent.add(filefield).height(40f).fillX().expandX().padLeft(10f); - - Table buttons = new Table(); - buttons.defaults().growX().height(50); - buttons.add(cancel); - buttons.add(ok); - - content.top().left(); - content.add(icontable).expandX().fillX(); - content.row(); + navigation = new TextField(""); + navigation.setTouchable(Touchable.disabled); - content.center().add(pane).width(UIUtils.portrait() ? Gdx.graphics.getWidth()/Unit.dp.scl(1) : Gdx.graphics.getWidth()/Unit.dp.scl(2)).colspan(3).grow(); - content.row(); - - if(!open){ - content.bottom().left().add(fieldcontent).colspan(3).grow().padTop(-2).padBottom(2); - content.row(); - } + files = new Table(); + files.marginRight(10); + files.marginLeft(3); - content.add(buttons).growX(); - - content().add(content); - } - - private void updateFileFieldStatus(){ - if(!open){ - ok.setDisabled(filefield.getText().replace(" ", "").isEmpty()); - }else{ - ok.setDisabled(!directory.child(filefield.getText()).exists() || directory.child(filefield.getText()).isDirectory()); - } - } + pane = new ScrollPane(files){ + public float getPrefHeight(){ + return Gdx.graphics.getHeight(); + } + }; + pane.setOverscroll(false, false); + pane.setFadeScrollBars(false); - private FileHandle[] getFileNames(){ - FileHandle[] handles = directory.list(file -> !file.getName().startsWith(".")); + updateFiles(true); - Arrays.sort(handles, (a, b) ->{ - if(a.isDirectory() && !b.isDirectory()) return -1; - if( !a.isDirectory() && b.isDirectory()) return 1; - return a.name().toUpperCase().compareTo(b.name().toUpperCase()); - }); - return handles; - } + Table icontable = new Table(); - private void updateFiles(boolean push){ - if(push) stack.push(directory); - //if is mac, don't display extra info since you can only ever go to downloads - navigation.setText(OS.isMac ? directory.name() : directory.toString()); - - GlyphLayout layout = Pools.obtain(GlyphLayout.class); - - layout.setText(Core.font, navigation.getText()); - - if(layout.width < navigation.getWidth()){ - navigation.setCursorPosition(0); - }else{ - navigation.setCursorPosition(navigation.getText().length()); - } - - Pools.free(layout); + float isize = 14 * 2; - files.clearChildren(); - files.top().left(); - FileHandle[] names = getFileNames(); + ImageButton up = new ImageButton("icon-folder-parent"); + up.resizeImage(isize); + up.clicked(() -> { + directory = directory.parent(); + updateFiles(true); + }); - //macs are confined to the Downloads/ directory - if(!OS.isMac) { - Image upimage = new Image("icon-folder-parent"); - TextButton upbutton = new TextButton(".." + directory.toString()); - upbutton.clicked(() -> { - directory = directory.parent(); - updateFiles(true); - }); + //Macs are confined to the Downloads/ directory + if(OS.isMac){ + up.setDisabled(true); + } - upbutton.left().add(upimage).padRight(4f).size(14 * 2); - upbutton.getLabel().setAlignment(Align.left); - upbutton.getCells().reverse(); + ImageButton back = new ImageButton("icon-arrow-left"); + back.resizeImage(isize); - files.add(upbutton).align(Align.topLeft).fillX().expandX().height(50).pad(2).colspan(2); - files.row(); - } - - ButtonGroup group = new ButtonGroup<>(); - group.setMinCheckCount(0); + ImageButton forward = new ImageButton("icon-arrow-right"); + forward.resizeImage(isize); - for(FileHandle file : names){ - if( !file.isDirectory() && !filter.test(file)) continue; //skip non-filtered files + forward.clicked(() -> stack.forward()); - String filename = file.name(); + back.clicked(() -> stack.back()); - TextButton button = new TextButton(shorten(filename), "toggle"); - group.add(button); - - button.clicked(()->{ - if( !file.isDirectory()){ - filefield.setText(filename); - updateFileFieldStatus(); - }else{ - directory = directory.child(filename); - updateFiles(true); - } - }); - - filefield.changed(()->{ - button.setChecked(filename.equals(filefield.getText())); - }); - - Image image = new Image(file.isDirectory() ? "icon-folder" : "icon-file-text"); - - button.add(image).padRight(4f).size(14*2f); - button.getCells().reverse(); - files.top().left().add(button).align(Align.topLeft).fillX().expandX() - .height(50).pad(2).padTop(0).padBottom(0).colspan(2); - button.getLabel().setAlignment(Align.left); - files.row(); - } + ImageButton home = new ImageButton("icon-home"); + home.resizeImage(isize); + home.clicked(() -> { + directory = homeDirectory; + updateFiles(true); + }); - pane.setScrollY(0f); - updateFileFieldStatus(); - - if(open) filefield.clearText(); - } + icontable.defaults().height(50).growX().uniform(); + icontable.add(home); + icontable.add(back); + icontable.add(forward); + icontable.add(up); - private String shorten(String string){ - int max = 30; - if(string.length() <= max){ - return string; - }else{ - return string.substring(0, max - 3).concat("..."); - } - } + Table fieldcontent = new Table(); + fieldcontent.bottom().left().add(new Label("File Name:")); + fieldcontent.add(filefield).height(40f).fillX().expandX().padLeft(10f); - @Override - public Dialog show(){ - Timers.runTask(2f, () -> { - content().clear(); - setupWidgets(); - super.show(); - Core.scene.setScrollFocus(pane); - }); - return this; - } + Table buttons = new Table(); + buttons.defaults().growX().height(50); + buttons.add(cancel); + buttons.add(ok); - public void fileSelected(Consumer listener){ - this.selectListener = listener; - } + content.top().left(); + content.add(icontable).expandX().fillX(); + content.row(); - public class FileHistory{ - private Array history = new Array<>(); - private int index; + content.center().add(pane).width(UIUtils.portrait() ? Gdx.graphics.getWidth() / Unit.dp.scl(1) : Gdx.graphics.getWidth() / Unit.dp.scl(2)).colspan(3).grow(); + content.row(); - public FileHistory(){ + if(!open){ + content.bottom().left().add(fieldcontent).colspan(3).grow().padTop(-2).padBottom(2); + content.row(); + } - } + content.add(buttons).growX(); - public void push(FileHandle file){ - if(index != history.size) history.truncate(index); - history.add(file); - index ++; - } + content().add(content); + } - public void back(){ - if( !canBack()) return; - index --; - directory = history.get(index - 1); - updateFiles(false); - } + private void updateFileFieldStatus(){ + if(!open){ + ok.setDisabled(filefield.getText().replace(" ", "").isEmpty()); + }else{ + ok.setDisabled(!directory.child(filefield.getText()).exists() || directory.child(filefield.getText()).isDirectory()); + } + } - public void forward(){ - if( !canForward()) return; - directory = history.get(index); - index ++; - updateFiles(false); - } + private FileHandle[] getFileNames(){ + FileHandle[] handles = directory.list(file -> !file.getName().startsWith(".")); - public boolean canForward(){ - return !(index >= history.size); - } + Arrays.sort(handles, (a, b) -> { + if(a.isDirectory() && !b.isDirectory()) return -1; + if(!a.isDirectory() && b.isDirectory()) return 1; + return a.name().toUpperCase().compareTo(b.name().toUpperCase()); + }); + return handles; + } - public boolean canBack(){ - return !(index == 1) && index > 0; - } + private void updateFiles(boolean push){ + if(push) stack.push(directory); + //if is mac, don't display extra info since you can only ever go to downloads + navigation.setText(OS.isMac ? directory.name() : directory.toString()); - void print(){ + GlyphLayout layout = Pools.obtain(GlyphLayout.class); - System.out.println("\n\n\n\n\n\n"); - int i = 0; - for(FileHandle file : history){ - i ++; - if(index == i){ - System.out.println("[[" + file.toString() + "]]"); - }else{ - System.out.println("--" + file.toString() + "--"); - } - } - } - } + layout.setText(Core.font, navigation.getText()); - public interface FileHandleFilter{ - boolean accept(FileHandle file); - } + if(layout.width < navigation.getWidth()){ + navigation.setCursorPosition(0); + }else{ + navigation.setCursorPosition(navigation.getText().length()); + } - public static Predicate pngFilter = file -> file.extension().equalsIgnoreCase("png"); - public static Predicate mapFilter = file -> file.extension().equalsIgnoreCase(Vars.mapExtension); - public static Predicate jpegFilter = file -> file.extension().equalsIgnoreCase("png") || file.extension().equalsIgnoreCase("jpg") || file.extension().equalsIgnoreCase("jpeg"); - public static Predicate defaultFilter = file -> true; + Pools.free(layout); + + files.clearChildren(); + files.top().left(); + FileHandle[] names = getFileNames(); + + //macs are confined to the Downloads/ directory + if(!OS.isMac){ + Image upimage = new Image("icon-folder-parent"); + TextButton upbutton = new TextButton(".." + directory.toString()); + upbutton.clicked(() -> { + directory = directory.parent(); + updateFiles(true); + }); + + upbutton.left().add(upimage).padRight(4f).size(14 * 2); + upbutton.getLabel().setAlignment(Align.left); + upbutton.getCells().reverse(); + + files.add(upbutton).align(Align.topLeft).fillX().expandX().height(50).pad(2).colspan(2); + files.row(); + } + + ButtonGroup group = new ButtonGroup<>(); + group.setMinCheckCount(0); + + for(FileHandle file : names){ + if(!file.isDirectory() && !filter.test(file)) continue; //skip non-filtered files + + String filename = file.name(); + + TextButton button = new TextButton(shorten(filename), "toggle"); + group.add(button); + + button.clicked(() -> { + if(!file.isDirectory()){ + filefield.setText(filename); + updateFileFieldStatus(); + }else{ + directory = directory.child(filename); + updateFiles(true); + } + }); + + filefield.changed(() -> { + button.setChecked(filename.equals(filefield.getText())); + }); + + Image image = new Image(file.isDirectory() ? "icon-folder" : "icon-file-text"); + + button.add(image).padRight(4f).size(14 * 2f); + button.getCells().reverse(); + files.top().left().add(button).align(Align.topLeft).fillX().expandX() + .height(50).pad(2).padTop(0).padBottom(0).colspan(2); + button.getLabel().setAlignment(Align.left); + files.row(); + } + + pane.setScrollY(0f); + updateFileFieldStatus(); + + if(open) filefield.clearText(); + } + + private String shorten(String string){ + int max = 30; + if(string.length() <= max){ + return string; + }else{ + return string.substring(0, max - 3).concat("..."); + } + } + + @Override + public Dialog show(){ + Timers.runTask(2f, () -> { + content().clear(); + setupWidgets(); + super.show(); + Core.scene.setScrollFocus(pane); + }); + return this; + } + + public void fileSelected(Consumer listener){ + this.selectListener = listener; + } + + public interface FileHandleFilter{ + boolean accept(FileHandle file); + } + + public class FileHistory{ + private Array history = new Array<>(); + private int index; + + public FileHistory(){ + + } + + public void push(FileHandle file){ + if(index != history.size) history.truncate(index); + history.add(file); + index++; + } + + public void back(){ + if(!canBack()) return; + index--; + directory = history.get(index - 1); + updateFiles(false); + } + + public void forward(){ + if(!canForward()) return; + directory = history.get(index); + index++; + updateFiles(false); + } + + public boolean canForward(){ + return !(index >= history.size); + } + + public boolean canBack(){ + return !(index == 1) && index > 0; + } + + void print(){ + + System.out.println("\n\n\n\n\n\n"); + int i = 0; + for(FileHandle file : history){ + i++; + if(index == i){ + System.out.println("[[" + file.toString() + "]]"); + }else{ + System.out.println("--" + file.toString() + "--"); + } + } + } + } } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/FloatingDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/FloatingDialog.java index e894da9207..16ba45bcff 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/FloatingDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/FloatingDialog.java @@ -11,43 +11,43 @@ import io.anuke.ucore.scene.ui.Dialog; import io.anuke.ucore.scene.ui.ScrollPane; public class FloatingDialog extends Dialog{ - - public FloatingDialog(String title){ - super(title, "dialog"); - setFillParent(true); - title().setAlignment(Align.center); - getTitleTable().row(); - getTitleTable().addImage("white", Palette.accent) - .growX().height(3f).pad(4f); - boolean[] done = {false}; + public FloatingDialog(String title){ + super(title, "dialog"); + setFillParent(true); + title().setAlignment(Align.center); + getTitleTable().row(); + getTitleTable().addImage("white", Palette.accent) + .growX().height(3f).pad(4f); - shown(() -> Gdx.app.postRunnable(() -> - forEach(child -> { - if (done[0]) return; + boolean[] done = {false}; - if (child instanceof ScrollPane) { - Core.scene.setScrollFocus(child); - done[0] = true; - } - }))); - } + shown(() -> Gdx.app.postRunnable(() -> + forEach(child -> { + if(done[0]) return; - protected void onResize(Runnable run){ - Events.on(ResizeEvent.class, () -> { - if(isShown()){ - run.run(); - } - }); - } - - @Override - public void addCloseButton(){ - buttons().addImageTextButton("$text.back", "icon-arrow-left", 30f, this::hide).size(230f, 64f); - - keyDown(key -> { - if(key == Keys.ESCAPE || key == Keys.BACK) - hide(); - }); - } + if(child instanceof ScrollPane){ + Core.scene.setScrollFocus(child); + done[0] = true; + } + }))); + } + + protected void onResize(Runnable run){ + Events.on(ResizeEvent.class, () -> { + if(isShown()){ + run.run(); + } + }); + } + + @Override + public void addCloseButton(){ + buttons().addImageTextButton("$text.back", "icon-arrow-left", 30f, this::hide).size(230f, 64f); + + keyDown(key -> { + if(key == Keys.ESCAPE || key == Keys.BACK) + hide(); + }); + } } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java index 2864942d46..077cd57de9 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java @@ -55,7 +55,7 @@ public class HostDialog extends FloatingDialog{ try{ Net.host(Vars.port); player.isAdmin = true; - }catch (IOException e){ + }catch(IOException e){ ui.showError(Bundles.format("text.server.error", Strings.parseException(e, false))); } ui.loadfrag.hide(); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java index 7777935928..8d48aa37ca 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java @@ -25,7 +25,7 @@ import io.anuke.ucore.util.Strings; import static io.anuke.mindustry.Vars.*; -public class JoinDialog extends FloatingDialog { +public class JoinDialog extends FloatingDialog{ Array servers = new Array<>(); Dialog add; Server renaming; @@ -49,7 +49,7 @@ public class JoinDialog extends FloatingDialog { add = new FloatingDialog("$text.joingame.title"); add.content().add("$text.joingame.ip").padRight(5f).left(); - Platform.instance.addDialog(add.content().addField(Settings.getString("ip"), text ->{ + Platform.instance.addDialog(add.content().addField(Settings.getString("ip"), text -> { Settings.putString("ip", text); Settings.save(); }).size(320f, 54f).get(), 100); @@ -58,7 +58,7 @@ public class JoinDialog extends FloatingDialog { add.buttons().defaults().size(140f, 60f).pad(4f); add.buttons().addButton("$text.cancel", add::hide); add.buttons().addButton("$text.ok", () -> { - if(renaming == null) { + if(renaming == null){ Server server = new Server(Settings.getString("ip"), Strings.parseInt(Settings.getString("port"))); servers.add(server); saveServers(); @@ -88,11 +88,11 @@ public class JoinDialog extends FloatingDialog { void setupRemote(){ remote.clear(); - for (Server server : servers) { + for(Server server : servers){ //why are java lambdas this bad TextButton[] buttons = {null}; - TextButton button = buttons[0] = remote.addButton("[accent]"+server.ip, "clear", () -> { + TextButton button = buttons[0] = remote.addButton("[accent]" + server.ip, "clear", () -> { if(!buttons[0].childrenPressed()) connect(server.ip, Vars.port); }).width(targetWidth()).height(150f).pad(4f).get(); @@ -104,16 +104,16 @@ public class JoinDialog extends FloatingDialog { inner.add(button.getLabel()).growX(); - inner.addImageButton("icon-loading", "empty", 16*2, () -> { + inner.addImageButton("icon-loading", "empty", 16 * 2, () -> { refreshServer(server); }).margin(3f).padTop(6f).top().right(); - inner.addImageButton("icon-pencil", "empty", 16*2, () -> { + inner.addImageButton("icon-pencil", "empty", 16 * 2, () -> { renaming = server; add.show(); }).margin(3f).padTop(6f).top().right(); - inner.addImageButton("icon-trash-16", "empty", 16*2, () -> { + inner.addImageButton("icon-trash-16", "empty", 16 * 2, () -> { ui.showConfirm("$text.confirm", "$text.server.delete", () -> { servers.removeValue(server, true); saveServers(); @@ -124,7 +124,8 @@ public class JoinDialog extends FloatingDialog { button.row(); - server.content = button.table(t -> {}).grow().get(); + server.content = button.table(t -> { + }).grow().get(); remote.row(); } @@ -143,7 +144,7 @@ public class JoinDialog extends FloatingDialog { Net.pingHost(server.ip, server.port, host -> { String versionString; - if(host.version == -1) { + if(host.version == -1){ versionString = Bundles.format("text.server.version", Bundles.get("text.server.custombuild")); }else if(host.version == 0){ versionString = Bundles.get("text.server.outdated"); @@ -179,7 +180,7 @@ public class JoinDialog extends FloatingDialog { } void refreshLocal(){ - if(!Vars.gwt) { + if(!Vars.gwt){ local.clear(); local.background("button"); local.label(() -> "[accent]" + Bundles.get("text.hosts.discovering") + Strings.animated(4, 10f, ".")).pad(10f); @@ -227,7 +228,7 @@ public class JoinDialog extends FloatingDialog { content().row(); content().add(pane).width(w + 34).pad(0); content().row(); - content().addCenteredImageTextButton("$text.server.add", "icon-add", "clear", 14*3, () -> { + content().addCenteredImageTextButton("$text.server.add", "icon-add", "clear", 14 * 3, () -> { renaming = null; add.show(); }).marginLeft(6).width(w).height(80f).update(button -> { @@ -238,7 +239,7 @@ public class JoinDialog extends FloatingDialog { pad = 6; } - Cell cell = ((Table)pane.getParent()).getCell(button); + Cell cell = ((Table) pane.getParent()).getCell(button); if(!MathUtils.isEqual(cell.getMinWidth(), pw)){ cell.width(pw); @@ -256,10 +257,10 @@ public class JoinDialog extends FloatingDialog { if(array.size == 0){ local.add("$text.hosts.none").pad(10f); local.add().growX(); - local.addImageButton("icon-loading", 16*2f, this::refreshLocal).pad(-10f).padLeft(0).padTop(-6).size(70f, 74f); - }else { - for (Host a : array) { - TextButton button = local.addButton("[accent]"+a.name, "clear", () -> { + local.addImageButton("icon-loading", 16 * 2f, this::refreshLocal).pad(-10f).padLeft(0).padTop(-6).size(70f, 74f); + }else{ + for(Host a : array){ + TextButton button = local.addButton("[accent]" + a.name, "clear", () -> { connect(a.address, Vars.port); }).width(w).height(80f).pad(4f).get(); button.left(); @@ -289,18 +290,18 @@ public class JoinDialog extends FloatingDialog { Net.connect(ip, port); hide(); add.hide(); - }catch (Exception e) { + }catch(Exception e){ Throwable t = e; while(t.getCause() != null){ t = t.getCause(); } //TODO localize String error = t.getMessage() == null ? "" : t.getMessage().toLowerCase(); - if(error.contains("connection refused")) { + if(error.contains("connection refused")){ error = "connection refused"; }else if(error.contains("port out of range")){ error = "invalid port!"; - }else if(error.contains("invalid argument")) { + }else if(error.contains("invalid argument")){ error = "invalid IP or port!"; }else if(t.getClass().toString().toLowerCase().contains("sockettimeout")){ error = "timed out!\nmake sure the host has port forwarding set up,\nand that the address is correct!"; @@ -340,6 +341,7 @@ public class JoinDialog extends FloatingDialog { this.port = port; } - Server(){} + Server(){ + } } } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/LevelDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/LevelDialog.java index 457856f17c..4df4316cd7 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/LevelDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/LevelDialog.java @@ -24,142 +24,142 @@ import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.*; public class LevelDialog extends FloatingDialog{ - - public LevelDialog(){ - super("$text.level.select"); - addCloseButton(); - shown(this::setup); - onResize(this::setup); - } - - void setup(){ - content().clear(); + public LevelDialog(){ + super("$text.level.select"); + addCloseButton(); + shown(this::setup); - Table maps = new Table(); - maps.marginRight(14); - ScrollPane pane = new ScrollPane(maps, "clear-black"); - pane.setFadeScrollBars(false); - - int maxwidth = (Gdx.graphics.getHeight() > Gdx.graphics.getHeight() ? 2 : 4); - - Table selmode = new Table(); - ButtonGroup group = new ButtonGroup<>(); - selmode.add("$text.level.mode").padRight(15f); - - for(GameMode mode : GameMode.values()){ - TextButton[] b = {null}; - b[0] = Elements.newButton("$mode." + mode.name() + ".name", "toggle", () -> state.mode = mode); - b[0].update(() -> b[0].setChecked(state.mode == mode)); - group.add(b[0]); - selmode.add(b[0]).size(130f, 54f); - } - selmode.addButton("?", this::displayGameModeHelp).size(50f, 54f).padLeft(18f); - - content().add(selmode); - content().row(); + onResize(this::setup); + } - Difficulty[] ds = Difficulty.values(); + void setup(){ + content().clear(); - float s = 50f; + Table maps = new Table(); + maps.marginRight(14); + ScrollPane pane = new ScrollPane(maps, "clear-black"); + pane.setFadeScrollBars(false); - Table sdif = new Table(); + int maxwidth = (Gdx.graphics.getHeight() > Gdx.graphics.getHeight() ? 2 : 4); - sdif.add("$setting.difficulty.name").padRight(15f); + Table selmode = new Table(); + ButtonGroup group = new ButtonGroup<>(); + selmode.add("$text.level.mode").padRight(15f); - sdif.defaults().height(s+4); - sdif.addImageButton("icon-arrow-left", 10*3, () -> { - state.difficulty = (ds[Mathf.mod(state.difficulty.ordinal() - 1, ds.length)]); - }).width(s); + for(GameMode mode : GameMode.values()){ + TextButton[] b = {null}; + b[0] = Elements.newButton("$mode." + mode.name() + ".name", "toggle", () -> state.mode = mode); + b[0].update(() -> b[0].setChecked(state.mode == mode)); + group.add(b[0]); + selmode.add(b[0]).size(130f, 54f); + } + selmode.addButton("?", this::displayGameModeHelp).size(50f, 54f).padLeft(18f); - sdif.addButton("", () -> { + content().add(selmode); + content().row(); - }).update(t -> { - t.setText(state.difficulty.toString()); - t.setTouchable(Touchable.disabled); - }).width(180f); + Difficulty[] ds = Difficulty.values(); - sdif.addImageButton("icon-arrow-right", 10*3, () -> { - state.difficulty = (ds[Mathf.mod(state.difficulty.ordinal() + 1, ds.length)]); - }).width(s); + float s = 50f; - content().add(sdif); - content().row(); + Table sdif = new Table(); - float images = 146f; + sdif.add("$setting.difficulty.name").padRight(15f); - int i = 0; - for(Map map : world.maps().all()){ + sdif.defaults().height(s + 4); + sdif.addImageButton("icon-arrow-left", 10 * 3, () -> { + state.difficulty = (ds[Mathf.mod(state.difficulty.ordinal() - 1, ds.length)]); + }).width(s); - if(i % maxwidth == 0){ - maps.row(); - } - - ImageButton image = new ImageButton(new TextureRegion(map.texture), "clear"); - image.margin(5); - image.getImageCell().size(images); - image.top(); - image.row(); - image.add("[accent]" + Bundles.get("map."+map.name+".name", map.name)).pad(3f).growX().wrap().get().setAlignment(Align.center, Align.center); - image.row(); - image.label((() -> Bundles.format("text.level.highscore", Settings.getInt("hiscore" + map.name, 0)))).pad(3f); + sdif.addButton("", () -> { - BorderImage border = new BorderImage(map.texture, 3f); - image.replaceImage(border); + }).update(t -> { + t.setText(state.difficulty.toString()); + t.setTouchable(Touchable.disabled); + }).width(180f); - image.clicked(() -> { - hide(); - control.playMap(map); - }); - - maps.add(image).width(170).fillY().top().pad(4f); - - i ++; - } + sdif.addImageButton("icon-arrow-right", 10 * 3, () -> { + state.difficulty = (ds[Mathf.mod(state.difficulty.ordinal() + 1, ds.length)]); + }).width(s); - ImageButton genb = maps.addImageButton("icon-editor", "clear", 16*3, () -> { - hide(); + content().add(sdif); + content().row(); - ui.loadfrag.show(); + float images = 146f; - Timers.run(5f, () -> { - Cursors.restoreCursor(); - threads.run(() -> { - world.loadProceduralMap(); - logic.play(); - Gdx.app.postRunnable(ui.loadfrag::hide); - }); - }); - }).width(170).fillY().pad(4f).get(); + int i = 0; + for(Map map : world.maps().all()){ - genb.top(); - genb.margin(5); - genb.clearChildren(); - genb.add(new BorderImage(Draw.region("icon-generated"), 3f)).size(images); - genb.row(); - genb.add("$text.map.random").growX().wrap().pad(3f).get().setAlignment(Align.center, Align.center); - genb.row(); - genb.add("").pad(3f); - - content().add(pane).uniformX(); - } + if(i % maxwidth == 0){ + maps.row(); + } - private void displayGameModeHelp() { - FloatingDialog d = new FloatingDialog(Bundles.get("mode.text.help.title")); - d.setFillParent(false); - Table table = new Table(); - table.defaults().pad(1f); - ScrollPane pane = new ScrollPane(table, "clear"); - pane.setFadeScrollBars(false); - table.row(); - for(GameMode mode : GameMode.values()){ - table.labelWrap("[accent]" + mode.toString() + ":[] [lightgray]" + mode.description()).width(600f); - table.row(); - } + ImageButton image = new ImageButton(new TextureRegion(map.texture), "clear"); + image.margin(5); + image.getImageCell().size(images); + image.top(); + image.row(); + image.add("[accent]" + Bundles.get("map." + map.name + ".name", map.name)).pad(3f).growX().wrap().get().setAlignment(Align.center, Align.center); + image.row(); + image.label((() -> Bundles.format("text.level.highscore", Settings.getInt("hiscore" + map.name, 0)))).pad(3f); - d.content().add(pane); - d.buttons().addButton("$text.ok", d::hide).size(110, 50).pad(10f); - d.show(); - } + BorderImage border = new BorderImage(map.texture, 3f); + image.replaceImage(border); + + image.clicked(() -> { + hide(); + control.playMap(map); + }); + + maps.add(image).width(170).fillY().top().pad(4f); + + i++; + } + + ImageButton genb = maps.addImageButton("icon-editor", "clear", 16 * 3, () -> { + hide(); + + ui.loadfrag.show(); + + Timers.run(5f, () -> { + Cursors.restoreCursor(); + threads.run(() -> { + world.loadProceduralMap(); + logic.play(); + Gdx.app.postRunnable(ui.loadfrag::hide); + }); + }); + }).width(170).fillY().pad(4f).get(); + + genb.top(); + genb.margin(5); + genb.clearChildren(); + genb.add(new BorderImage(Draw.region("icon-generated"), 3f)).size(images); + genb.row(); + genb.add("$text.map.random").growX().wrap().pad(3f).get().setAlignment(Align.center, Align.center); + genb.row(); + genb.add("").pad(3f); + + content().add(pane).uniformX(); + } + + private void displayGameModeHelp(){ + FloatingDialog d = new FloatingDialog(Bundles.get("mode.text.help.title")); + d.setFillParent(false); + Table table = new Table(); + table.defaults().pad(1f); + ScrollPane pane = new ScrollPane(table, "clear"); + pane.setFadeScrollBars(false); + table.row(); + for(GameMode mode : GameMode.values()){ + table.labelWrap("[accent]" + mode.toString() + ":[] [lightgray]" + mode.description()).width(600f); + table.row(); + } + + d.content().add(pane); + d.buttons().addButton("$text.ok", d::hide).size(110, 50).pad(10f); + d.show(); + } } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/LoadDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/LoadDialog.java index 7285338725..7730850513 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/LoadDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/LoadDialog.java @@ -6,11 +6,9 @@ import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.Vars; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.core.Platform; -import io.anuke.mindustry.game.EventType.ResizeEvent; import io.anuke.mindustry.io.SaveIO; import io.anuke.mindustry.io.Saves.SaveSlot; import io.anuke.ucore.core.Core; -import io.anuke.ucore.core.Events; import io.anuke.ucore.core.Timers; import io.anuke.ucore.scene.ui.ScrollPane; import io.anuke.ucore.scene.ui.TextButton; @@ -24,150 +22,150 @@ import java.io.IOException; import static io.anuke.mindustry.Vars.*; public class LoadDialog extends FloatingDialog{ - ScrollPane pane; - Table slots; + ScrollPane pane; + Table slots; - public LoadDialog() { - this("$text.loadgame"); - } + public LoadDialog(){ + this("$text.loadgame"); + } - public LoadDialog(String title) { - super(title); - setup(); + public LoadDialog(String title){ + super(title); + setup(); - shown(() -> { - setup(); - Timers.runTask(2f, () -> Core.scene.setScrollFocus(pane)); - }); + shown(() -> { + setup(); + Timers.runTask(2f, () -> Core.scene.setScrollFocus(pane)); + }); - addCloseButton(); - } + addCloseButton(); + } - protected void setup(){ - content().clear(); + protected void setup(){ + content().clear(); - slots = new Table(); - pane = new ScrollPane(slots, "clear-black"); - pane.setFadeScrollBars(false); - pane.setScrollingDisabled(true, false); + slots = new Table(); + pane = new ScrollPane(slots, "clear-black"); + pane.setFadeScrollBars(false); + pane.setScrollingDisabled(true, false); - slots.marginRight(24); + slots.marginRight(24); - Timers.runTask(2f, () -> Core.scene.setScrollFocus(pane)); + Timers.runTask(2f, () -> Core.scene.setScrollFocus(pane)); - Array array = control.getSaves().getSaveSlots(); + Array array = control.getSaves().getSaveSlots(); - for(SaveSlot slot : array){ + for(SaveSlot slot : array){ - TextButton button = new TextButton("[accent]" + slot.getName(), "clear"); - button.getLabelCell().growX().left(); - button.getLabelCell().padBottom(8f); - button.getLabelCell().top().left().growX(); + TextButton button = new TextButton("[accent]" + slot.getName(), "clear"); + button.getLabelCell().growX().left(); + button.getLabelCell().padBottom(8f); + button.getLabelCell().top().left().growX(); - button.defaults().left(); + button.defaults().left(); - button.table(t -> { - t.right(); + button.table(t -> { + t.right(); - t.addImageButton("icon-floppy", "emptytoggle", 14*3, () -> { - slot.setAutosave(!slot.isAutosave()); - }).checked(slot.isAutosave()).right(); + t.addImageButton("icon-floppy", "emptytoggle", 14 * 3, () -> { + slot.setAutosave(!slot.isAutosave()); + }).checked(slot.isAutosave()).right(); - t.addImageButton("icon-trash", "empty", 14*3, () -> { - ui.showConfirm("$text.confirm", "$text.save.delete.confirm", () -> { - slot.delete(); - setup(); - }); - }).size(14*3).right(); + t.addImageButton("icon-trash", "empty", 14 * 3, () -> { + ui.showConfirm("$text.confirm", "$text.save.delete.confirm", () -> { + slot.delete(); + setup(); + }); + }).size(14 * 3).right(); - t.addImageButton("icon-pencil-small", "empty", 14*3, () -> { - ui.showTextInput("$text.save.rename", "$text.save.rename.text", slot.getName(), text -> { - slot.setName(text); - setup(); - }); - }).size(14*3).right(); + t.addImageButton("icon-pencil-small", "empty", 14 * 3, () -> { + ui.showTextInput("$text.save.rename", "$text.save.rename.text", slot.getName(), text -> { + slot.setName(text); + setup(); + }); + }).size(14 * 3).right(); - if(!gwt) { - t.addImageButton("icon-save", "empty", 14 * 3, () -> { - if(!ios) { - Platform.instance.showFileChooser(Bundles.get("text.save.export"), "Mindustry Save", file -> { - try { - slot.exportFile(file); - setup(); - } catch (IOException e) { - ui.showError(Bundles.format("text.save.export.fail", Strings.parseException(e, false))); - } - }, false, saveExtension); + if(!gwt){ + t.addImageButton("icon-save", "empty", 14 * 3, () -> { + if(!ios){ + Platform.instance.showFileChooser(Bundles.get("text.save.export"), "Mindustry Save", file -> { + try{ + slot.exportFile(file); + setup(); + }catch(IOException e){ + ui.showError(Bundles.format("text.save.export.fail", Strings.parseException(e, false))); + } + }, false, saveExtension); }else{ - try { + try{ FileHandle file = Gdx.files.local("save-" + slot.getName() + "." + Vars.saveExtension); slot.exportFile(file); Platform.instance.shareFile(file); - }catch (Exception e){ + }catch(Exception e){ ui.showError(Bundles.format("text.save.export.fail", Strings.parseException(e, false))); } } - }).size(14 * 3).right(); - } + }).size(14 * 3).right(); + } - }).padRight(-10).growX(); + }).padRight(-10).growX(); - String color = "[lightgray]"; + String color = "[lightgray]"; - button.defaults().padBottom(3); - button.row(); - button.add(Bundles.format("text.save.map", color+ (slot.getMap() == null ? "Unknown" : slot.getMap().meta.name()))); - button.row(); - button.add(Bundles.get("text.level.mode") + " " +color+ slot.getMode()); - button.row(); - button.add(Bundles.format("text.save.wave", color+slot.getWave())); - button.row(); - button.add(Bundles.format("text.save.difficulty", color+slot.getDifficulty())); - button.row(); - button.label(() -> Bundles.format("text.save.autosave", color + Bundles.get(slot.isAutosave() ? "text.on" : "text.off"))); - button.row(); - button.add(Bundles.format("text.save.date", color+slot.getDate())).colspan(2).padTop(5).right(); - button.row(); - modifyButton(button, slot); + button.defaults().padBottom(3); + button.row(); + button.add(Bundles.format("text.save.map", color + (slot.getMap() == null ? "Unknown" : slot.getMap().meta.name()))); + button.row(); + button.add(Bundles.get("text.level.mode") + " " + color + slot.getMode()); + button.row(); + button.add(Bundles.format("text.save.wave", color + slot.getWave())); + button.row(); + button.add(Bundles.format("text.save.difficulty", color + slot.getDifficulty())); + button.row(); + button.label(() -> Bundles.format("text.save.autosave", color + Bundles.get(slot.isAutosave() ? "text.on" : "text.off"))); + button.row(); + button.add(Bundles.format("text.save.date", color + slot.getDate())).colspan(2).padTop(5).right(); + button.row(); + modifyButton(button, slot); - slots.add(button).uniformX().fillX().pad(4).padRight(-4).margin(10f).marginLeft(20f).marginRight(20f); - slots.row(); - } + slots.add(button).uniformX().fillX().pad(4).padRight(-4).margin(10f).marginLeft(20f).marginRight(20f); + slots.row(); + } - content().add(pane); + content().add(pane); - addSetup(); - } + addSetup(); + } - public void addSetup(){ - if(control.getSaves().getSaveSlots().size == 0) { + public void addSetup(){ + if(control.getSaves().getSaveSlots().size == 0){ - slots.row(); - slots.addButton("$text.save.none", "clear", () -> { - }).disabled(true).fillX().margin(20f).minWidth(340f).height(80f).pad(4f); - } + slots.row(); + slots.addButton("$text.save.none", "clear", () -> { + }).disabled(true).fillX().margin(20f).minWidth(340f).height(80f).pad(4f); + } - slots.row(); + slots.row(); - if(gwt || ios) return; + if(gwt || ios) return; - slots.addImageTextButton("$text.save.import", "icon-add", "clear", 14*3, () -> { - Platform.instance.showFileChooser(Bundles.get("text.save.import"), "Mindustry Save", file -> { - if(SaveIO.isSaveValid(file)){ - try{ - control.getSaves().importSave(file); - setup(); - }catch (IOException e){ - ui.showError(Bundles.format("text.save.import.fail", Strings.parseException(e, false))); - } - }else{ - ui.showError("$text.save.import.invalid"); - } - }, true, saveExtension); - }).fillX().margin(10f).minWidth(300f).height(70f).pad(4f).padRight(-4); - } + slots.addImageTextButton("$text.save.import", "icon-add", "clear", 14 * 3, () -> { + Platform.instance.showFileChooser(Bundles.get("text.save.import"), "Mindustry Save", file -> { + if(SaveIO.isSaveValid(file)){ + try{ + control.getSaves().importSave(file); + setup(); + }catch(IOException e){ + ui.showError(Bundles.format("text.save.import.fail", Strings.parseException(e, false))); + } + }else{ + ui.showError("$text.save.import.invalid"); + } + }, true, saveExtension); + }).fillX().margin(10f).minWidth(300f).height(70f).pad(4f).padRight(-4); + } - public void runLoadSave(SaveSlot slot){ + public void runLoadSave(SaveSlot slot){ ui.loadfrag.show(); Timers.runTask(3f, () -> { @@ -187,11 +185,11 @@ public class LoadDialog extends FloatingDialog{ }); } - public void modifyButton(TextButton button, SaveSlot slot){ - button.clicked(() -> { - if(!button.childrenPressed()){ - runLoadSave(slot); - } - }); - } + public void modifyButton(TextButton button, SaveSlot slot){ + button.clicked(() -> { + if(!button.childrenPressed()){ + runLoadSave(slot); + } + }); + } } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/LocalPlayerDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/LocalPlayerDialog.java index 29927af5b4..7ef5786ee3 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/LocalPlayerDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/LocalPlayerDialog.java @@ -1,16 +1,18 @@ package io.anuke.mindustry.ui.dialogs; import com.badlogic.gdx.utils.Scaling; -import static io.anuke.mindustry.Vars.*; import io.anuke.mindustry.entities.Player; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.scene.ui.Image; import io.anuke.ucore.scene.ui.layout.Stack; import io.anuke.ucore.scene.ui.layout.Table; +import static io.anuke.mindustry.Vars.control; +import static io.anuke.mindustry.Vars.players; + public class LocalPlayerDialog extends FloatingDialog{ - public LocalPlayerDialog() { + public LocalPlayerDialog(){ super("$text.addplayers"); addCloseButton(); @@ -22,7 +24,7 @@ public class LocalPlayerDialog extends FloatingDialog{ content().clear(); - if(players.length > 1) { + if(players.length > 1){ content().addImageButton("icon-cancel", 14 * 2, () -> { control.removePlayer(); rebuild(); @@ -49,7 +51,7 @@ public class LocalPlayerDialog extends FloatingDialog{ content().add(table).pad(5); } - if(players.length < 4) { + if(players.length < 4){ content().addImageButton("icon-add", 14 * 2, () -> { control.addPlayer(players.length); rebuild(); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/MapsDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/MapsDialog.java index f1abf8086c..b60603fa82 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/MapsDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/MapsDialog.java @@ -22,13 +22,13 @@ import java.io.DataInputStream; import static io.anuke.mindustry.Vars.*; -public class MapsDialog extends FloatingDialog { +public class MapsDialog extends FloatingDialog{ - public MapsDialog() { + public MapsDialog(){ super("$text.maps"); addCloseButton(); - buttons().addImageTextButton("$text.editor.importmap", "icon-add", 14*2, () -> { + buttons().addImageTextButton("$text.editor.importmap", "icon-add", 14 * 2, () -> { Platform.instance.showFileChooser("$text.editor.importmap", "Map File", file -> { try{ DataInputStream stream = new DataInputStream(file.read()); @@ -50,7 +50,7 @@ public class MapsDialog extends FloatingDialog { setup(); } - }catch (Exception e){ + }catch(Exception e){ ui.showError(Bundles.format("text.editor.errorimageload", Strings.parseException(e, false))); Log.err(e); } @@ -86,11 +86,11 @@ public class MapsDialog extends FloatingDialog { button.row(); button.addImage("white").growX().pad(4).color(Color.GRAY); button.row(); - ((Image)button.stack(new Image(map.texture), new BorderImage(map.texture)).size(mapsize-20f).get().getChildren().first()).setScaling(Scaling.fit); + ((Image) button.stack(new Image(map.texture), new BorderImage(map.texture)).size(mapsize - 20f).get().getChildren().first()).setScaling(Scaling.fit); button.row(); button.add(map.custom ? "$text.custom" : "$text.builtin").color(Color.GRAY).padTop(3); - i ++; + i++; } if(world.maps().all().size == 0){ @@ -139,13 +139,13 @@ public class MapsDialog extends FloatingDialog { table.row(); - table.addImageTextButton("$text.editor.openin", "icon-load-map", "clear", 16*2, () -> { + table.addImageTextButton("$text.editor.openin", "icon-load-map", "clear", 16 * 2, () -> { Vars.ui.editor.beginEditMap(map.stream.get()); dialog.hide(); hide(); }).fillX().height(50f).marginLeft(6); - table.addImageTextButton("$text.delete", "icon-trash-16", "clear", 16*2, () -> { + table.addImageTextButton("$text.delete", "icon-trash-16", "clear", 16 * 2, () -> { ui.showConfirm("$text.confirm", Bundles.format("text.map.delete", map.name), () -> { world.maps().removeMap(map); dialog.hide(); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java index 5caf0f519b..d2be114720 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java @@ -11,136 +11,136 @@ import io.anuke.ucore.util.Bundles; import static io.anuke.mindustry.Vars.*; public class PausedDialog extends FloatingDialog{ - private SaveDialog save = new SaveDialog(); - private LoadDialog load = new LoadDialog(); - public boolean wasPaused = false; + public boolean wasPaused = false; + private SaveDialog save = new SaveDialog(); + private LoadDialog load = new LoadDialog(); - public PausedDialog() { - super("$text.menu"); - setup(); - } + public PausedDialog(){ + super("$text.menu"); + setup(); + } - void setup(){ - update(() -> { - if(state.is(State.menu) && isShown()){ - hide(); - } - }); + void setup(){ + update(() -> { + if(state.is(State.menu) && isShown()){ + hide(); + } + }); - shown(() -> { - wasPaused = state.is(State.paused); - if(!Net.active()) state.set(State.paused); - }); - - if(!mobile){ - content().defaults().width(220).height(50); + shown(() -> { + wasPaused = state.is(State.paused); + if(!Net.active()) state.set(State.paused); + }); - content().addButton("$text.back", () -> { - hide(); - if((!wasPaused || Net.active()) && !state.is(State.menu)) - state.set(State.playing); - }); + if(!mobile){ + content().defaults().width(220).height(50); - content().row(); - content().addButton("$text.settings", ui.settings::show); + content().addButton("$text.back", () -> { + hide(); + if((!wasPaused || Net.active()) && !state.is(State.menu)) + state.set(State.playing); + }); - content().row(); - content().addButton("$text.savegame", () -> { - save.show(); - }); + content().row(); + content().addButton("$text.settings", ui.settings::show); - content().row(); - content().addButton("$text.loadgame", () -> { - load.show(); - }).disabled(b -> Net.active()); + content().row(); + content().addButton("$text.savegame", () -> { + save.show(); + }); - //Local multiplayer is currently functional, but disabled. + content().row(); + content().addButton("$text.loadgame", () -> { + load.show(); + }).disabled(b -> Net.active()); + + //Local multiplayer is currently functional, but disabled. /* content().row(); content().addButton("$text.addplayers", () -> { ui.localplayers.show(); }).disabled(b -> Net.active());*/ - content().row(); + content().row(); - content().addButton("$text.hostserver", () -> { - if(!gwt){ - ui.host.show(); - }else{ - ui.showInfo("$text.host.web"); - } - }).disabled(b -> Net.active()); + content().addButton("$text.hostserver", () -> { + if(!gwt){ + ui.host.show(); + }else{ + ui.showInfo("$text.host.web"); + } + }).disabled(b -> Net.active()); content().row(); - content().addButton("$text.quit", () -> { + content().addButton("$text.quit", () -> { ui.showConfirm("$text.confirm", "$text.quit.confirm", () -> { - if(Net.client()) netClient.disconnectQuietly(); - runExitSave(); - hide(); - }); - }); + if(Net.client()) netClient.disconnectQuietly(); + runExitSave(); + hide(); + }); + }); - }else{ - build.begin(content()); - - content().defaults().size(120f).pad(5); - float isize = 14f*4; - - new imagebutton("icon-play-2", isize, () -> { - hide(); - if(!wasPaused && !state.is(State.menu)) - state.set(State.playing); - }).text("$text.back").padTop(4f); - - new imagebutton("icon-tools", isize, ui.settings::show).text("$text.settings").padTop(4f); - - imagebutton sa = new imagebutton("icon-save", isize, save::show); - sa.text("$text.save").padTop(4f); + }else{ + build.begin(content()); - content().row(); - - imagebutton lo = new imagebutton("icon-load", isize, load::show); - lo.text("$text.load").padTop(4f); - lo.cell.disabled(b -> Net.active()); + content().defaults().size(120f).pad(5); + float isize = 14f * 4; - imagebutton ho = new imagebutton("icon-host", isize, () -> { - ui.host.show(); - }); - ho.text("$text.host").padTop(4f); - ho.cell.disabled(b -> Net.active()); - - new imagebutton("icon-quit", isize, () -> { - ui.showConfirm("$text.confirm", "$text.quit.confirm", () -> { - if(Net.client()) netClient.disconnectQuietly(); - runExitSave(); - hide(); - }); - }).text("Quit").padTop(4f); - - build.end(); - } - } + new imagebutton("icon-play-2", isize, () -> { + hide(); + if(!wasPaused && !state.is(State.menu)) + state.set(State.playing); + }).text("$text.back").padTop(4f); - private void runExitSave(){ - if(control.getSaves().getCurrent() == null || - !control.getSaves().getCurrent().isAutosave()){ - state.set(State.menu); - return; - } + new imagebutton("icon-tools", isize, ui.settings::show).text("$text.settings").padTop(4f); - ui.loadfrag.show("$text.saveload"); + imagebutton sa = new imagebutton("icon-save", isize, save::show); + sa.text("$text.save").padTop(4f); - Timers.runTask(5f, () -> { - ui.loadfrag.hide(); - try{ - control.getSaves().getCurrent().save(); - }catch(Throwable e){ - e = (e.getCause() == null ? e : e.getCause()); - ui.showError("[orange]"+ Bundles.get("text.savefail")+"\n[white]" + ClassReflection.getSimpleName(e.getClass()) + ": " + e.getMessage() + "\n" + "at " + e.getStackTrace()[0].getFileName() + ":" + e.getStackTrace()[0].getLineNumber()); - } - state.set(State.menu); - }); - } + content().row(); + + imagebutton lo = new imagebutton("icon-load", isize, load::show); + lo.text("$text.load").padTop(4f); + lo.cell.disabled(b -> Net.active()); + + imagebutton ho = new imagebutton("icon-host", isize, () -> { + ui.host.show(); + }); + ho.text("$text.host").padTop(4f); + ho.cell.disabled(b -> Net.active()); + + new imagebutton("icon-quit", isize, () -> { + ui.showConfirm("$text.confirm", "$text.quit.confirm", () -> { + if(Net.client()) netClient.disconnectQuietly(); + runExitSave(); + hide(); + }); + }).text("Quit").padTop(4f); + + build.end(); + } + } + + private void runExitSave(){ + if(control.getSaves().getCurrent() == null || + !control.getSaves().getCurrent().isAutosave()){ + state.set(State.menu); + return; + } + + ui.loadfrag.show("$text.saveload"); + + Timers.runTask(5f, () -> { + ui.loadfrag.hide(); + try{ + control.getSaves().getCurrent().save(); + }catch(Throwable e){ + e = (e.getCause() == null ? e : e.getCause()); + ui.showError("[orange]" + Bundles.get("text.savefail") + "\n[white]" + ClassReflection.getSimpleName(e.getClass()) + ": " + e.getMessage() + "\n" + "at " + e.getStackTrace()[0].getFileName() + ":" + e.getStackTrace()[0].getLineNumber()); + } + state.set(State.menu); + }); + } } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/RestartDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/RestartDialog.java index 855f53d6ff..38554f889f 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/RestartDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/RestartDialog.java @@ -5,8 +5,8 @@ import io.anuke.ucore.scene.ui.Dialog; import static io.anuke.mindustry.Vars.*; -public class RestartDialog extends Dialog { - +public class RestartDialog extends Dialog{ + public RestartDialog(){ super("$text.gameover", "dialog"); @@ -21,7 +21,7 @@ public class RestartDialog extends Dialog { pack(); }); - getButtonTable().addButton("$text.menu", ()-> { + getButtonTable().addButton("$text.menu", () -> { hide(); state.set(State.menu); logic.reset(); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/RollbackDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/RollbackDialog.java index 9675e64a9c..2a991e30dd 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/RollbackDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/RollbackDialog.java @@ -5,34 +5,35 @@ import io.anuke.ucore.util.Strings; import static io.anuke.mindustry.Vars.gwt; -public class RollbackDialog extends FloatingDialog { - - public RollbackDialog(){ - super("$text.server.rollback"); - - setup(); - shown(this::setup); - } - - private void setup(){ - content().clear(); - buttons().clear(); - - if(gwt) return; - - content().row(); - content().add("$text.server.rollback.numberfield"); - - TextField field = content().addField("", t->{}).size(200f, 48f).get(); - field.setTextFieldFilter((f, c) -> field.getText().length() < 4); - - content().row(); - buttons().defaults().size(200f, 50f).left().pad(2f); - buttons().addButton("$text.cancel", this::hide); - - buttons().addButton("$text.ok", () -> { - //NetEvents.handleRollbackRequest(Integer.valueOf(field.getText())); - hide(); - }).disabled(b -> field.getText().isEmpty() || !Strings.canParsePostiveInt(field.getText())); - } +public class RollbackDialog extends FloatingDialog{ + + public RollbackDialog(){ + super("$text.server.rollback"); + + setup(); + shown(this::setup); + } + + private void setup(){ + content().clear(); + buttons().clear(); + + if(gwt) return; + + content().row(); + content().add("$text.server.rollback.numberfield"); + + TextField field = content().addField("", t -> { + }).size(200f, 48f).get(); + field.setTextFieldFilter((f, c) -> field.getText().length() < 4); + + content().row(); + buttons().defaults().size(200f, 50f).left().pad(2f); + buttons().addButton("$text.cancel", this::hide); + + buttons().addButton("$text.ok", () -> { + //NetEvents.handleRollbackRequest(Integer.valueOf(field.getText())); + hide(); + }).disabled(b -> field.getText().isEmpty() || !Strings.canParsePostiveInt(field.getText())); + } } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/SaveDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/SaveDialog.java index f56b6f3137..26a5e6b148 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/SaveDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/SaveDialog.java @@ -11,57 +11,57 @@ import static io.anuke.mindustry.Vars.*; public class SaveDialog extends LoadDialog{ - public SaveDialog() { - super("$text.savegame"); + public SaveDialog(){ + super("$text.savegame"); - update(() -> { - if(state.is(State.menu) && isShown()){ - hide(); - } - }); - } + update(() -> { + if(state.is(State.menu) && isShown()){ + hide(); + } + }); + } - public void addSetup(){ - if(!control.getSaves().canAddSave()){ - return; - } + public void addSetup(){ + if(!control.getSaves().canAddSave()){ + return; + } - slots.row(); - slots.addImageTextButton("$text.save.new", "icon-add", "clear", 14*3, () -> - ui.showTextInput("$text.save", "$text.save.newslot", "", text -> { - ui.loadAnd("$text.saving", () -> { - control.getSaves().addSave(text); - setup(); - }); - }) - ).fillX().margin(10f).minWidth(300f).height(70f).pad(4f).padRight(-4); - } + slots.row(); + slots.addImageTextButton("$text.save.new", "icon-add", "clear", 14 * 3, () -> + ui.showTextInput("$text.save", "$text.save.newslot", "", text -> { + ui.loadAnd("$text.saving", () -> { + control.getSaves().addSave(text); + setup(); + }); + }) + ).fillX().margin(10f).minWidth(300f).height(70f).pad(4f).padRight(-4); + } - @Override - public void modifyButton(TextButton button, SaveSlot slot){ - button.clicked(() -> { - if(button.childrenPressed()) return; + @Override + public void modifyButton(TextButton button, SaveSlot slot){ + button.clicked(() -> { + if(button.childrenPressed()) return; - ui.showConfirm("$text.overwrite", "$text.save.overwrite", () -> save(slot)); - }); - } + ui.showConfirm("$text.overwrite", "$text.save.overwrite", () -> save(slot)); + }); + } - void save(SaveSlot slot){ + void save(SaveSlot slot){ - ui.loadfrag.show("$text.saveload"); + ui.loadfrag.show("$text.saveload"); - Timers.runTask(5f, () -> { - hide(); - ui.loadfrag.hide(); - try{ - slot.save(); - }catch(Throwable e){ - e.printStackTrace(); - e = (e.getCause() == null ? e : e.getCause()); + Timers.runTask(5f, () -> { + hide(); + ui.loadfrag.hide(); + try{ + slot.save(); + }catch(Throwable e){ + e.printStackTrace(); + e = (e.getCause() == null ? e : e.getCause()); - ui.showError("[orange]"+Bundles.get("text.savefail")+"\n[white]" + ClassReflection.getSimpleName(e.getClass()) + ": " + e.getMessage() + "\n" + "at " + e.getStackTrace()[0].getFileName() + ":" + e.getStackTrace()[0].getLineNumber()); - } - }); - } + ui.showError("[orange]" + Bundles.get("text.savefail") + "\n[white]" + ClassReflection.getSimpleName(e.getClass()) + ": " + e.getMessage() + "\n" + "at " + e.getStackTrace()[0].getFileName() + ":" + e.getStackTrace()[0].getLineNumber()); + } + }); + } } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java index 72ebfe9ccb..a1fc7bbc3f 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java @@ -24,164 +24,164 @@ import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.*; public class SettingsMenuDialog extends SettingsDialog{ - public SettingsTable graphics; - public SettingsTable game; - public SettingsTable sound; + public SettingsTable graphics; + public SettingsTable game; + public SettingsTable sound; - private Table prefs; - private Table menu; - private boolean wasPaused; - - public SettingsMenuDialog(){ - setStyle(Core.skin.get("dialog", WindowStyle.class)); + private Table prefs; + private Table menu; + private boolean wasPaused; - hidden(() -> { - if(!state.is(State.menu)){ - if(!wasPaused || Net.active()) - state.set(State.playing); - } - }); + public SettingsMenuDialog(){ + setStyle(Core.skin.get("dialog", WindowStyle.class)); - shown(() -> { - if(!state.is(State.menu)){ - wasPaused = state.is(State.paused); - if(ui.paused.getScene() != null){ - wasPaused = ui.paused.wasPaused; - } - if(!Net.active()) state.set(State.paused); - ui.paused.hide(); - } - }); + hidden(() -> { + if(!state.is(State.menu)){ + if(!wasPaused || Net.active()) + state.set(State.playing); + } + }); - setFillParent(true); - title().setAlignment(Align.center); - getTitleTable().row(); - getTitleTable().add(new Image("white")) - .growX().height(3f).pad(4f).get().setColor(Palette.accent); + shown(() -> { + if(!state.is(State.menu)){ + wasPaused = state.is(State.paused); + if(ui.paused.getScene() != null){ + wasPaused = ui.paused.wasPaused; + } + if(!Net.active()) state.set(State.paused); + ui.paused.hide(); + } + }); - content().clearChildren(); - content().remove(); - buttons().remove(); + setFillParent(true); + title().setAlignment(Align.center); + getTitleTable().row(); + getTitleTable().add(new Image("white")) + .growX().height(3f).pad(4f).get().setColor(Palette.accent); - menu = new Table(); + content().clearChildren(); + content().remove(); + buttons().remove(); - Consumer s = table -> { - table.row(); - table.addImageTextButton("$text.back", "icon-arrow-left", 10*3, this::back).size(240f, 60f).colspan(2).padTop(15f); - }; + menu = new Table(); - game = new SettingsTable(s); - graphics = new SettingsTable(s); - sound = new SettingsTable(s); + Consumer s = table -> { + table.row(); + table.addImageTextButton("$text.back", "icon-arrow-left", 10 * 3, this::back).size(240f, 60f).colspan(2).padTop(15f); + }; - prefs = new Table(); - prefs.top(); - prefs.margin(14f); + game = new SettingsTable(s); + graphics = new SettingsTable(s); + sound = new SettingsTable(s); - menu.defaults().size(300f, 60f).pad(3f); - menu.addButton("$text.settings.game", () -> visible(0)); - menu.row(); - menu.addButton("$text.settings.graphics", () -> visible(1)); - menu.row(); - menu.addButton("$text.settings.sound", () -> visible(2)); - if(!Vars.mobile) { - menu.row(); - menu.addButton("$text.settings.controls", ui.controls::show); - } - menu.row(); - menu.addButton("$text.settings.language", ui.language::show); + prefs = new Table(); + prefs.top(); + prefs.margin(14f); - prefs.clearChildren(); - prefs.add(menu); + menu.defaults().size(300f, 60f).pad(3f); + menu.addButton("$text.settings.game", () -> visible(0)); + menu.row(); + menu.addButton("$text.settings.graphics", () -> visible(1)); + menu.row(); + menu.addButton("$text.settings.sound", () -> visible(2)); + if(!Vars.mobile){ + menu.row(); + menu.addButton("$text.settings.controls", ui.controls::show); + } + menu.row(); + menu.addButton("$text.settings.language", ui.language::show); - ScrollPane pane = new ScrollPane(prefs, "clear"); - pane.addCaptureListener(new InputListener() { - @Override - public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) { - Element actor = pane.hit(x, y, true); - if (actor instanceof Slider) { - pane.setFlickScroll(false); - return true; - } + prefs.clearChildren(); + prefs.add(menu); - return super.touchDown(event, x, y, pointer, button); - } + ScrollPane pane = new ScrollPane(prefs, "clear"); + pane.addCaptureListener(new InputListener(){ + @Override + public boolean touchDown(InputEvent event, float x, float y, int pointer, int button){ + Element actor = pane.hit(x, y, true); + if(actor instanceof Slider){ + pane.setFlickScroll(false); + return true; + } - @Override - public void touchUp(InputEvent event, float x, float y, int pointer, int button) { - pane.setFlickScroll(true); - super.touchUp(event, x, y, pointer, button); - } - }); - pane.setFadeScrollBars(false); + return super.touchDown(event, x, y, pointer, button); + } - row(); - add(pane).grow().top(); - row(); - add(buttons()).fillX(); + @Override + public void touchUp(InputEvent event, float x, float y, int pointer, int button){ + pane.setFlickScroll(true); + super.touchUp(event, x, y, pointer, button); + } + }); + pane.setFadeScrollBars(false); - hidden(this::back); + row(); + add(pane).grow().top(); + row(); + add(buttons()).fillX(); - addSettings(); - } + hidden(this::back); - void addSettings(){ - sound.volumePrefs(); + addSettings(); + } - game.screenshakePref(); - //game.checkPref("smoothcam", true); - game.checkPref("effects", true); - //game.sliderPref("sensitivity", 100, 10, 300, i -> i + "%"); - game.sliderPref("saveinterval", 90, 10, 5*120, i -> Bundles.format("setting.seconds", i)); + void addSettings(){ + sound.volumePrefs(); - if(!gwt){ - graphics.checkPref("multithread", true, threads::setEnabled); + game.screenshakePref(); + //game.checkPref("smoothcam", true); + game.checkPref("effects", true); + //game.sliderPref("sensitivity", 100, 10, 300, i -> i + "%"); + game.sliderPref("saveinterval", 90, 10, 5 * 120, i -> Bundles.format("setting.seconds", i)); - if(Settings.getBool("multithread")){ - threads.setEnabled(true); - } - } + if(!gwt){ + graphics.checkPref("multithread", true, threads::setEnabled); - if(!mobile && !gwt) { - graphics.checkPref("vsync", true, b -> Gdx.graphics.setVSync(b)); - graphics.checkPref("fullscreen", false, b -> { - if (b) { - Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode()); - } else { - Gdx.graphics.setWindowedMode(600, 480); - } - }); + if(Settings.getBool("multithread")){ + threads.setEnabled(true); + } + } - Gdx.graphics.setVSync(Settings.getBool("vsync")); - if(Settings.getBool("fullscreen")){ - Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode()); - } - } + if(!mobile && !gwt){ + graphics.checkPref("vsync", true, b -> Gdx.graphics.setVSync(b)); + graphics.checkPref("fullscreen", false, b -> { + if(b){ + Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode()); + }else{ + Gdx.graphics.setWindowedMode(600, 480); + } + }); - graphics.checkPref("fps", false); - graphics.checkPref("lasers", true); - graphics.checkPref("healthbars", true); - graphics.checkPref("minimap", !mobile); //minimap is disabled by default on mobile devices - } + Gdx.graphics.setVSync(Settings.getBool("vsync")); + if(Settings.getBool("fullscreen")){ + Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode()); + } + } - private void back(){ - prefs.clearChildren(); - prefs.add(menu); - } + graphics.checkPref("fps", false); + graphics.checkPref("lasers", true); + graphics.checkPref("healthbars", true); + graphics.checkPref("minimap", !mobile); //minimap is disabled by default on mobile devices + } - private void visible(int index){ - prefs.clearChildren(); - Table table = Mathf.select(index, game, graphics, sound); + private void back(){ + prefs.clearChildren(); + prefs.add(menu); + } + + private void visible(int index){ + prefs.clearChildren(); + Table table = Mathf.select(index, game, graphics, sound); prefs.add(table); - } - - @Override - public void addCloseButton(){ - buttons().addImageTextButton("$text.menu", "icon-arrow-left", 30f, this::hide).size(230f, 64f); - - keyDown(key->{ - if(key == Keys.ESCAPE || key == Keys.BACK) - hide(); - }); - } + } + + @Override + public void addCloseButton(){ + buttons().addImageTextButton("$text.menu", "icon-arrow-left", 30f, this::hide).size(230f, 64f); + + keyDown(key -> { + if(key == Keys.ESCAPE || key == Keys.BACK) + hide(); + }); + } } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/TraceDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/TraceDialog.java index 1874ec157c..39eece4f47 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/TraceDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/TraceDialog.java @@ -5,7 +5,7 @@ import io.anuke.mindustry.net.TraceInfo; import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.util.Bundles; -public class TraceDialog extends FloatingDialog { +public class TraceDialog extends FloatingDialog{ public TraceDialog(){ super("$text.trace"); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/UnlocksDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/UnlocksDialog.java index 87f667e628..7bc8d5e445 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/UnlocksDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/UnlocksDialog.java @@ -15,9 +15,9 @@ import io.anuke.ucore.scene.utils.UIUtils; import static io.anuke.mindustry.Vars.control; -public class UnlocksDialog extends FloatingDialog { +public class UnlocksDialog extends FloatingDialog{ - public UnlocksDialog() { + public UnlocksDialog(){ super("$text.unlocks"); addCloseButton(); @@ -38,7 +38,7 @@ public class UnlocksDialog extends FloatingDialog { Array array = allContent.get(key); if(array.size == 0 || !(array.first() instanceof UnlockableContent)) continue; - table.add("$content." +key + ".name").growX().left().color(Palette.accent); + table.add("$content." + key + ".name").growX().left().color(Palette.accent); table.row(); table.addImage("white").growX().pad(5).padLeft(0).padRight(0).height(3).color(Palette.accent); table.row(); @@ -46,19 +46,19 @@ public class UnlocksDialog extends FloatingDialog { list.left(); int maxWidth = UIUtils.portrait() ? 7 : 13; - int size = 8*6; + int size = 8 * 6; int count = 0; - for (int i = 0; i < array.size; i++) { - UnlockableContent unlock = (UnlockableContent)array.get(i); + for(int i = 0; i < array.size; i++){ + UnlockableContent unlock = (UnlockableContent) array.get(i); if(unlock.isHidden()) continue; Image image = control.database().isUnlocked(unlock) ? new Image(unlock.getContentIcon()) : new Image("icon-locked"); list.add(image).size(size).pad(3); - if(control.database().isUnlocked(unlock)) { + if(control.database().isUnlocked(unlock)){ image.clicked(() -> Vars.ui.content.show(unlock)); image.addListener(new Tooltip<>(new Table("clear"){{ add(unlock.localizedName()); diff --git a/core/src/io/anuke/mindustry/ui/fragments/BackgroundFragment.java b/core/src/io/anuke/mindustry/ui/fragments/BackgroundFragment.java index 793da24841..55c96f856b 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/BackgroundFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/BackgroundFragment.java @@ -10,29 +10,29 @@ import io.anuke.ucore.scene.ui.layout.Unit; import static io.anuke.mindustry.Vars.state; -public class BackgroundFragment extends Fragment { +public class BackgroundFragment extends Fragment{ @Override - public void build(Group parent) { + public void build(Group parent){ Core.scene.table().addRect((a, b, w, h) -> { Draw.color(); TextureRegion back = Draw.region("background"); - float backscl = (int)Math.max(Gdx.graphics.getWidth() / (float)back.getRegionWidth() * 1.5f, Unit.dp.scl(5f)); + float backscl = (int) Math.max(Gdx.graphics.getWidth() / (float) back.getRegionWidth() * 1.5f, Unit.dp.scl(5f)); Draw.alpha(0.5f); - Core.batch.draw(back, w/2 - back.getRegionWidth()*backscl/2, h/2 - back.getRegionHeight()*backscl/2, - back.getRegionWidth()*backscl, back.getRegionHeight()*backscl); + Core.batch.draw(back, w / 2 - back.getRegionWidth() * backscl / 2, h / 2 - back.getRegionHeight() * backscl / 2, + back.getRegionWidth() * backscl, back.getRegionHeight() * backscl); boolean portrait = Gdx.graphics.getWidth() < Gdx.graphics.getHeight(); - float logoscl = (int)Unit.dp.scl(7) * (portrait ? 5f/7f : 1f); + float logoscl = (int) Unit.dp.scl(7) * (portrait ? 5f / 7f : 1f); TextureRegion logo = Core.skin.getRegion("logotext"); - float logow = logo.getRegionWidth()*logoscl; - float logoh = logo.getRegionHeight()*logoscl; + float logow = logo.getRegionWidth() * logoscl; + float logoh = logo.getRegionHeight() * logoscl; Draw.color(); - Core.batch.draw(logo, (int)(w/2 - logow/2), (int)(h - logoh + 15 - Unit.dp.scl(portrait ? 30f : 0)), logow, logoh); + Core.batch.draw(logo, (int) (w / 2 - logow / 2), (int) (h - logoh + 15 - Unit.dp.scl(portrait ? 30f : 0)), logow, logoh); }).visible(() -> state.is(State.menu)).grow(); } } diff --git a/core/src/io/anuke/mindustry/ui/fragments/BlockConfigFragment.java b/core/src/io/anuke/mindustry/ui/fragments/BlockConfigFragment.java index 2ad8787086..b122811e16 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/BlockConfigFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/BlockConfigFragment.java @@ -7,6 +7,7 @@ import com.badlogic.gdx.utils.Align; import io.anuke.mindustry.content.blocks.Blocks; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.input.InputHandler; +import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; import io.anuke.ucore.core.Core; import io.anuke.ucore.core.Graphics; @@ -18,17 +19,18 @@ import io.anuke.ucore.scene.ui.layout.Table; import static io.anuke.mindustry.Vars.state; import static io.anuke.mindustry.Vars.tilesize; -public class BlockConfigFragment extends Fragment { +public class BlockConfigFragment extends Fragment{ private Table table = new Table(); private InputHandler input; private Tile configTile; + private Block configBlock; public BlockConfigFragment(InputHandler input){ this.input = input; } @Override - public void build(Group parent) { + public void build(Group parent){ parent.addChild(table); } @@ -42,6 +44,7 @@ public class BlockConfigFragment extends Fragment { public void showConfig(Tile tile){ configTile = tile; + configBlock = tile.block(); table.setVisible(true); table.clear(); @@ -63,9 +66,9 @@ public class BlockConfigFragment extends Fragment { } table.setOrigin(Align.center); - Vector2 pos = Graphics.screen(tile.drawx(), tile.drawy() - tile.block().size * tilesize/2f - 1); + Vector2 pos = Graphics.screen(tile.drawx(), tile.drawy() - tile.block().size * tilesize / 2f - 1); table.setPosition(pos.x, pos.y, Align.top); - if(configTile == null || configTile.block() == Blocks.air){ + if(configTile == null || configTile.block() == Blocks.air || configTile.block() != configBlock){ hideConfig(); } }); diff --git a/core/src/io/anuke/mindustry/ui/fragments/BlockConsumeFragment.java b/core/src/io/anuke/mindustry/ui/fragments/BlockConsumeFragment.java index 0934f8fb4c..eed5e343aa 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/BlockConsumeFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/BlockConsumeFragment.java @@ -17,12 +17,12 @@ import io.anuke.ucore.scene.ui.layout.Table; import static io.anuke.mindustry.Vars.*; -public class BlockConsumeFragment extends Fragment { +public class BlockConsumeFragment extends Fragment{ private Table table; private boolean visible; @Override - public void build(Group parent) { + public void build(Group parent){ table = new Table(); table.setVisible(() -> !state.is(State.menu) && visible); table.setTransform(true); @@ -68,7 +68,7 @@ public class BlockConsumeFragment extends Fragment { rebuild(block, entity); } - Vector2 v = Graphics.screen(tile.drawx() - tile.block().size * tilesize/2f, tile.drawy() + tile.block().size * tilesize/2f); + Vector2 v = Graphics.screen(tile.drawx() - tile.block().size * tilesize / 2f, tile.drawy() + tile.block().size * tilesize / 2f); table.pack(); table.setPosition(v.x, v.y, Align.topRight); }); @@ -78,7 +78,8 @@ public class BlockConsumeFragment extends Fragment { public void hide(){ table.clear(); - table.update(() -> {}); + table.update(() -> { + }); visible = false; } @@ -97,10 +98,10 @@ public class BlockConsumeFragment extends Fragment { }).get().act(0); Table result = table.table(out -> { - out.addImage(c.getIcon()).size(10*scale).color(Color.DARK_GRAY).padRight(-10*scale).padBottom(-scale*2); - out.addImage(c.getIcon()).size(10*scale).color(Palette.accent); - out.addImage("icon-missing").size(10*scale).color(Palette.remove).padLeft(-10*scale); - }).size(10*scale).get(); + out.addImage(c.getIcon()).size(10 * scale).color(Color.DARK_GRAY).padRight(-10 * scale).padBottom(-scale * 2); + out.addImage(c.getIcon()).size(10 * scale).color(Palette.accent); + out.addImage("icon-missing").size(10 * scale).color(Palette.remove).padLeft(-10 * scale); + }).size(10 * scale).get(); result.hovered(() -> hovered[0] = true); if(!mobile){ diff --git a/core/src/io/anuke/mindustry/ui/fragments/BlockInventoryFragment.java b/core/src/io/anuke/mindustry/ui/fragments/BlockInventoryFragment.java index 2720ad7096..bfc30db2df 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/BlockInventoryFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/BlockInventoryFragment.java @@ -30,7 +30,7 @@ import io.anuke.ucore.util.Strings; import static io.anuke.mindustry.Vars.*; -public class BlockInventoryFragment extends Fragment { +public class BlockInventoryFragment extends Fragment{ private final static float holdWithdraw = 40f; private Table table; @@ -44,8 +44,20 @@ public class BlockInventoryFragment extends Fragment { this.input = input; } + @Remote(called = Loc.server, targets = Loc.both, in = In.blocks, forward = true) + public static void requestItem(Player player, Tile tile, Item item, int amount){ + if(player == null) return; + + int removed = tile.block().removeStack(tile, item, amount); + + player.inventory.addItem(item, removed); + for(int j = 0; j < Mathf.clamp(removed / 3, 1, 8); j++){ + Timers.run(j * 3f, () -> CallEntity.transferItemEffect(item, tile.drawx(), tile.drawy(), player)); + } + } + @Override - public void build(Group parent) { + public void build(Group parent){ table = new Table(); table.setVisible(() -> !state.is(State.menu)); table.setTransform(true); @@ -55,7 +67,8 @@ public class BlockInventoryFragment extends Fragment { public void showFor(Tile t){ this.tile = t.target(); - if(tile == null || tile.entity == null || !tile.block().isAccessible() || tile.entity.items.total() == 0) return; + if(tile == null || tile.entity == null || !tile.block().isAccessible() || tile.entity.items.total() == 0) + return; rebuild(true); } @@ -93,10 +106,10 @@ public class BlockInventoryFragment extends Fragment { } updateTablePosition(); - if(tile.block().hasItems) { - for (int i = 0; i < Item.all().size; i++) { + if(tile.block().hasItems){ + for(int i = 0; i < Item.all().size; i++){ boolean has = tile.entity.items.has(Item.getByID(i)); - if (has != container.contains(i)) { + if(has != container.contains(i)){ rebuild(false); } } @@ -108,13 +121,13 @@ public class BlockInventoryFragment extends Fragment { int row = 0; table.margin(6f); - table.defaults().size(mobile ? 16*3 : 16*2).space(6f); + table.defaults().size(mobile ? 16 * 3 : 16 * 2).space(6f); - if(tile.block().hasItems) { + if(tile.block().hasItems){ - for (int i = 0; i < Item.all().size; i++) { + for(int i = 0; i < Item.all().size; i++){ Item item = Item.getByID(i); - if (!tile.entity.items.has(item)) continue; + if(!tile.entity.items.has(item)) continue; container.add(i); @@ -133,7 +146,7 @@ public class BlockInventoryFragment extends Fragment { image.addListener(new InputListener(){ @Override - public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) { + public boolean touchDown(InputEvent event, float x, float y, int pointer, int button){ if(!canPick.get() || !tile.entity.items.has(item)) return false; int amount = Math.min(1, player.inventory.itemCapacityUsed(item)); CallBlocks.requestItem(player, tile, item, amount); @@ -144,14 +157,14 @@ public class BlockInventoryFragment extends Fragment { } @Override - public void touchUp(InputEvent event, float x, float y, int pointer, int button) { + public void touchUp(InputEvent event, float x, float y, int pointer, int button){ holding = false; lastItem = null; } }); table.add(image); - if (row++ % cols == cols - 1) table.row(); + if(row++ % cols == cols - 1) table.row(); } } @@ -168,29 +181,17 @@ public class BlockInventoryFragment extends Fragment { } private String round(float f){ - f = (int)f; + f = (int) f; if(f >= 1000){ - return Strings.toFixed(f/1000, 1) + "k"; + return Strings.toFixed(f / 1000, 1) + "k"; }else{ - return (int)f+""; + return (int) f + ""; } } private void updateTablePosition(){ - Vector2 v = Graphics.screen(tile.drawx() + tile.block().size * tilesize/2f, tile.drawy() + tile.block().size * tilesize/2f); + Vector2 v = Graphics.screen(tile.drawx() + tile.block().size * tilesize / 2f, tile.drawy() + tile.block().size * tilesize / 2f); table.pack(); table.setPosition(v.x, v.y, Align.topLeft); } - - @Remote(called = Loc.server, targets = Loc.both, in = In.blocks, forward = true) - public static void requestItem(Player player, Tile tile, Item item, int amount){ - if(player == null) return; - - int removed = tile.block().removeStack(tile, item, amount); - - player.inventory.addItem(item, removed); - for(int j = 0; j < Mathf.clamp(removed/3, 1, 8); j ++){ - Timers.run(j*3f, () -> CallEntity.transferItemEffect(item, tile.drawx(), tile.drawy(), player)); - } - } } diff --git a/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java b/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java index 673ac7c2aa..a6949bcdf6 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java @@ -29,327 +29,344 @@ import io.anuke.ucore.util.Strings; import static io.anuke.mindustry.Vars.*; public class BlocksFragment extends Fragment{ - /**Table containing description that is shown on top.*/ - private Table descTable; - /**Main table containing the whole menu.*/ - private Table mainTable; - /**Table for all section buttons and blocks.*/ - private Table selectTable; - /**Whether the whole thing is shown or hidden by the popup button.*/ - private boolean shown = true; - /**Recipe currently hovering over.*/ - private Recipe hoverRecipe; - /**Last category selected.*/ - private Category lastCategory; - /**Last block pane scroll Y position.*/ - private float lastScroll; - /**Temporary recipe array for storage*/ - private Array recipes = new Array<>(); - - //number of block icon rows - private static final int rows = 4; - //number of category button rows - private static final int secrows = 4; - //size of each block icon - private static final float size = 48; - //maximum recipe rows - private static final int maxrow = 3; - - public void build(Group parent){ - InputHandler input = control.input(0); - - //create container table - new table(){{ - abottom(); - aright(); - - //make it only be shown when needed. - visible(() -> !state.is(State.menu)); - - //create the main blocks table - mainTable = new table(){{ - - //add top description table - descTable = new Table("button"); - descTable.setVisible(() -> hoverRecipe != null || input.recipe != null); //make sure it's visible when necessary - descTable.update(() -> { - // note: This is required because there is no direct connection between - // input.recipe and the description ui. If input.recipe gets set to null - // a proper cleanup of the ui elements is required. - boolean anyRecipeShown = input.recipe != null || hoverRecipe != null; - boolean descriptionTableClean = descTable.getChildren().size == 0; - boolean cleanupRequired = !anyRecipeShown && !descriptionTableClean; - if(cleanupRequired){ - descTable.clear(); - } - }); - - add(descTable).fillX().uniformX(); - - row(); - - //now add the block selection menu - selectTable = new table("pane") {{ - touchable(Touchable.enabled); - - margin(10f); - marginLeft(0f); - marginRight(0f); - marginTop(-5); - - }}.right().bottom().end().get(); - - visible(() -> !state.is(State.menu)); - - }}.end().get(); - - }}.end(); - - rebuild(); - } - - /**Rebuilds the whole placement menu, attempting to preserve previous state.*/ - void rebuild(){ - selectTable.clear(); - - InputHandler input = control.input(0); - Stack stack = new Stack(); - ButtonGroup group = new ButtonGroup<>(); - Table catTable = selectTable; - - int cati = 0; - int checkedi = 0; - int rowsUsed = 0; - - //add categories - for (Category cat : Category.values()) { - //get recipes out by category - Recipe.getUnlockedByCategory(cat, recipes); - - //empty section, nothing to see here - if(recipes.size == 0){ - continue; - } - - //table where actual recipes go - Table recipeTable = new Table(); - recipeTable.margin(4).top().left().marginRight(15); - - //add a new row here when needed - if (cati == secrows) { - catTable = new Table(); - selectTable.row(); - selectTable.add(catTable).colspan(secrows).padTop(-5).growX(); - } - - //add category button - ImageButton catb = catTable.addImageButton( "icon-" + cat.name(), "toggle", 40, () -> { - if (!recipeTable.isVisible() && input.recipe != null) { - input.recipe = null; - } - lastCategory = cat; - stack.act(Gdx.graphics.getDeltaTime()); - stack.act(Gdx.graphics.getDeltaTime()); - }).growX().height(54).group(group) - .name("sectionbutton" + cat.name()).get(); - - if(lastCategory == cat || lastCategory == null){ - checkedi = cati; - lastCategory = cat; - } - - //scrollpane for recipes - ScrollPane pane = new ScrollPane(recipeTable, "clear-black"); - pane.setOverscroll(false, false); - pane.setVisible(catb::isChecked); - pane.setScrollYForce(lastScroll); - pane.update(() -> { - Element e = Core.scene.hit(Graphics.mouse().x, Graphics.mouse().y, true); - if(e != null && e.isDescendantOf(pane)){ - Core.scene.setScrollFocus(pane); - }else if(Core.scene.getScrollFocus() == pane){ - Core.scene.setScrollFocus(null); - } - - if(lastCategory == cat){ - lastScroll = pane.getVisualScrollY(); - } - }); - stack.add(pane); - - int i = 0; - - //add actual recipes - for (Recipe r : recipes) { - if((r.debugOnly && !debug) || (r.desktopOnly && mobile)) continue; - - ImageButton image = new ImageButton(new TextureRegion(), "select"); - - TextureRegion[] regions = r.result.getCompactIcon(); - Stack istack = new Stack(); - for(TextureRegion region : regions){ - Image u = new Image(region); - u.update(() -> u.setColor(istack.getColor())); - istack.add(u); - } - - image.getImageCell().setActor(istack).size(size); - image.addChild(istack); - image.setTouchable(Touchable.enabled); - image.getImage().remove(); - - image.addListener(new ClickListener(){ - @Override - public void enter(InputEvent event, float x, float y, int pointer, Element fromActor) { - super.enter(event, x, y, pointer, fromActor); - if (hoverRecipe != r) { - hoverRecipe = r; - updateRecipe(r); - } - } - - @Override - public void exit(InputEvent event, float x, float y, int pointer, Element toActor) { - super.exit(event, x, y, pointer, toActor); - hoverRecipe = null; - updateRecipe(input.recipe); - } - }); - - image.clicked(() -> { - // note: input.recipe only gets set here during a click. - // during a hover only the visual description will be updated. - InputHandler handler = mobile ? input : control.input(0); - - boolean nothingSelectedYet = handler.recipe == null; - boolean selectedSomethingElse = !nothingSelectedYet && handler.recipe != r; - boolean shouldMakeSelection = nothingSelectedYet || selectedSomethingElse; - if (shouldMakeSelection) { - handler.recipe = r; - hoverRecipe = r; - updateRecipe(r); - } else { - handler.recipe = null; - hoverRecipe = null; - updateRecipe(null); - } - }); - - recipeTable.add(image).size(size + 8); - - image.update(() -> { - image.setChecked(r == control.input(0).recipe); - TileEntity entity = players[0].getClosestCore(); - - if(entity == null) return; - - for(ItemStack s : r.requirements){ - if(!entity.items.has(s.item, Mathf.ceil(s.amount))){ - istack.setColor(Color.GRAY); - return; - } - } - istack.setColor(Color.WHITE); - }); - - if (i % rows == rows - 1) { - rowsUsed = Math.max((i+1)/rows, rowsUsed); - recipeTable.row(); - } - - i++; - } - - cati ++; - } - - if(group.getButtons().size > 0){ - group.getButtons().get(checkedi).setChecked(true); - } - - selectTable.row(); - selectTable.add(stack).growX().left().top().colspan(Category.values().length).padBottom(-5).height((size + 12)*rowsUsed); - } - - void toggle(boolean show, float t, Interpolation ip){ - if(shown){ - shown = false; - mainTable.actions(Actions.translateBy(0, mainTable.getTranslation().y + (-mainTable.getHeight() - descTable.getHeight()), t, ip)); - }else{ - shown = true; - mainTable.actions(Actions.translateBy(0, -mainTable.getTranslation().y, t, ip)); - } - } - - private void updateRecipe(Recipe recipe){ - if (recipe == null) { - descTable.clear(); - return; - } - - descTable.clear(); - descTable.setTouchable(Touchable.enabled); - - descTable.defaults().left(); - descTable.left(); - descTable.margin(12); - - Table header = new Table(); - - descTable.add(header).left(); - - descTable.row(); - - TextureRegion[] regions = recipe.result.getCompactIcon(); - - Stack istack = new Stack(); - - for(TextureRegion region : regions) istack.add(new Image(region)); - - header.add(istack).size(8*5).padTop(4); - Label nameLabel = new Label(recipe.result.formalName); - nameLabel.setWrap(true); - header.add(nameLabel).padLeft(2).width(120f); - - header.addButton("?", () -> ui.content.show(recipe)).expandX().padLeft(3).top().right().size(40f, 44f).padTop(-2); - - descTable.add().pad(2); - - Table requirements = new Table(); - - descTable.row(); - - descTable.add(requirements); - descTable.left(); - - for(ItemStack stack : recipe.requirements){ - requirements.addImage(stack.item.region).size(8*3); - Label reqlabel = new Label(() ->{ - TileEntity core = players[0].getClosestCore(); - if(core == null) return "*/*"; + //number of block icon rows + private static final int rows = 4; + //number of category button rows + private static final int secrows = 4; + //size of each block icon + private static final float size = 48; + //maximum recipe rows + private static final int maxrow = 3; + /** + * Table containing description that is shown on top. + */ + private Table descTable; + /** + * Main table containing the whole menu. + */ + private Table mainTable; + /** + * Table for all section buttons and blocks. + */ + private Table selectTable; + /** + * Whether the whole thing is shown or hidden by the popup button. + */ + private boolean shown = true; + /** + * Recipe currently hovering over. + */ + private Recipe hoverRecipe; + /** + * Last category selected. + */ + private Category lastCategory; + /** + * Last block pane scroll Y position. + */ + private float lastScroll; + /** + * Temporary recipe array for storage + */ + private Array recipes = new Array<>(); + + public void build(Group parent){ + InputHandler input = control.input(0); + + //create container table + new table(){{ + abottom(); + aright(); + + //make it only be shown when needed. + visible(() -> !state.is(State.menu)); + + //create the main blocks table + mainTable = new table(){{ + + //add top description table + descTable = new Table("button"); + descTable.setVisible(() -> hoverRecipe != null || input.recipe != null); //make sure it's visible when necessary + descTable.update(() -> { + // note: This is required because there is no direct connection between + // input.recipe and the description ui. If input.recipe gets set to null + // a proper cleanup of the ui elements is required. + boolean anyRecipeShown = input.recipe != null || hoverRecipe != null; + boolean descriptionTableClean = descTable.getChildren().size == 0; + boolean cleanupRequired = !anyRecipeShown && !descriptionTableClean; + if(cleanupRequired){ + descTable.clear(); + } + }); + + add(descTable).fillX().uniformX(); + + row(); + + //now add the block selection menu + selectTable = new table("pane"){{ + touchable(Touchable.enabled); + + margin(10f); + marginLeft(0f); + marginRight(0f); + marginTop(-5); + + }}.right().bottom().end().get(); + + visible(() -> !state.is(State.menu)); + + }}.end().get(); + + }}.end(); + + rebuild(); + } + + /** + * Rebuilds the whole placement menu, attempting to preserve previous state. + */ + void rebuild(){ + selectTable.clear(); + + InputHandler input = control.input(0); + Stack stack = new Stack(); + ButtonGroup group = new ButtonGroup<>(); + Table catTable = selectTable; + + int cati = 0; + int checkedi = 0; + int rowsUsed = 0; + + //add categories + for(Category cat : Category.values()){ + //get recipes out by category + Recipe.getUnlockedByCategory(cat, recipes); + + //empty section, nothing to see here + if(recipes.size == 0){ + continue; + } + + //table where actual recipes go + Table recipeTable = new Table(); + recipeTable.margin(4).top().left().marginRight(15); + + //add a new row here when needed + if(cati == secrows){ + catTable = new Table(); + selectTable.row(); + selectTable.add(catTable).colspan(secrows).padTop(-5).growX(); + } + + //add category button + ImageButton catb = catTable.addImageButton("icon-" + cat.name(), "toggle", 40, () -> { + if(!recipeTable.isVisible() && input.recipe != null){ + input.recipe = null; + } + lastCategory = cat; + stack.act(Gdx.graphics.getDeltaTime()); + stack.act(Gdx.graphics.getDeltaTime()); + }).growX().height(54).group(group) + .name("sectionbutton" + cat.name()).get(); + + if(lastCategory == cat || lastCategory == null){ + checkedi = cati; + lastCategory = cat; + } + + //scrollpane for recipes + ScrollPane pane = new ScrollPane(recipeTable, "clear-black"); + pane.setOverscroll(false, false); + pane.setVisible(catb::isChecked); + pane.setScrollYForce(lastScroll); + pane.update(() -> { + Element e = Core.scene.hit(Graphics.mouse().x, Graphics.mouse().y, true); + if(e != null && e.isDescendantOf(pane)){ + Core.scene.setScrollFocus(pane); + }else if(Core.scene.getScrollFocus() == pane){ + Core.scene.setScrollFocus(null); + } + + if(lastCategory == cat){ + lastScroll = pane.getVisualScrollY(); + } + }); + stack.add(pane); + + int i = 0; + + //add actual recipes + for(Recipe r : recipes){ + if((r.debugOnly && !debug) || (r.desktopOnly && mobile)) continue; + + ImageButton image = new ImageButton(new TextureRegion(), "select"); + + TextureRegion[] regions = r.result.getCompactIcon(); + Stack istack = new Stack(); + for(TextureRegion region : regions){ + Image u = new Image(region); + u.update(() -> u.setColor(istack.getColor())); + istack.add(u); + } + + image.getImageCell().setActor(istack).size(size); + image.addChild(istack); + image.setTouchable(Touchable.enabled); + image.getImage().remove(); + + image.addListener(new ClickListener(){ + @Override + public void enter(InputEvent event, float x, float y, int pointer, Element fromActor){ + super.enter(event, x, y, pointer, fromActor); + if(hoverRecipe != r){ + hoverRecipe = r; + updateRecipe(r); + } + } + + @Override + public void exit(InputEvent event, float x, float y, int pointer, Element toActor){ + super.exit(event, x, y, pointer, toActor); + hoverRecipe = null; + updateRecipe(input.recipe); + } + }); + + image.clicked(() -> { + // note: input.recipe only gets set here during a click. + // during a hover only the visual description will be updated. + InputHandler handler = mobile ? input : control.input(0); + + boolean nothingSelectedYet = handler.recipe == null; + boolean selectedSomethingElse = !nothingSelectedYet && handler.recipe != r; + boolean shouldMakeSelection = nothingSelectedYet || selectedSomethingElse; + if(shouldMakeSelection){ + handler.recipe = r; + hoverRecipe = r; + updateRecipe(r); + }else{ + handler.recipe = null; + hoverRecipe = null; + updateRecipe(null); + } + }); + + recipeTable.add(image).size(size + 8); + + image.update(() -> { + image.setChecked(r == control.input(0).recipe); + TileEntity entity = players[0].getClosestCore(); + + if(entity == null) return; + + for(ItemStack s : r.requirements){ + if(!entity.items.has(s.item, Mathf.ceil(s.amount))){ + istack.setColor(Color.GRAY); + return; + } + } + istack.setColor(Color.WHITE); + }); + + if(i % rows == rows - 1){ + rowsUsed = Math.max((i + 1) / rows, rowsUsed); + recipeTable.row(); + } + + i++; + } + + cati++; + } + + if(group.getButtons().size > 0){ + group.getButtons().get(checkedi).setChecked(true); + } + + selectTable.row(); + selectTable.add(stack).growX().left().top().colspan(Category.values().length).padBottom(-5).height((size + 12) * rowsUsed); + } + + void toggle(boolean show, float t, Interpolation ip){ + if(shown){ + shown = false; + mainTable.actions(Actions.translateBy(0, mainTable.getTranslation().y + (-mainTable.getHeight() - descTable.getHeight()), t, ip)); + }else{ + shown = true; + mainTable.actions(Actions.translateBy(0, -mainTable.getTranslation().y, t, ip)); + } + } + + private void updateRecipe(Recipe recipe){ + if(recipe == null){ + descTable.clear(); + return; + } + + descTable.clear(); + descTable.setTouchable(Touchable.enabled); + + descTable.defaults().left(); + descTable.left(); + descTable.margin(12); + + Table header = new Table(); + + descTable.add(header).left(); + + descTable.row(); + + TextureRegion[] regions = recipe.result.getCompactIcon(); + + Stack istack = new Stack(); + + for(TextureRegion region : regions) istack.add(new Image(region)); + + header.add(istack).size(8 * 5).padTop(4); + Label nameLabel = new Label(recipe.result.formalName); + nameLabel.setWrap(true); + header.add(nameLabel).padLeft(2).width(120f); + + header.addButton("?", () -> ui.content.show(recipe)).expandX().padLeft(3).top().right().size(40f, 44f).padTop(-2); + + descTable.add().pad(2); + + Table requirements = new Table(); + + descTable.row(); + + descTable.add(requirements); + descTable.left(); + + for(ItemStack stack : recipe.requirements){ + requirements.addImage(stack.item.region).size(8 * 3); + Label reqlabel = new Label(() -> { + TileEntity core = players[0].getClosestCore(); + if(core == null) return "*/*"; - int amount = core.items.get(stack.item); - String color = (amount < stack.amount/2f ? "[red]" : amount < stack.amount ? "[orange]" : "[white]"); + int amount = core.items.get(stack.item); + String color = (amount < stack.amount / 2f ? "[red]" : amount < stack.amount ? "[orange]" : "[white]"); - return color + format(amount) + "[white]/" + stack.amount; - }); + return color + format(amount) + "[white]/" + stack.amount; + }); - requirements.add(reqlabel).left(); - requirements.row(); - } + requirements.add(reqlabel).left(); + requirements.row(); + } - descTable.row(); - } + descTable.row(); + } - String format(int number){ - if(number >= 1000000) { - return Strings.toFixed(number/1000000f, 1) + "[gray]mil[]"; - }else if(number >= 10000){ - return number/1000 + "[gray]k[]"; - }else if(number >= 1000){ - return Strings.toFixed(number/1000f, 1) + "[gray]k[]"; - }else{ - return number + ""; - } - } + String format(int number){ + if(number >= 1000000){ + return Strings.toFixed(number / 1000000f, 1) + "[gray]mil[]"; + }else if(number >= 10000){ + return number / 1000 + "[gray]k[]"; + }else if(number >= 1000){ + return Strings.toFixed(number / 1000f, 1) + "[gray]k[]"; + }else{ + return number + ""; + } + } } \ No newline at end of file diff --git a/core/src/io/anuke/mindustry/ui/fragments/ChatFragment.java b/core/src/io/anuke/mindustry/ui/fragments/ChatFragment.java index 153ed15ea5..82d67556ed 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/ChatFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/ChatFragment.java @@ -43,9 +43,9 @@ public class ChatFragment extends Table{ private Array history = new Array<>(); private int historyPos = 0; private int scrollPos = 0; - private Fragment container = new Fragment() { + private Fragment container = new Fragment(){ @Override - public void build(Group parent) { + public void build(Group parent){ scene.add(ChatFragment.this); } }; @@ -67,17 +67,17 @@ public class ChatFragment extends Table{ toggle(); } - if (chatOpen) { - if (Inputs.keyTap("chat_history_prev") && historyPos < history.size - 1) { - if (historyPos == 0) history.set(0, chatfield.getText()); + if(chatOpen){ + if(Inputs.keyTap("chat_history_prev") && historyPos < history.size - 1){ + if(historyPos == 0) history.set(0, chatfield.getText()); historyPos++; updateChat(); } - if (Inputs.keyTap("chat_history_next") && historyPos > 0) { + if(Inputs.keyTap("chat_history_next") && historyPos > 0){ historyPos--; updateChat(); } - scrollPos = (int)Mathf.clamp(scrollPos + Inputs.getAxis("chat_scroll"), 0, Math.max(0, messages.size - messagesShown)); + scrollPos = (int) Mathf.clamp(scrollPos + Inputs.getAxis("chat_scroll"), 0, Math.max(0, messages.size - messagesShown)); } }); @@ -85,7 +85,7 @@ public class ChatFragment extends Table{ setup(); } - public Fragment container() { + public Fragment container(){ return container; } @@ -108,16 +108,16 @@ public class ChatFragment extends Table{ chatfield.setStyle(chatfield.getStyle()); Platform.instance.addDialog(chatfield, Vars.maxTextLength); - bottom().left().marginBottom(offsety).marginLeft(offsetx*2).add(fieldlabel).padBottom(4f); + bottom().left().marginBottom(offsety).marginLeft(offsetx * 2).add(fieldlabel).padBottom(4f); add(chatfield).padBottom(offsety).padLeft(offsetx).growX().padRight(offsetx).height(28); - if(Vars.mobile) { + if(Vars.mobile){ marginBottom(105f); marginRight(240f); } - if(Vars.mobile) { + if(Vars.mobile){ addImageButton("icon-arrow-right", 14 * 2, this::toggle).size(46f, 51f).visible(() -> chatOpen).pad(2f); } } @@ -128,7 +128,7 @@ public class ChatFragment extends Table{ batch.setColor(shadowColor); if(chatOpen) - batch.draw(skin.getRegion("white"), offsetx, chatfield.getY(), chatfield.getWidth() + 15f, chatfield.getHeight()-1); + batch.draw(skin.getRegion("white"), offsetx, chatfield.getY(), chatfield.getWidth() + 15f, chatfield.getHeight() - 1); super.draw(batch, alpha); @@ -143,18 +143,18 @@ public class ChatFragment extends Table{ for(int i = scrollPos; i < messages.size && i < messagesShown + scrollPos && (i < fadetime || chatOpen); i++){ layout.setText(font, messages.get(i).formattedMessage, Color.WHITE, textWidth, Align.bottomLeft, true); - theight += layout.height+textspacing; - if(i - scrollPos == 0) theight -= textspacing+1; + theight += layout.height + textspacing; + if(i - scrollPos == 0) theight -= textspacing + 1; font.getCache().clear(); font.getCache().addText(messages.get(i).formattedMessage, fontoffsetx + offsetx, offsety + theight, textWidth, Align.bottomLeft, true); - if(!chatOpen && fadetime-i < 1f && fadetime-i >= 0f){ - font.getCache().setAlphas(fadetime-i); - batch.setColor(0, 0, 0, shadowColor.a*(fadetime-i)); + if(!chatOpen && fadetime - i < 1f && fadetime - i >= 0f){ + font.getCache().setAlphas(fadetime - i); + batch.setColor(0, 0, 0, shadowColor.a * (fadetime - i)); } - batch.draw(skin.getRegion("white"), offsetx, theight-layout.height-2, textWidth + Unit.dp.scl(4f), layout.height+textspacing); + batch.draw(skin.getRegion("white"), offsetx, theight - layout.height - 2, textWidth + Unit.dp.scl(4f), layout.height + textspacing); batch.setColor(shadowColor); font.getCache().draw(batch); @@ -163,7 +163,7 @@ public class ChatFragment extends Table{ batch.setColor(Color.WHITE); if(fadetime > 0 && !chatOpen) - fadetime -= Timers.delta()/180f; + fadetime -= Timers.delta() / 180f; } private void sendMessage(){ @@ -197,12 +197,12 @@ public class ChatFragment extends Table{ clearChatInput(); } - public void updateChat() { + public void updateChat(){ chatfield.setText(history.get(historyPos)); chatfield.setCursorPosition(chatfield.getText().length()); } - public void clearChatInput() { + public void clearChatInput(){ historyPos = 0; history.set(0, ""); chatfield.setText(""); @@ -234,7 +234,7 @@ public class ChatFragment extends Table{ if(sender == null){ //no sender, this is a server message? formattedMessage = message; }else{ - formattedMessage = "[CORAL][["+sender+"[CORAL]]:[WHITE] "+message; + formattedMessage = "[CORAL][[" + sender + "[CORAL]]:[WHITE] " + message; } } } diff --git a/core/src/io/anuke/mindustry/ui/fragments/DebugFragment.java b/core/src/io/anuke/mindustry/ui/fragments/DebugFragment.java index 8b2b6338ca..0ec1779737 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/DebugFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/DebugFragment.java @@ -27,7 +27,7 @@ import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.*; -public class DebugFragment extends Fragment { +public class DebugFragment extends Fragment{ private static StringBuilder log = new StringBuilder(); static{ @@ -35,7 +35,7 @@ public class DebugFragment extends Fragment { @Override public void print(String text, Object... args){ super.print(text, args); - if(log.length() < 1000) { + if(log.length() < 1000){ log.append(Log.format(text, args)); log.append("\n"); } @@ -43,109 +43,6 @@ public class DebugFragment extends Fragment { }); } - @Override - public void build(Group parent){ - - Player player = players[0]; - new table(){{ - visible(() -> debug); - - abottom().aleft(); - - new table("pane"){{ - defaults().fillX().width(100f); - - new label(() -> Gdx.app.getJavaHeap() / 1024 / 1024 + "MB"); - row(); - - new label("Debug"); - row(); - new button("noclip", "toggle", () -> noclip = !noclip); - row(); - new button("items", () -> { - for (int i = 0; i < 10; i++) { - ItemDrop.create(Item.all().random(), 5, player.x, player.y, Mathf.random(360f)); - } - }); - row(); - new button("team", "toggle", player::toggleTeam); - row(); - new button("blocks", "toggle", () -> showBlockDebug = !showBlockDebug); - row(); - new button("fog", () -> showFog = !showFog); - row(); - new button("gameover", () ->{ - state.teams.get(Team.blue).cores.get(0).entity.health = 0; - state.teams.get(Team.blue).cores.get(0).entity.damage(1); - }); - row(); - new button("wave", () -> state.wavetime = 0f); - row(); - new button("death", () -> player.damage(99999, true)); - row(); - new button("spawn", () -> { - FloatingDialog dialog = new FloatingDialog("debug spawn"); - for(UnitType type : UnitType.all()){ - dialog.content().addImageButton("white", 40, () -> { - BaseUnit unit = type.create(player.getTeam()); - unit.inventory.addAmmo(type.weapon.getAmmoType(type.weapon.getAcceptedItems().iterator().next())); - unit.setWave(); - unit.set(player.x, player.y); - unit.add(); - }).get().getStyle().imageUp = new TextureRegionDrawable(type.iconRegion); - } - dialog.addCloseButton(); - dialog.setFillParent(false); - dialog.show(); - }); - row(); - }}.end(); - - row(); - - }}.end(); - - - new table(){{ - visible(() -> console); - - atop().aleft(); - - new table("pane") {{ - defaults().fillX(); - - ScrollPane pane = new ScrollPane(new Label(DebugFragment::debugInfo), "clear"); - - add(pane); - row(); - new button("dump", () -> { - try{ - FileHandle file = Gdx.files.local("packet-dump.txt"); - file.writeString("--INFO--\n", false); - file.writeString(debugInfo(), true); - file.writeString("--LOG--\n\n", true); - file.writeString(log.toString(), true); - }catch (Exception e){ - ui.showError("Error dumping log."); - } - }); - }}.end(); - }}.end(); - - new table(){{ - visible(() -> console); - - atop(); - - Table table = new Table("pane"); - table.label(() -> log.toString()); - - ScrollPane pane = new ScrollPane(table, "clear"); - - get().add(pane); - }}.end(); - } - public static void printDebugInfo(){ Gdx.app.error("Minudstry Info Dump", debugInfo()); } @@ -166,9 +63,9 @@ public class DebugFragment extends Fragment { "units: " + totalUnits, "bullets: " + bulletGroup.size(), Net.client() ? - "chat.open: " + ui.chatfrag.chatOpen() + "\n" + - "chat.messages: " + ui.chatfrag.getMessagesSize() + "\n" + - "client.connecting: " + netClient.isConnecting() + "\n" : "", + "chat.open: " + ui.chatfrag.chatOpen() + "\n" + + "chat.messages: " + ui.chatfrag.getMessagesSize() + "\n" + + "client.connecting: " + netClient.isConnecting() + "\n" : "", "players: " + playerGroup.size(), "tiles: " + tileGroup.size(), "tiles.sleeping: " + TileEntity.sleepingEntities, @@ -212,10 +109,113 @@ public class DebugFragment extends Fragment { private static StringBuilder join(String... strings){ StringBuilder builder = new StringBuilder(); - for (String string : strings) { + for(String string : strings){ builder.append(string); builder.append("\n"); } return builder; } + + @Override + public void build(Group parent){ + + Player player = players[0]; + new table(){{ + visible(() -> debug); + + abottom().aleft(); + + new table("pane"){{ + defaults().fillX().width(100f); + + new label(() -> Gdx.app.getJavaHeap() / 1024 / 1024 + "MB"); + row(); + + new label("Debug"); + row(); + new button("noclip", "toggle", () -> noclip = !noclip); + row(); + new button("items", () -> { + for(int i = 0; i < 10; i++){ + ItemDrop.create(Item.all().random(), 5, player.x, player.y, Mathf.random(360f)); + } + }); + row(); + new button("team", "toggle", player::toggleTeam); + row(); + new button("blocks", "toggle", () -> showBlockDebug = !showBlockDebug); + row(); + new button("fog", () -> showFog = !showFog); + row(); + new button("gameover", () -> { + state.teams.get(Team.blue).cores.get(0).entity.health = 0; + state.teams.get(Team.blue).cores.get(0).entity.damage(1); + }); + row(); + new button("wave", () -> state.wavetime = 0f); + row(); + new button("death", () -> player.damage(99999, true)); + row(); + new button("spawn", () -> { + FloatingDialog dialog = new FloatingDialog("debug spawn"); + for(UnitType type : UnitType.all()){ + dialog.content().addImageButton("white", 40, () -> { + BaseUnit unit = type.create(player.getTeam()); + unit.inventory.addAmmo(type.weapon.getAmmoType(type.weapon.getAcceptedItems().iterator().next())); + unit.setWave(); + unit.set(player.x, player.y); + unit.add(); + }).get().getStyle().imageUp = new TextureRegionDrawable(type.iconRegion); + } + dialog.addCloseButton(); + dialog.setFillParent(false); + dialog.show(); + }); + row(); + }}.end(); + + row(); + + }}.end(); + + + new table(){{ + visible(() -> console); + + atop().aleft(); + + new table("pane"){{ + defaults().fillX(); + + ScrollPane pane = new ScrollPane(new Label(DebugFragment::debugInfo), "clear"); + + add(pane); + row(); + new button("dump", () -> { + try{ + FileHandle file = Gdx.files.local("packet-dump.txt"); + file.writeString("--INFO--\n", false); + file.writeString(debugInfo(), true); + file.writeString("--LOG--\n\n", true); + file.writeString(log.toString(), true); + }catch(Exception e){ + ui.showError("Error dumping log."); + } + }); + }}.end(); + }}.end(); + + new table(){{ + visible(() -> console); + + atop(); + + Table table = new Table("pane"); + table.label(() -> log.toString()); + + ScrollPane pane = new ScrollPane(table, "clear"); + + get().add(pane); + }}.end(); + } } diff --git a/core/src/io/anuke/mindustry/ui/fragments/Fragment.java b/core/src/io/anuke/mindustry/ui/fragments/Fragment.java index f28b87f8dc..080c2c4a05 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/Fragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/Fragment.java @@ -3,5 +3,5 @@ package io.anuke.mindustry.ui.fragments; import io.anuke.ucore.scene.Group; public abstract class Fragment{ - public abstract void build(Group parent); + public abstract void build(Group parent); } diff --git a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java index 8fb5334a82..f0980dac14 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java @@ -34,316 +34,318 @@ import io.anuke.ucore.util.Bundles; import static io.anuke.mindustry.Vars.*; public class HudFragment extends Fragment{ - public final BlocksFragment blockfrag = new BlocksFragment(); + public final BlocksFragment blockfrag = new BlocksFragment(); - private ImageButton menu, flip; - private Table respawntable; - private Table wavetable; - private Table infolabel; - private Table lastUnlockTable; - private Table lastUnlockLayout; - private boolean shown = true; - private float dsize = 58; - private float isize = 40; + private ImageButton menu, flip; + private Table respawntable; + private Table wavetable; + private Table infolabel; + private Table lastUnlockTable; + private Table lastUnlockLayout; + private boolean shown = true; + private float dsize = 58; + private float isize = 40; - public void build(Group parent){ + public void build(Group parent){ - //menu at top left - new table(){{ - atop(); - aleft(); + //menu at top left + new table(){{ + atop(); + aleft(); - new table(){{ + new table(){{ - new table() {{ - left(); - defaults().size(dsize).left(); + new table(){{ + left(); + defaults().size(dsize).left(); - menu = new imagebutton("icon-menu", isize, ui.paused::show).get(); - flip = new imagebutton("icon-arrow-up", isize, () -> toggleMenus()).get(); + menu = new imagebutton("icon-menu", isize, ui.paused::show).get(); + flip = new imagebutton("icon-arrow-up", isize, () -> toggleMenus()).get(); - update(t -> { - if(Inputs.keyTap("toggle_menus") && !ui.chatfrag.chatOpen()){ - toggleMenus(); - } - }); + update(t -> { + if(Inputs.keyTap("toggle_menus") && !ui.chatfrag.chatOpen()){ + toggleMenus(); + } + }); - new imagebutton("icon-pause", isize, () -> { - if (Net.active()) { - ui.listfrag.toggle(); - } else { - state.set(state.is(State.paused) ? State.playing : State.paused); - } - }).update(i -> { - if (Net.active()) { - i.getStyle().imageUp = Core.skin.getDrawable("icon-players"); - } else { - i.setDisabled(Net.active()); - i.getStyle().imageUp = Core.skin.getDrawable(state.is(State.paused) ? "icon-play" : "icon-pause"); - } - }).get(); + new imagebutton("icon-pause", isize, () -> { + if(Net.active()){ + ui.listfrag.toggle(); + }else{ + state.set(state.is(State.paused) ? State.playing : State.paused); + } + }).update(i -> { + if(Net.active()){ + i.getStyle().imageUp = Core.skin.getDrawable("icon-players"); + }else{ + i.setDisabled(Net.active()); + i.getStyle().imageUp = Core.skin.getDrawable(state.is(State.paused) ? "icon-play" : "icon-pause"); + } + }).get(); - new imagebutton("icon-settings", isize, () -> { - if (Net.active() && mobile) { - if (ui.chatfrag.chatOpen()) { - ui.chatfrag.hide(); - } else { - ui.chatfrag.toggle(); - } - } else { - ui.settings.show(); - } - }).update(i -> { - if (Net.active() && mobile) { - i.getStyle().imageUp = Core.skin.getDrawable("icon-chat"); - } else { - i.getStyle().imageUp = Core.skin.getDrawable("icon-settings"); - } - }).get(); + new imagebutton("icon-settings", isize, () -> { + if(Net.active() && mobile){ + if(ui.chatfrag.chatOpen()){ + ui.chatfrag.hide(); + }else{ + ui.chatfrag.toggle(); + } + }else{ + ui.settings.show(); + } + }).update(i -> { + if(Net.active() && mobile){ + i.getStyle().imageUp = Core.skin.getDrawable("icon-chat"); + }else{ + i.getStyle().imageUp = Core.skin.getDrawable("icon-settings"); + } + }).get(); - }}.end(); + }}.end(); - row(); + row(); - new table() {{ - touchable(Touchable.enabled); - addWaveTable(); - }}.fillX().end(); + new table(){{ + touchable(Touchable.enabled); + addWaveTable(); + }}.fillX().end(); - row(); + row(); - visible(() -> !state.is(State.menu)); - row(); - new table(){{ - IntFormat fps = new IntFormat("text.fps"); - IntFormat tps = new IntFormat("text.tps"); - IntFormat ping = new IntFormat("text.ping"); - new label(() -> fps.get(Gdx.graphics.getFramesPerSecond())).padRight(10); - new label(() -> tps.get(threads.getTPS())).visible(() -> threads.isEnabled()); - row(); - new label(() -> ping.get(Net.getPing())).visible(() -> Net.client() && !gwt).colspan(2); + visible(() -> !state.is(State.menu)); + row(); + new table(){{ + IntFormat fps = new IntFormat("text.fps"); + IntFormat tps = new IntFormat("text.tps"); + IntFormat ping = new IntFormat("text.ping"); + new label(() -> fps.get(Gdx.graphics.getFramesPerSecond())).padRight(10); + new label(() -> tps.get(threads.getTPS())).visible(() -> threads.isEnabled()); + row(); + new label(() -> ping.get(Net.getPing())).visible(() -> Net.client() && !gwt).colspan(2); - infolabel = get(); - }}.size(-1).end().visible(() -> Settings.getBool("fps")); + infolabel = get(); + }}.size(-1).end().visible(() -> Settings.getBool("fps")); - }}.end(); - }}.end(); + }}.end(); + }}.end(); - new table(){{ - visible(() -> !state.is(State.menu)); - atop(); - aright(); + new table(){{ + visible(() -> !state.is(State.menu)); + atop(); + aright(); - Minimap minimap = new Minimap(); + Minimap minimap = new Minimap(); - add(minimap).visible(() -> Settings.getBool("minimap")); - }}.end(); + add(minimap).visible(() -> Settings.getBool("minimap")); + }}.end(); - //paused table - new table(){{ - visible(() -> state.is(State.paused) && !Net.active()); - atop(); + //paused table + new table(){{ + visible(() -> state.is(State.paused) && !Net.active()); + atop(); - new table("pane"){{ - new label("[orange]< "+ Bundles.get("text.paused") + " >").scale(0.75f).pad(6); - }}.end(); - }}.end(); + new table("pane"){{ + new label("[orange]< " + Bundles.get("text.paused") + " >").scale(0.75f).pad(6); + }}.end(); + }}.end(); - //respawn background table - new table("white"){{ - respawntable = get(); - respawntable.setColor(Color.CLEAR); - update(t -> { - if(state.is(State.menu)){ - respawntable.setColor(Color.CLEAR); - } - }); - }}.end(); + //respawn background table + new table("white"){{ + respawntable = get(); + respawntable.setColor(Color.CLEAR); + update(t -> { + if(state.is(State.menu)){ + respawntable.setColor(Color.CLEAR); + } + }); + }}.end(); - new table(){{ - abottom(); - visible(() -> !state.is(State.menu) && control.getSaves().isSaving()); + new table(){{ + abottom(); + visible(() -> !state.is(State.menu) && control.getSaves().isSaving()); - new label("$text.saveload"); + new label("$text.saveload"); - }}.end(); + }}.end(); - blockfrag.build(Core.scene.getRoot()); - } + blockfrag.build(Core.scene.getRoot()); + } - /**Show unlock notification for a new recipe.*/ - public void showUnlock(Recipe recipe){ - blockfrag.rebuild(); + /** + * Show unlock notification for a new recipe. + */ + public void showUnlock(Recipe recipe){ + blockfrag.rebuild(); - //if there's currently no unlock notification... - if(lastUnlockTable == null) { - Table table = new Table("button"); - table.update(() -> { - if(state.is(State.menu)){ - table.remove(); - lastUnlockLayout = null; - lastUnlockTable = null; - } - }); - table.margin(12); + //if there's currently no unlock notification... + if(lastUnlockTable == null){ + Table table = new Table("button"); + table.update(() -> { + if(state.is(State.menu)){ + table.remove(); + lastUnlockLayout = null; + lastUnlockTable = null; + } + }); + table.margin(12); - Table in = new Table(); + Table in = new Table(); - //create texture stack for displaying - Stack stack = new Stack(); - for (TextureRegion region : recipe.result.getCompactIcon()) { - Image image = new Image(region); - image.setScaling(Scaling.fit); - stack.add(image); - } + //create texture stack for displaying + Stack stack = new Stack(); + for(TextureRegion region : recipe.result.getCompactIcon()){ + Image image = new Image(region); + image.setScaling(Scaling.fit); + stack.add(image); + } - in.add(stack).size(48f).pad(2); + in.add(stack).size(48f).pad(2); - //add to table - table.add(in).padRight(8); - table.add("$text.unlocked"); - table.pack(); + //add to table + table.add(in).padRight(8); + table.add("$text.unlocked"); + table.pack(); - //create container table which will align and move - Table container = Core.scene.table(); - container.top().add(table); - container.setTranslation(0, table.getPrefHeight()); - container.actions(Actions.translateBy(0, -table.getPrefHeight(), 1f, Interpolation.fade), Actions.delay(4f), - //nesting actions() calls is necessary so the right prefHeight() is used - Actions.run(() -> container.actions(Actions.translateBy(0, table.getPrefHeight(), 1f, Interpolation.fade), Actions.run(() ->{ - lastUnlockTable = null; - lastUnlockLayout = null; - }), Actions.removeActor()))); + //create container table which will align and move + Table container = Core.scene.table(); + container.top().add(table); + container.setTranslation(0, table.getPrefHeight()); + container.actions(Actions.translateBy(0, -table.getPrefHeight(), 1f, Interpolation.fade), Actions.delay(4f), + //nesting actions() calls is necessary so the right prefHeight() is used + Actions.run(() -> container.actions(Actions.translateBy(0, table.getPrefHeight(), 1f, Interpolation.fade), Actions.run(() -> { + lastUnlockTable = null; + lastUnlockLayout = null; + }), Actions.removeActor()))); - lastUnlockTable = container; - lastUnlockLayout = in; - }else{ - //max column size - int col = 3; - //max amount of elements minus extra 'plus' - int cap = col*col-1; + lastUnlockTable = container; + lastUnlockLayout = in; + }else{ + //max column size + int col = 3; + //max amount of elements minus extra 'plus' + int cap = col * col - 1; - //get old elements - Array elements = new Array<>(lastUnlockLayout.getChildren()); - int esize = elements.size; + //get old elements + Array elements = new Array<>(lastUnlockLayout.getChildren()); + int esize = elements.size; - //...if it's already reached the cap, ignore everything - if(esize > cap) return; + //...if it's already reached the cap, ignore everything + if(esize > cap) return; - //get size of each element - float size = 48f / Math.min(elements.size + 1, col); + //get size of each element + float size = 48f / Math.min(elements.size + 1, col); - //correct plurals if needed - if(esize == 1){ - ((Label)lastUnlockLayout.getParent().find(e -> e instanceof Label)).setText("$text.unlocked.plural"); - } + //correct plurals if needed + if(esize == 1){ + ((Label) lastUnlockLayout.getParent().find(e -> e instanceof Label)).setText("$text.unlocked.plural"); + } - lastUnlockLayout.clearChildren(); - lastUnlockLayout.defaults().size(size).pad(2); + lastUnlockLayout.clearChildren(); + lastUnlockLayout.defaults().size(size).pad(2); - for(int i = 0; i < esize && i <= cap; i ++){ - lastUnlockLayout.add(elements.get(i)); + for(int i = 0; i < esize && i <= cap; i++){ + lastUnlockLayout.add(elements.get(i)); - if(i % col == col - 1){ - lastUnlockLayout.row(); - } - } + if(i % col == col - 1){ + lastUnlockLayout.row(); + } + } - //if there's space, add it - if(esize < cap) { + //if there's space, add it + if(esize < cap){ - Stack stack = new Stack(); - for (TextureRegion region : recipe.result.getCompactIcon()) { - Image image = new Image(region); - image.setScaling(Scaling.fit); - stack.add(image); - } + Stack stack = new Stack(); + for(TextureRegion region : recipe.result.getCompactIcon()){ + Image image = new Image(region); + image.setScaling(Scaling.fit); + stack.add(image); + } - lastUnlockLayout.add(stack); - }else{ //else, add a specific icon to denote no more space - lastUnlockLayout.addImage("icon-add"); - } + lastUnlockLayout.add(stack); + }else{ //else, add a specific icon to denote no more space + lastUnlockLayout.addImage("icon-add"); + } - lastUnlockLayout.pack(); - } - } + lastUnlockLayout.pack(); + } + } - private void toggleMenus(){ - wavetable.clearActions(); - infolabel.clearActions(); + private void toggleMenus(){ + wavetable.clearActions(); + infolabel.clearActions(); - float dur = 0.3f; - Interpolation in = Interpolation.pow3Out; + float dur = 0.3f; + Interpolation in = Interpolation.pow3Out; - flip.getStyle().imageUp = Core.skin.getDrawable(shown ? "icon-arrow-down" : "icon-arrow-up"); + flip.getStyle().imageUp = Core.skin.getDrawable(shown ? "icon-arrow-down" : "icon-arrow-up"); - if (shown) { - shown = false; - blockfrag.toggle(false, dur, in); - wavetable.actions(Actions.translateBy(0, (wavetable.getHeight() + dsize) - wavetable.getTranslation().y, dur, in)); - infolabel.actions(Actions.translateBy(0, (wavetable.getHeight()) - wavetable.getTranslation().y, dur, in)); - } else { - shown = true; - blockfrag.toggle(true, dur, in); - wavetable.actions(Actions.translateBy(0, -wavetable.getTranslation().y, dur, in)); - infolabel.actions(Actions.translateBy(0, -infolabel.getTranslation().y, dur, in)); - } - } + if(shown){ + shown = false; + blockfrag.toggle(false, dur, in); + wavetable.actions(Actions.translateBy(0, (wavetable.getHeight() + dsize) - wavetable.getTranslation().y, dur, in)); + infolabel.actions(Actions.translateBy(0, (wavetable.getHeight()) - wavetable.getTranslation().y, dur, in)); + }else{ + shown = true; + blockfrag.toggle(true, dur, in); + wavetable.actions(Actions.translateBy(0, -wavetable.getTranslation().y, dur, in)); + infolabel.actions(Actions.translateBy(0, -infolabel.getTranslation().y, dur, in)); + } + } - private String getEnemiesRemaining() { - int enemies = unitGroups[Team.red.ordinal()].size(); - if(enemies == 1) { - return Bundles.format("text.enemies.single", enemies); - } else { - return Bundles.format("text.enemies", enemies); - } - } + private String getEnemiesRemaining(){ + int enemies = unitGroups[Team.red.ordinal()].size(); + if(enemies == 1){ + return Bundles.format("text.enemies.single", enemies); + }else{ + return Bundles.format("text.enemies", enemies); + } + } - private void addWaveTable(){ - float uheight = 66f; + private void addWaveTable(){ + float uheight = 66f; - IntFormat wavef = new IntFormat("text.wave"); - IntFormat timef = new IntFormat("text.wave.waiting"); + IntFormat wavef = new IntFormat("text.wave"); + IntFormat timef = new IntFormat("text.wave.waiting"); - wavetable = new table("button"){{ - aleft(); - new table(){{ - aleft(); + wavetable = new table("button"){{ + aleft(); + new table(){{ + aleft(); - new label(() -> wavef.get(state.wave)).scale(fontScale *1.5f).left().padLeft(-6); + new label(() -> wavef.get(state.wave)).scale(fontScale * 1.5f).left().padLeft(-6); - row(); + row(); - new label(() -> unitGroups[Team.red.ordinal()].size() > 0 && state.mode.disableWaveTimer ? - getEnemiesRemaining() : - (state.mode.disableWaveTimer) ? "$text.waiting" - : timef.get((int) (state.wavetime / 60f))) - .minWidth(126).padLeft(-6).left(); + new label(() -> unitGroups[Team.red.ordinal()].size() > 0 && state.mode.disableWaveTimer ? + getEnemiesRemaining() : + (state.mode.disableWaveTimer) ? "$text.waiting" + : timef.get((int) (state.wavetime / 60f))) + .minWidth(126).padLeft(-6).left(); - margin(10f); - get().marginLeft(6); - }}.left().end(); + margin(10f); + get().marginLeft(6); + }}.left().end(); - add().growX(); + add().growX(); - playButton(uheight); - }}.height(uheight).fillX().expandX().end().get(); - wavetable.getParent().getParent().swapActor(wavetable.getParent(), menu.getParent()); - } + playButton(uheight); + }}.height(uheight).fillX().expandX().end().get(); + wavetable.getParent().getParent().swapActor(wavetable.getParent(), menu.getParent()); + } - private void playButton(float uheight){ - new imagebutton("icon-play", 30f, () -> { - if(Net.client() && players[0].isAdmin){ - Call.onAdminRequest(players[0], AdminAction.wave); - }else { - state.wavetime = 0f; - } - }).height(uheight).fillX().right().padTop(-8f).padBottom(-12f).padLeft(-15).padRight(-10).width(40f).update(l->{ - boolean vis = state.mode.disableWaveTimer && ((Net.server() || players[0].isAdmin) || !Net.active()); - boolean paused = state.is(State.paused) || !vis; + private void playButton(float uheight){ + new imagebutton("icon-play", 30f, () -> { + if(Net.client() && players[0].isAdmin){ + Call.onAdminRequest(players[0], AdminAction.wave); + }else{ + state.wavetime = 0f; + } + }).height(uheight).fillX().right().padTop(-8f).padBottom(-12f).padLeft(-15).padRight(-10).width(40f).update(l -> { + boolean vis = state.mode.disableWaveTimer && ((Net.server() || players[0].isAdmin) || !Net.active()); + boolean paused = state.is(State.paused) || !vis; - l.getStyle().imageUp = Core.skin.getDrawable(vis ? "icon-play" : "clear"); - l.setTouchable(!paused ? Touchable.enabled : Touchable.disabled); - }).visible(() -> state.mode.disableWaveTimer && ((Net.server() || players[0].isAdmin) || !Net.active()) && unitGroups[Team.red.ordinal()].size() == 0); - } + l.getStyle().imageUp = Core.skin.getDrawable(vis ? "icon-play" : "clear"); + l.setTouchable(!paused ? Touchable.enabled : Touchable.disabled); + }).visible(() -> state.mode.disableWaveTimer && ((Net.server() || players[0].isAdmin) || !Net.active()) && unitGroups[Team.red.ordinal()].size() == 0); + } } diff --git a/core/src/io/anuke/mindustry/ui/fragments/LoadingFragment.java b/core/src/io/anuke/mindustry/ui/fragments/LoadingFragment.java index 3e41e10d54..4104939c22 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/LoadingFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/LoadingFragment.java @@ -10,14 +10,14 @@ import io.anuke.ucore.scene.ui.Label; import io.anuke.ucore.scene.ui.TextButton; import io.anuke.ucore.scene.ui.layout.Table; -public class LoadingFragment extends Fragment { +public class LoadingFragment extends Fragment{ private Table table; private TextButton button; @Override - public void build(Group parent) { + public void build(Group parent){ - table = new table("loadDim"){{ + table = new table("loadDim"){{ add().height(70f).row(); touchable(Touchable.enabled); @@ -33,7 +33,8 @@ public class LoadingFragment extends Fragment { row(); - button = get().addButton("$text.cancel", () -> {}).pad(20).size(250f, 70f).get(); + button = get().addButton("$text.cancel", () -> { + }).pad(20).size(250f, 70f).get(); button.setVisible(false); }}.end().get(); diff --git a/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java b/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java index 2a9834943f..228015ea52 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java @@ -18,175 +18,175 @@ import io.anuke.ucore.scene.ui.layout.Table; import static io.anuke.mindustry.Vars.*; public class MenuFragment extends Fragment{ - private Table mobileContainer; + private Table mobileContainer; - @Override - public void build(Group parent){ - new table(){{ - visible(() -> state.is(State.menu)); + @Override + public void build(Group parent){ + new table(){{ + visible(() -> state.is(State.menu)); - if(!mobile){ - buildDesktop(); - }else{ - buildMobile(); + if(!mobile){ + buildDesktop(); + }else{ + buildMobile(); - Events.on(ResizeEvent.class, () -> buildMobile()); - } - }}.end(); + Events.on(ResizeEvent.class, () -> buildMobile()); + } + }}.end(); - //discord icon in top right - if(Platform.instance.hasDiscord()) { - new table() {{ - abottom().atop().aright(); - get().addButton("", "discord", ui.discord::show).size(81, 42); - }}.end().visible(() -> state.is(State.menu)); - } + //discord icon in top right + if(Platform.instance.hasDiscord()){ + new table(){{ + abottom().atop().aright(); + get().addButton("", "discord", ui.discord::show).size(81, 42); + }}.end().visible(() -> state.is(State.menu)); + } - //info icon - if(mobile) { - new table() {{ - abottom().atop().aleft(); - get().addButton("", "info", ui.about::show).size(81, 42); - }}.end().visible(() -> state.is(State.menu)); - } + //info icon + if(mobile){ + new table(){{ + abottom().atop().aleft(); + get().addButton("", "info", ui.about::show).size(81, 42); + }}.end().visible(() -> state.is(State.menu)); + } - //version info - new table(){{ - visible(() -> state.is(State.menu)); - abottom().aleft(); - new label("Mindustry " + Version.code + " " + Version.type + " / " + Version.buildName); - }}.end(); - } + //version info + new table(){{ + visible(() -> state.is(State.menu)); + abottom().aleft(); + new label("Mindustry " + Version.code + " " + Version.type + " / " + Version.buildName); + }}.end(); + } - private void buildMobile(){ - if(mobileContainer == null){ - mobileContainer = build.getTable(); - } + private void buildMobile(){ + if(mobileContainer == null){ + mobileContainer = build.getTable(); + } - mobileContainer.clear(); - mobileContainer.setSize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + mobileContainer.clear(); + mobileContainer.setSize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); - float size = 120f; - float isize = 14f * 4; - mobileContainer.defaults().size(size).pad(5).padTop(4f); + float size = 120f; + float isize = 14f * 4; + mobileContainer.defaults().size(size).pad(5).padTop(4f); - MobileButton - play = new MobileButton("icon-play-2", isize, "$text.play", ui.levels::show), - maps = new MobileButton("icon-map", isize, "$text.maps", ui.maps::show), - load = new MobileButton("icon-load", isize, "$text.load", ui.load::show), - join = new MobileButton("icon-add", isize, "$text.joingame", ui.join::show), - editor = new MobileButton("icon-editor", isize, "$text.editor", () -> ui.loadAnd(ui.editor::show)), - tools = new MobileButton("icon-tools", isize, "$text.settings", ui.settings::show), - unlocks = new MobileButton("icon-unlocks", isize, "$text.unlocks", ui.unlocks::show), - donate = new MobileButton("icon-donate", isize, "$text.donate", Platform.instance::openDonations); + MobileButton + play = new MobileButton("icon-play-2", isize, "$text.play", ui.levels::show), + maps = new MobileButton("icon-map", isize, "$text.maps", ui.maps::show), + load = new MobileButton("icon-load", isize, "$text.load", ui.load::show), + join = new MobileButton("icon-add", isize, "$text.joingame", ui.join::show), + editor = new MobileButton("icon-editor", isize, "$text.editor", () -> ui.loadAnd(ui.editor::show)), + tools = new MobileButton("icon-tools", isize, "$text.settings", ui.settings::show), + unlocks = new MobileButton("icon-unlocks", isize, "$text.unlocks", ui.unlocks::show), + donate = new MobileButton("icon-donate", isize, "$text.donate", Platform.instance::openDonations); - if(Gdx.graphics.getWidth() > Gdx.graphics.getHeight()){ - mobileContainer.add(play); - mobileContainer.add(join); - mobileContainer.add(load); - mobileContainer.add(maps); - mobileContainer.row(); + if(Gdx.graphics.getWidth() > Gdx.graphics.getHeight()){ + mobileContainer.add(play); + mobileContainer.add(join); + mobileContainer.add(load); + mobileContainer.add(maps); + mobileContainer.row(); - mobileContainer.table(table -> { - table.defaults().set(mobileContainer.defaults()); + mobileContainer.table(table -> { + table.defaults().set(mobileContainer.defaults()); - table.add(editor); - table.add(tools); - table.add(unlocks); + table.add(editor); + table.add(tools); + table.add(unlocks); - if(Platform.instance.canDonate()) table.add(donate); - }).colspan(4); - }else{ - mobileContainer.add(play); - mobileContainer.add(maps); - mobileContainer.row(); - mobileContainer.add(load); - mobileContainer.add(join); - mobileContainer.row(); - mobileContainer.add(editor); - mobileContainer.add(tools); - mobileContainer.row(); + if(Platform.instance.canDonate()) table.add(donate); + }).colspan(4); + }else{ + mobileContainer.add(play); + mobileContainer.add(maps); + mobileContainer.row(); + mobileContainer.add(load); + mobileContainer.add(join); + mobileContainer.row(); + mobileContainer.add(editor); + mobileContainer.add(tools); + mobileContainer.row(); - mobileContainer.table(table -> { - table.defaults().set(mobileContainer.defaults()); + mobileContainer.table(table -> { + table.defaults().set(mobileContainer.defaults()); - table.add(unlocks); + table.add(unlocks); - if(Platform.instance.canDonate()) table.add(donate); - }).colspan(2); - } - } + if(Platform.instance.canDonate()) table.add(donate); + }).colspan(2); + } + } - private void buildDesktop(){ - new table(){{ + private void buildDesktop(){ + new table(){{ - float w = 200f; - float bw = w * 2f + 10f; + float w = 200f; + float bw = w * 2f + 10f; - defaults().size(w, 66f).padTop(5).padRight(5); + defaults().size(w, 66f).padTop(5).padRight(5); - add(new MenuButton("icon-play-2", "$text.play", MenuFragment.this::showPlaySelect)).width(bw).colspan(2); + add(new MenuButton("icon-play-2", "$text.play", MenuFragment.this::showPlaySelect)).width(bw).colspan(2); - row(); + row(); - add(new MenuButton("icon-editor", "$text.editor", () -> ui.loadAnd(ui.editor::show))); + add(new MenuButton("icon-editor", "$text.editor", () -> ui.loadAnd(ui.editor::show))); - add(new MenuButton("icon-map", "$text.maps", ui.maps::show)); + add(new MenuButton("icon-map", "$text.maps", ui.maps::show)); - row(); + row(); - add(new MenuButton("icon-info", "$text.about.button", ui.about::show)); + add(new MenuButton("icon-info", "$text.about.button", ui.about::show)); - add(new MenuButton("icon-tools", "$text.settings", ui.settings::show)); + add(new MenuButton("icon-tools", "$text.settings", ui.settings::show)); - row(); + row(); - add(new MenuButton("icon-menu", "$text.changelog.title", ui.changelog::show)); + add(new MenuButton("icon-menu", "$text.changelog.title", ui.changelog::show)); - add(new MenuButton("icon-unlocks", "$text.unlocks", ui.unlocks::show)); + add(new MenuButton("icon-unlocks", "$text.unlocks", ui.unlocks::show)); - row(); + row(); - if(!gwt){ - add(new MenuButton("icon-exit", "$text.quit", Gdx.app::exit)).width(bw).colspan(2); - } + if(!gwt){ + add(new MenuButton("icon-exit", "$text.quit", Gdx.app::exit)).width(bw).colspan(2); + } - get().margin(16); - }}.end(); - } + get().margin(16); + }}.end(); + } - private void showPlaySelect(){ - float w = 200f; - float bw = w * 2f + 10f; + private void showPlaySelect(){ + float w = 200f; + float bw = w * 2f + 10f; - FloatingDialog dialog = new FloatingDialog("$text.play"); - dialog.addCloseButton(); - dialog.content().defaults().height(66f).width(w).padRight(5f); + FloatingDialog dialog = new FloatingDialog("$text.play"); + dialog.addCloseButton(); + dialog.content().defaults().height(66f).width(w).padRight(5f); - dialog.content().add(new MenuButton("icon-play-2", "$text.newgame", () -> { - dialog.hide(); - ui.levels.show(); - })).width(bw).colspan(2); - dialog.content().row(); + dialog.content().add(new MenuButton("icon-play-2", "$text.newgame", () -> { + dialog.hide(); + ui.levels.show(); + })).width(bw).colspan(2); + dialog.content().row(); - dialog.content().add(new MenuButton("icon-add", "$text.joingame", () -> { - if(Platform.instance.canJoinGame()){ - ui.join.show(); - dialog.hide(); - }else{ - ui.showInfo("$text.multiplayer.web"); - } - })); + dialog.content().add(new MenuButton("icon-add", "$text.joingame", () -> { + if(Platform.instance.canJoinGame()){ + ui.join.show(); + dialog.hide(); + }else{ + ui.showInfo("$text.multiplayer.web"); + } + })); - dialog.content().add(new MenuButton("icon-tutorial", "$text.tutorial", ()-> ui.showInfo("The tutorial is currently not yet implemented."))); + dialog.content().add(new MenuButton("icon-tutorial", "$text.tutorial", () -> ui.showInfo("The tutorial is currently not yet implemented."))); - dialog.content().row(); + dialog.content().row(); - dialog.content().add(new MenuButton("icon-load", "$text.loadgame", () -> { - ui.load.show(); - dialog.hide(); - })).width(bw).colspan(2); + dialog.content().add(new MenuButton("icon-load", "$text.loadgame", () -> { + ui.load.show(); + dialog.hide(); + })).width(bw).colspan(2); - dialog.show(); - } + dialog.show(); + } } diff --git a/core/src/io/anuke/mindustry/ui/fragments/OverlayFragment.java b/core/src/io/anuke/mindustry/ui/fragments/OverlayFragment.java index 060467f109..fd861518ad 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/OverlayFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/OverlayFragment.java @@ -3,7 +3,9 @@ package io.anuke.mindustry.ui.fragments; import io.anuke.mindustry.input.InputHandler; import io.anuke.ucore.scene.Group; -/**Fragment for displaying overlays such as block inventories. One is created for each input handler.*/ +/** + * Fragment for displaying overlays such as block inventories. One is created for each input handler. + */ public class OverlayFragment extends Fragment{ public final BlockInventoryFragment inv; public final BlockConfigFragment config; diff --git a/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java b/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java index 08f8780a47..584fef1b94 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java @@ -116,26 +116,26 @@ public class PlayerListFragment extends Fragment{ button.labelWrap("[#" + player.color.toString().toUpperCase() + "]" + player.name).width(170f).pad(10); button.add().grow(); - button.addImage("icon-admin").size(14*2).visible(() -> player.isAdmin && !(!player.isLocal && Net.server())).padRight(5); + button.addImage("icon-admin").size(14 * 2).visible(() -> player.isAdmin && !(!player.isLocal && Net.server())).padRight(5); if((Net.server() || players[0].isAdmin) && !player.isLocal && (!player.isAdmin || Net.server())){ button.add().growY(); - float bs = (h + 14)/2f; + float bs = (h + 14) / 2f; button.table(t -> { t.defaults().size(bs - 1, bs + 3); //TODO requests. - t.addImageButton("icon-ban", 14*2, () -> { + t.addImageButton("icon-ban", 14 * 2, () -> { ui.showConfirm("$text.confirm", "$text.confirmban", () -> Call.onAdminRequest(player, AdminAction.ban)); }).padBottom(-5.1f); - t.addImageButton("icon-cancel", 14*2, () -> Call.onAdminRequest(player, AdminAction.kick)).padBottom(-5.1f); + t.addImageButton("icon-cancel", 14 * 2, () -> Call.onAdminRequest(player, AdminAction.kick)).padBottom(-5.1f); t.row(); - t.addImageButton("icon-admin", "toggle", 14*2, () -> { + t.addImageButton("icon-admin", "toggle", 14 * 2, () -> { if(Net.client()) return; String id = netServer.admins.getTraceByID(player.uuid).uuid; @@ -154,7 +154,7 @@ public class PlayerListFragment extends Fragment{ b.setDisabled(Net.client()); }).get().setTouchable(() -> Net.client() ? Touchable.disabled : Touchable.enabled); - t.addImageButton("icon-zoom-small", 14*2, () -> Call.onAdminRequest(player, AdminAction.trace)); + t.addImageButton("icon-zoom-small", 14 * 2, () -> Call.onAdminRequest(player, AdminAction.trace)); }).padRight(12).padTop(-5).padLeft(0).padBottom(-10).size(bs + 10f, bs); diff --git a/core/src/io/anuke/mindustry/world/BarType.java b/core/src/io/anuke/mindustry/world/BarType.java index 332ed5c7a1..e5ed5a6d3b 100644 --- a/core/src/io/anuke/mindustry/world/BarType.java +++ b/core/src/io/anuke/mindustry/world/BarType.java @@ -2,7 +2,7 @@ package io.anuke.mindustry.world; import com.badlogic.gdx.graphics.Color; -public enum BarType { +public enum BarType{ health(Color.SCARLET), inventory(Color.GREEN), power(Color.valueOf("fbeb67")), diff --git a/core/src/io/anuke/mindustry/world/BaseBlock.java b/core/src/io/anuke/mindustry/world/BaseBlock.java index 875de327d1..466996ddae 100644 --- a/core/src/io/anuke/mindustry/world/BaseBlock.java +++ b/core/src/io/anuke/mindustry/world/BaseBlock.java @@ -15,7 +15,7 @@ import io.anuke.ucore.core.Timers; import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Translator; -public abstract class BaseBlock { +public abstract class BaseBlock{ public boolean hasItems; public boolean hasLiquids; public boolean hasPower; @@ -34,7 +34,9 @@ public abstract class BaseBlock { return true; } - /**Returns the amount of items this block can accept.*/ + /** + * Returns the amount of items this block can accept. + */ public int acceptStack(Item item, int amount, Tile tile, Unit source){ if(acceptItem(item, tile, tile) && hasItems && source.getTeam() == tile.getTeam()){ return Math.min(getMaximumAccepted(tile, item), amount); @@ -47,25 +49,32 @@ public abstract class BaseBlock { return itemCapacity - tile.entity.items.total(); } - /**Remove a stack from this inventory, and return the amount removed.*/ + /** + * Remove a stack from this inventory, and return the amount removed. + */ public int removeStack(Tile tile, Item item, int amount){ tile.entity.wakeUp(); tile.entity.items.remove(item, amount); return amount; } - /**Handle a stack input.*/ + /** + * Handle a stack input. + */ public void handleStack(Item item, int amount, Tile tile, Unit source){ tile.entity.wakeUp(); tile.entity.items.add(item, amount); } - /**Returns offset for stack placement.*/ + /** + * Returns offset for stack placement. + */ public void getStackOffset(Item item, Tile tile, Translator trns){ } - public void onProximityUpdate(Tile tile){} + public void onProximityUpdate(Tile tile){ + } public void handleItem(Item item, Tile tile, Tile source){ tile.entity.items.add(item, 1); @@ -89,7 +98,9 @@ public abstract class BaseBlock { return true; } - /**Returns how much power is accepted.*/ + /** + * Returns how much power is accepted. + */ public float addPower(Tile tile, float amount){ float canAccept = Math.min(powerCapacity - tile.entity.power.amount, amount); @@ -102,16 +113,16 @@ public abstract class BaseBlock { Array proximity = tile.entity.proximity(); int dump = tile.getDump(); - for (int i = 0; i < proximity.size; i ++) { + for(int i = 0; i < proximity.size; i++){ incrementDump(tile, proximity.size); Tile other = proximity.get((i + dump) % proximity.size); Tile in = Edges.getFacingEdge(tile, other); - if (other.block().hasLiquids) { + if(other.block().hasLiquids){ float ofract = other.entity.liquids.get(liquid) / other.block().liquidCapacity; float fract = tile.entity.liquids.get(liquid) / liquidCapacity; - if (ofract < fract) tryMoveLiquid(tile, in, other, (fract - ofract) * liquidCapacity / 2f, liquid); + if(ofract < fract) tryMoveLiquid(tile, in, other, (fract - ofract) * liquidCapacity / 2f, liquid); } } @@ -133,36 +144,36 @@ public abstract class BaseBlock { if(next.block().hasLiquids && tile.entity.liquids.get(liquid) > 0f){ - if(next.block().acceptLiquid(next, tile, liquid, 0f)) { + if(next.block().acceptLiquid(next, tile, liquid, 0f)){ float ofract = next.entity.liquids.get(liquid) / next.block().liquidCapacity; float fract = tile.entity.liquids.get(liquid) / liquidCapacity; float flow = Math.min(Mathf.clamp((fract - ofract) * (1f)) * (liquidCapacity), tile.entity.liquids.get(liquid)); flow = Math.min(flow, next.block().liquidCapacity - next.entity.liquids.get(liquid) - 0.001f); - if (flow > 0f && ofract <= fract && next.block().acceptLiquid(next, tile, liquid, flow)) { + if(flow > 0f && ofract <= fract && next.block().acceptLiquid(next, tile, liquid, flow)){ next.block().handleLiquid(next, tile, liquid, flow); tile.entity.liquids.remove(liquid, flow); return flow; - } else if (ofract > 0.1f && fract > 0.1f) { + }else if(ofract > 0.1f && fract > 0.1f){ Liquid other = next.entity.liquids.current(); - if ((other.flammability > 0.3f && liquid.temperature > 0.7f) || - (liquid.flammability > 0.3f && other.temperature > 0.7f)) { + if((other.flammability > 0.3f && liquid.temperature > 0.7f) || + (liquid.flammability > 0.3f && other.temperature > 0.7f)){ tile.entity.damage(1 * Timers.delta()); next.entity.damage(1 * Timers.delta()); - if (Mathf.chance(0.1 * Timers.delta())) { + if(Mathf.chance(0.1 * Timers.delta())){ Effects.effect(EnvironmentFx.fire, (tile.worldx() + next.worldx()) / 2f, (tile.worldy() + next.worldy()) / 2f); } - } else if ((liquid.temperature > 0.7f && other.temperature < 0.55f) || - (other.temperature > 0.7f && liquid.temperature < 0.55f)) { + }else if((liquid.temperature > 0.7f && other.temperature < 0.55f) || + (other.temperature > 0.7f && liquid.temperature < 0.55f)){ tile.entity.liquids.remove(liquid, Math.min(tile.entity.liquids.get(liquid), 0.7f * Timers.delta())); - if (Mathf.chance(0.2f * Timers.delta())) { + if(Mathf.chance(0.2f * Timers.delta())){ Effects.effect(EnvironmentFx.steam, (tile.worldx() + next.worldx()) / 2f, (tile.worldy() + next.worldy()) / 2f); } } } } }else if(leak && !next.block().solid && !next.block().hasLiquids){ - float leakAmount = tile.entity.liquids.get(liquid)/1.5f; + float leakAmount = tile.entity.liquids.get(liquid) / 1.5f; Puddle.deposit(next, tile, liquid, leakAmount); tile.entity.liquids.remove(liquid, leakAmount); } @@ -171,12 +182,13 @@ public abstract class BaseBlock { /** * Tries to put this item into a nearby container, if there are no available - * containers, it gets added to the block's inventory.*/ + * containers, it gets added to the block's inventory. + */ public void offloadNear(Tile tile, Item item){ Array proximity = tile.entity.proximity(); int dump = tile.getDump(); - for(int i = 0; i < proximity.size; i ++){ + for(int i = 0; i < proximity.size; i++){ incrementDump(tile, proximity.size); Tile other = proximity.get((i + dump) % proximity.size); Tile in = Edges.getFacingEdge(tile, other); @@ -189,32 +201,38 @@ public abstract class BaseBlock { handleItem(item, tile, tile); } - /**Try dumping any item near the tile.*/ + /** + * Try dumping any item near the tile. + */ public boolean tryDump(Tile tile){ return tryDump(tile, null); } - /**Try dumping a specific item near the tile. - * @param todump Item to dump. Can be null to dump anything.*/ + /** + * Try dumping a specific item near the tile. + * + * @param todump Item to dump. Can be null to dump anything. + */ public boolean tryDump(Tile tile, Item todump){ TileEntity entity = tile.entity; - if(entity == null || !hasItems || tile.entity.items.total() == 0 || (todump != null && !entity.items.has(todump))) return false; + if(entity == null || !hasItems || tile.entity.items.total() == 0 || (todump != null && !entity.items.has(todump))) + return false; Array proximity = entity.proximity(); int dump = tile.getDump(); if(proximity.size == 0) return false; - for(int i = 0; i < proximity.size; i ++){ + for(int i = 0; i < proximity.size; i++){ Tile other = proximity.get((i + dump) % proximity.size); Tile in = Edges.getFacingEdge(tile, other); - if(todump == null) { + if(todump == null){ - for (int ii = 0; ii < Item.all().size; ii++) { + for(int ii = 0; ii < Item.all().size; ii++){ Item item = Item.getByID(ii); - if (entity.items.has(item) && other.block().acceptItem(item, other, in) && canDump(tile, other, item)) { + if(entity.items.has(item) && other.block().acceptItem(item, other, in) && canDump(tile, other, item)){ other.block().handleItem(item, other, in); tile.entity.items.remove(item, 1); incrementDump(tile, proximity.size); @@ -223,7 +241,7 @@ public abstract class BaseBlock { } }else{ - if (other.block().acceptItem(todump, other, in) && canDump(tile, other, todump)) { + if(other.block().acceptItem(todump, other, in) && canDump(tile, other, todump)){ other.block().handleItem(todump, other, in); tile.entity.items.remove(todump, 1); incrementDump(tile, proximity.size); @@ -238,10 +256,12 @@ public abstract class BaseBlock { } private void incrementDump(Tile tile, int prox){ - tile.setDump((byte)((tile.getDump() + 1) % prox)); + tile.setDump((byte) ((tile.getDump() + 1) % prox)); } - /**Used for dumping items.*/ + /** + * Used for dumping items. + */ public boolean canDump(Tile tile, Tile to, Item item){ return true; } diff --git a/core/src/io/anuke/mindustry/world/Block.java b/core/src/io/anuke/mindustry/world/Block.java index 5e2b2631a5..a8961072a4 100644 --- a/core/src/io/anuke/mindustry/world/Block.java +++ b/core/src/io/anuke/mindustry/world/Block.java @@ -33,352 +33,391 @@ import static io.anuke.mindustry.Vars.tilesize; import static io.anuke.mindustry.Vars.world; public class Block extends BaseBlock implements Content{ - private static int lastid; - private static Array blocks = new Array<>(140); - private static ObjectMap map = new ObjectMap<>(); + private static int lastid; + private static Array blocks = new Array<>(140); + private static ObjectMap map = new ObjectMap<>(); + /** internal name */ + public final String name; + /** internal ID */ + public final int id; + /** display name */ + public final String formalName; + /** Detailed description of the block. Can be as long as necesary. */ + public final String fullDescription; + /** whether this block has a tile entity that updates */ + public boolean update; + /** whether this block has health and can be destroyed */ + public boolean destructible; + /** if true, this block cannot be broken by normal means. */ + public boolean unbreakable; + /** whether this is solid */ + public boolean solid; + /** whether this block CAN be solid. */ + public boolean solidifes; + /** whether this is rotateable */ + public boolean rotate; + /** whether you can break this with rightclick */ + public boolean breakable; + /** whether this floor can be placed on. */ + public boolean placeableOn = true; + /** tile entity health */ + public int health = -1; + /** base block explosiveness */ + public float baseExplosiveness = 0f; + /** whether this block can be placed on liquids. */ + public boolean floating = true; + /** stuff that drops when broken */ + public ItemStack drops = null; + /** multiblock size */ + public int size = 1; + /** Whether to draw this block in the expanded draw range. */ + public boolean expanded = false; + /** Max of timers used. */ + public int timers = 0; + /** Cache layer. Only used for 'cached' rendering. */ + public CacheLayer cacheLayer = CacheLayer.normal; + /** Layer to draw extra stuff on. */ + public Layer layer = null; + /** Extra layer to draw extra extra stuff on. */ + public Layer layer2 = null; + /** whether this block can be replaced in all cases */ + public boolean alwaysReplace = false; + /** whether this block has instant transfer checking. used for calculations to prevent infinite loops. */ + public boolean instantTransfer = false; + /** The block group. Unless {@link #canReplace} is overriden, blocks in the same group can replace each other. */ + public BlockGroup group = BlockGroup.none; + /** list of displayed block status bars. Defaults to health bar. */ + public BlockBars bars = new BlockBars(); + /** List of block stats. */ + public BlockStats stats = new BlockStats(this); + /** List of block flags. Used for AI indexing. */ + public EnumSet flags; + /** Whether to automatically set the entity to 'sleeping' when created. */ + public boolean autoSleep; + /** Name of shadow region to load. Null to indicate normal shadow. */ + public String shadow = null; + /** Whether the block can be tapped and selected to configure. */ + public boolean configurable; + /** Whether this block consumes touchDown events when tapped. */ + public boolean consumesTap; + /** The color of this block when displayed on the minimap or map preview. */ + public Color minimapColor = Color.CLEAR; + /** View range of this block type. Use a value < 0 to disable. */ + public float viewRange = 10; + protected Array tempTiles = new Array<>(); + protected Color tempColor = new Color(); + protected TextureRegion[] blockIcon; + protected TextureRegion[] icon; + protected TextureRegion[] compactIcon; + protected TextureRegion editorIcon; + protected TextureRegion shadowRegion; + protected TextureRegion region; - protected Array tempTiles = new Array<>(); - protected Color tempColor = new Color(); + public Block(String name){ + this.name = name; + this.formalName = Bundles.get("block." + name + ".name", name); + this.fullDescription = Bundles.getOrNull("block." + name + ".description"); + this.solid = false; + this.id = lastid++; - protected TextureRegion[] blockIcon; - protected TextureRegion[] icon; - protected TextureRegion[] compactIcon; - protected TextureRegion editorIcon; - - protected TextureRegion shadowRegion; - protected TextureRegion region; - - /**internal name*/ - public final String name; - /**internal ID*/ - public final int id; - /**display name*/ - public final String formalName; - /**whether this block has a tile entity that updates*/ - public boolean update; - /**whether this block has health and can be destroyed*/ - public boolean destructible; - /**if true, this block cannot be broken by normal means.*/ - public boolean unbreakable; - /**whether this is solid*/ - public boolean solid; - /**whether this block CAN be solid.*/ - public boolean solidifes; - /**whether this is rotateable*/ - public boolean rotate; - /**whether you can break this with rightclick*/ - public boolean breakable; - /**whether this floor can be placed on.*/ - public boolean placeableOn = true; - /**tile entity health*/ - public int health = -1; - /**base block explosiveness*/ - public float baseExplosiveness = 0f; - /**whether this block can be placed on liquids.*/ - public boolean floating = true; - /**stuff that drops when broken*/ - public ItemStack drops = null; - /**multiblock size*/ - public int size = 1; - /**Detailed description of the block. Can be as long as necesary.*/ - public final String fullDescription; - /**Whether to draw this block in the expanded draw range.*/ - public boolean expanded = false; - /**Max of timers used.*/ - public int timers = 0; - /**Cache layer. Only used for 'cached' rendering.*/ - public CacheLayer cacheLayer = CacheLayer.normal; - /**Layer to draw extra stuff on.*/ - public Layer layer = null; - /**Extra layer to draw extra extra stuff on.*/ - public Layer layer2 = null; - /**whether this block can be replaced in all cases*/ - public boolean alwaysReplace = false; - /**whether this block has instant transfer checking. used for calculations to prevent infinite loops.*/ - public boolean instantTransfer = false; - /**The block group. Unless {@link #canReplace} is overriden, blocks in the same group can replace each other.*/ - public BlockGroup group = BlockGroup.none; - /**list of displayed block status bars. Defaults to health bar.*/ - public BlockBars bars = new BlockBars(); - /**List of block stats.*/ - public BlockStats stats = new BlockStats(this); - /**List of block flags. Used for AI indexing.*/ - public EnumSet flags; - /**Whether to automatically set the entity to 'sleeping' when created.*/ - public boolean autoSleep; - /**Name of shadow region to load. Null to indicate normal shadow.*/ - public String shadow = null; - /**Whether the block can be tapped and selected to configure.*/ - public boolean configurable; - /**Whether this block consumes touchDown events when tapped.*/ - public boolean consumesTap; - /**The color of this block when displayed on the minimap or map preview.*/ - public Color minimapColor = Color.CLEAR; - /**View range of this block type. Use a value < 0 to disable.*/ - public float viewRange = 10; - - public Block(String name) { - this.name = name; - this.formalName = Bundles.get("block." + name + ".name", name); - this.fullDescription = Bundles.getOrNull("block." + name + ".description"); - this.solid = false; - this.id = lastid++; - - if(map.containsKey(name)){ - throw new RuntimeException("Two blocks cannot have the same names! Problematic block: " + name); - } - - map.put(name, this); - blocks.add(this); - } - - public boolean isLayer(Tile tile){return true;} - public boolean isLayer2(Tile tile){return true;} - public void drawLayer(Tile tile){} - public void drawLayer2(Tile tile){} - - /**Draw the block overlay that is shown when a cursor is over the block.*/ - public void drawSelect(Tile tile){} - - /**Drawn when you are placing a block.*/ - public void drawPlace(int x, int y, int rotation, boolean valid){} - - /**Called after the block is placed.*/ - public void placed(Tile tile){} - - /**Called every frame a unit is on this tile.*/ - public void unitOn(Tile tile, Unit unit){} - - /**Returns whether ot not this block can be place on the specified tile.*/ - public boolean canPlaceOn(Tile tile){ return true; } - - /**Called after all blocks are created.*/ - @Override - public void init(){ - //initialize default health based on size - if(health == -1){ - health = size*size*40; - } - - setStats(); - setBars(); - - consumes.checkRequired(this); - } - - @Override - public void load() { - shadowRegion = Draw.region(shadow == null ? "shadow-" + size : shadow); - region = Draw.region(name); - } - - /**Called when the block is tapped.*/ - public void tapped(Tile tile, Player player){ - - } - - /**Returns whether or not a hand cursor should be shown over this block.*/ - public CursorType getCursor(Tile tile){ - return configurable ? CursorType.hand : CursorType.normal; - } - - /**Called when this block is tapped to build a UI on the table. - * {@link #configurable} able} must return true for this to be called.*/ - public void buildTable(Tile tile, Table table) {} - - /**Called when another tile is tapped while this block is selected. - * Returns whether or not this block should be deselected.*/ - public boolean onConfigureTileTapped(Tile tile, Tile other){ - return tile != other; - } - - /**Returns whether this config menu should show when the specified player taps it.*/ - public boolean shouldShowConfigure(Tile tile, Player player){ - return true; - } - - /**Whether this configuration should be hidden now. Called every frame the config is open.*/ - public boolean shouldHideConfigure(Tile tile, Player player){ - return false; - } - - public boolean synthetic(){ - return update || destructible || solid; - } - - public void drawConfigure(Tile tile){ - Draw.color(Palette.accent); - Lines.stroke(1f); - Lines.square(tile.drawx(), tile.drawy(), - tile.block().size * tilesize / 2f + 1f); - Draw.reset(); - } - - public void setStats(){ - stats.add(BlockStat.size, "{0}x{0}", size); - stats.add(BlockStat.health, health, StatUnit.none); - - consumes.forEach(cons -> cons.display(stats)); - - if(hasPower) stats.add(BlockStat.powerCapacity, powerCapacity, StatUnit.powerUnits); - if(hasLiquids) stats.add(BlockStat.liquidCapacity, liquidCapacity, StatUnit.liquidUnits); - if(hasItems) stats.add(BlockStat.itemCapacity, itemCapacity, StatUnit.items); - } - - //TODO make this easier to config. - public void setBars(){ - if(hasPower) bars.add(new BlockBar(BarType.power, true, tile -> tile.entity.power.amount / powerCapacity)); - if(hasLiquids) bars.add(new BlockBar(BarType.liquid, true, tile -> tile.entity.liquids.total() / liquidCapacity)); - if(hasItems) bars.add(new BlockBar(BarType.inventory, true, tile -> (float)tile.entity.items.total() / itemCapacity)); - } - - public String name(){ - return name; - } - - public boolean isSolidFor(Tile tile){ - return false; - } - - public boolean canReplace(Block other){ - return (other != this || rotate) && this.group != BlockGroup.none && other.group == this.group; - } - - public float handleDamage(Tile tile, float amount){ - return amount; - } - - public void handleBulletHit(TileEntity entity, Bullet bullet){ - entity.damage(bullet.getDamage()); - } - - public void update(Tile tile){} - - public boolean isAccessible(){ - return (hasItems && itemCapacity > 0); - } - - /**Called after the block is destroyed and removed.*/ - public void afterDestroyed(Tile tile, TileEntity entity){ - - } - - /**Called when the block is destroyed.*/ - public void onDestroyed(Tile tile){ - float x = tile.worldx(), y = tile.worldy(); - float explosiveness = baseExplosiveness; - float flammability = 0f; - float power = 0f; - int units = 1; - tempColor.set(Palette.darkFlame); - - if(hasItems){ - for(Item item : Item.all()){ - int amount = tile.entity.items.get(item); - explosiveness += item.explosiveness*amount; - flammability += item.flammability*amount; - - if(item.flammability*amount > 0.5){ - units ++; - Hue.addu(tempColor, item.flameColor); - } - } - } - - if(hasLiquids){ - flammability += tile.entity.liquids.sum((liquid, amount) -> liquid.explosiveness * amount/2f); - explosiveness += tile.entity.liquids.sum((liquid, amount) -> liquid.flammability * amount/2f); - } - - if(hasPower){ - power += tile.entity.power.amount; - } - - tempColor.mul(1f/units); - - if(hasLiquids) { - - tile.entity.liquids.forEach((liquid, amount) -> { - float splash = Mathf.clamp(amount / 4f, 0f, 10f); - - for (int i = 0; i < Mathf.clamp(amount / 5, 0, 30); i++) { - Timers.run(i / 2, () -> { - Tile other = world.tile(tile.x + Mathf.range(size / 2), tile.y + Mathf.range(size / 2)); - if (other != null) { - Puddle.deposit(other, liquid, splash); - } - }); - } - }); - } - - Damage.dynamicExplosion(x, y, flammability, explosiveness, power, tilesize * size/2f, tempColor); - if(!tile.floor().solid && !tile.floor().isLiquid){ - RubbleDecal.create(tile.drawx(), tile.drawy(), size); - } - } - - /**Returns the flammability of the tile. Used for fire calculations. - * Takes flammability of floor liquid into account.*/ - public float getFlammability(Tile tile){ - if(!hasItems || tile.entity == null){ - if(tile.floor().isLiquid && !solid){ - return tile.floor().liquidDrop.flammability; - } - return 0; - }else{ - float result = tile.entity.items.sum((item, amount) -> item.flammability * amount); - - if(hasLiquids){ - result += tile.entity.liquids.sum((liquid, amount) -> liquid.flammability * amount/3f); - } - - return result; - } - } - - public TextureRegion getEditorIcon(){ - if(editorIcon == null){ - editorIcon = Draw.region("block-icon-" + name, Draw.region("clear")); - } - return editorIcon; - } - - /**Returns the icon used for displaying this block in the place menu*/ - public TextureRegion[] getIcon(){ - if(icon == null) { - if (Draw.hasRegion(name + "-icon")) { - icon = new TextureRegion[]{Draw.region(name + "-icon")}; - } else if (Draw.hasRegion(name)){ - icon = new TextureRegion[]{Draw.region(name)}; - } else if (Draw.hasRegion(name + "1")) { - icon = new TextureRegion[]{Draw.region(name + "1")}; - }else{ - icon = new TextureRegion[]{}; - } + if(map.containsKey(name)){ + throw new RuntimeException("Two blocks cannot have the same names! Problematic block: " + name); } - return icon; - } - - /**Returns a list of regions that represent this block in the world*/ - public TextureRegion[] getBlockIcon(){ - return getIcon(); + map.put(name, this); + blocks.add(this); } - /**Returns a list of icon regions that have been cropped to 8x8*/ - public TextureRegion[] getCompactIcon(){ - if(compactIcon == null) { - compactIcon = new TextureRegion[getIcon().length]; - for (int i = 0; i < compactIcon.length; i++) { - compactIcon[i] = iconRegion(getIcon()[i]); - } - } - return compactIcon; - } + public static Array all(){ + return blocks; + } - /**Crops a regionto 8x8*/ - protected TextureRegion iconRegion(TextureRegion src){ + public static Block getByName(String name){ + return map.get(name); + } + + public static Block getByID(int id){ + if(id < 0){ //offset negative values by 256, as they are a product of byte overflow + id += 256; + } + if(id >= blocks.size || id < 0){ + throw new RuntimeException("No block with ID '" + id + "' found!"); + } + return blocks.get(id); + } + + public boolean isLayer(Tile tile){ + return true; + } + + public boolean isLayer2(Tile tile){ + return true; + } + + public void drawLayer(Tile tile){ + } + + public void drawLayer2(Tile tile){ + } + + /** Draw the block overlay that is shown when a cursor is over the block. */ + public void drawSelect(Tile tile){ + } + + /** Drawn when you are placing a block. */ + public void drawPlace(int x, int y, int rotation, boolean valid){ + } + + /** Called after the block is placed. */ + public void placed(Tile tile){ + } + + /** Called every frame a unit is on this tile. */ + public void unitOn(Tile tile, Unit unit){ + } + + /** Returns whether ot not this block can be place on the specified tile. */ + public boolean canPlaceOn(Tile tile){ + return true; + } + + /** Called after all blocks are created. */ + @Override + public void init(){ + //initialize default health based on size + if(health == -1){ + health = size * size * 40; + } + + setStats(); + setBars(); + + consumes.checkRequired(this); + } + + @Override + public void load(){ + shadowRegion = Draw.region(shadow == null ? "shadow-" + size : shadow); + region = Draw.region(name); + } + + /** Called when the block is tapped. */ + public void tapped(Tile tile, Player player){ + + } + + /** Returns whether or not a hand cursor should be shown over this block. */ + public CursorType getCursor(Tile tile){ + return configurable ? CursorType.hand : CursorType.normal; + } + + /** + * Called when this block is tapped to build a UI on the table. + * {@link #configurable} able} must return true for this to be called. + */ + public void buildTable(Tile tile, Table table){ + } + + /** + * Called when another tile is tapped while this block is selected. + * Returns whether or not this block should be deselected. + */ + public boolean onConfigureTileTapped(Tile tile, Tile other){ + return tile != other; + } + + /** Returns whether this config menu should show when the specified player taps it. */ + public boolean shouldShowConfigure(Tile tile, Player player){ + return true; + } + + /** Whether this configuration should be hidden now. Called every frame the config is open. */ + public boolean shouldHideConfigure(Tile tile, Player player){ + return false; + } + + public boolean synthetic(){ + return update || destructible || solid; + } + + public void drawConfigure(Tile tile){ + Draw.color(Palette.accent); + Lines.stroke(1f); + Lines.square(tile.drawx(), tile.drawy(), + tile.block().size * tilesize / 2f + 1f); + Draw.reset(); + } + + public void setStats(){ + stats.add(BlockStat.size, "{0}x{0}", size); + stats.add(BlockStat.health, health, StatUnit.none); + + consumes.forEach(cons -> cons.display(stats)); + + if(hasPower) stats.add(BlockStat.powerCapacity, powerCapacity, StatUnit.powerUnits); + if(hasLiquids) stats.add(BlockStat.liquidCapacity, liquidCapacity, StatUnit.liquidUnits); + if(hasItems) stats.add(BlockStat.itemCapacity, itemCapacity, StatUnit.items); + } + + //TODO make this easier to config. + public void setBars(){ + if(hasPower) bars.add(new BlockBar(BarType.power, true, tile -> tile.entity.power.amount / powerCapacity)); + if(hasLiquids) + bars.add(new BlockBar(BarType.liquid, true, tile -> tile.entity.liquids.total() / liquidCapacity)); + if(hasItems) + bars.add(new BlockBar(BarType.inventory, true, tile -> (float) tile.entity.items.total() / itemCapacity)); + } + + public String name(){ + return name; + } + + public boolean isSolidFor(Tile tile){ + return false; + } + + public boolean canReplace(Block other){ + return (other != this || rotate) && this.group != BlockGroup.none && other.group == this.group; + } + + public float handleDamage(Tile tile, float amount){ + return amount; + } + + public void handleBulletHit(TileEntity entity, Bullet bullet){ + entity.damage(bullet.getDamage()); + } + + public void update(Tile tile){ + } + + public boolean isAccessible(){ + return (hasItems && itemCapacity > 0); + } + + /** Called after the block is destroyed and removed. */ + public void afterDestroyed(Tile tile, TileEntity entity){ + + } + + /** Called when the block is destroyed. */ + public void onDestroyed(Tile tile){ + float x = tile.worldx(), y = tile.worldy(); + float explosiveness = baseExplosiveness; + float flammability = 0f; + float power = 0f; + int units = 1; + tempColor.set(Palette.darkFlame); + + if(hasItems){ + for(Item item : Item.all()){ + int amount = tile.entity.items.get(item); + explosiveness += item.explosiveness * amount; + flammability += item.flammability * amount; + + if(item.flammability * amount > 0.5){ + units++; + Hue.addu(tempColor, item.flameColor); + } + } + } + + if(hasLiquids){ + flammability += tile.entity.liquids.sum((liquid, amount) -> liquid.explosiveness * amount / 2f); + explosiveness += tile.entity.liquids.sum((liquid, amount) -> liquid.flammability * amount / 2f); + } + + if(hasPower){ + power += tile.entity.power.amount; + } + + tempColor.mul(1f / units); + + if(hasLiquids){ + + tile.entity.liquids.forEach((liquid, amount) -> { + float splash = Mathf.clamp(amount / 4f, 0f, 10f); + + for(int i = 0; i < Mathf.clamp(amount / 5, 0, 30); i++){ + Timers.run(i / 2, () -> { + Tile other = world.tile(tile.x + Mathf.range(size / 2), tile.y + Mathf.range(size / 2)); + if(other != null){ + Puddle.deposit(other, liquid, splash); + } + }); + } + }); + } + + Damage.dynamicExplosion(x, y, flammability, explosiveness, power, tilesize * size / 2f, tempColor); + if(!tile.floor().solid && !tile.floor().isLiquid){ + RubbleDecal.create(tile.drawx(), tile.drawy(), size); + } + } + + /** + * Returns the flammability of the tile. Used for fire calculations. + * Takes flammability of floor liquid into account. + */ + public float getFlammability(Tile tile){ + if(!hasItems || tile.entity == null){ + if(tile.floor().isLiquid && !solid){ + return tile.floor().liquidDrop.flammability; + } + return 0; + }else{ + float result = tile.entity.items.sum((item, amount) -> item.flammability * amount); + + if(hasLiquids){ + result += tile.entity.liquids.sum((liquid, amount) -> liquid.flammability * amount / 3f); + } + + return result; + } + } + + public TextureRegion getEditorIcon(){ + if(editorIcon == null){ + editorIcon = Draw.region("block-icon-" + name, Draw.region("clear")); + } + return editorIcon; + } + + /** Returns the icon used for displaying this block in the place menu */ + public TextureRegion[] getIcon(){ + if(icon == null){ + if(Draw.hasRegion(name + "-icon")){ + icon = new TextureRegion[]{Draw.region(name + "-icon")}; + }else if(Draw.hasRegion(name)){ + icon = new TextureRegion[]{Draw.region(name)}; + }else if(Draw.hasRegion(name + "1")){ + icon = new TextureRegion[]{Draw.region(name + "1")}; + }else{ + icon = new TextureRegion[]{}; + } + } + + return icon; + } + + /** Returns a list of regions that represent this block in the world */ + public TextureRegion[] getBlockIcon(){ + return getIcon(); + } + + /** Returns a list of icon regions that have been cropped to 8x8 */ + public TextureRegion[] getCompactIcon(){ + if(compactIcon == null){ + compactIcon = new TextureRegion[getIcon().length]; + for(int i = 0; i < compactIcon.length; i++){ + compactIcon[i] = iconRegion(getIcon()[i]); + } + } + return compactIcon; + } + + /** Crops a regionto 8x8 */ + protected TextureRegion iconRegion(TextureRegion src){ TextureRegion region = new TextureRegion(src); region.setRegionWidth(8); region.setRegionHeight(8); @@ -386,76 +425,59 @@ public class Block extends BaseBlock implements Content{ } public boolean hasEntity(){ - return destructible || update; - } - - public TileEntity getEntity(){ - return new TileEntity(); - } - - public void draw(Tile tile){ - Draw.rect(region, tile.drawx(), tile.drawy(), rotate ? tile.getRotation() * 90 : 0); - } + return destructible || update; + } - public void drawNonLayer(Tile tile){} - - public void drawShadow(Tile tile){ - Draw.rect(shadowRegion, tile.drawx(), tile.drawy()); - } - - /**Offset for placing and drawing multiblocks.*/ - public float offset(){ - return ((size + 1) % 2) * tilesize/2; - } - - public boolean isMultiblock(){ - return size > 1; - } + public TileEntity getEntity(){ + return new TileEntity(); + } - public Array getDebugInfo(Tile tile){ - return Array.with( - "block", tile.block().name, - "floor", tile.floor().name, - "x", tile.x, - "y", tile.y, - "entity.name", ClassReflection.getSimpleName(tile.entity.getClass()), - "entity.x", tile.entity.x, - "entity.y", tile.entity.y, - "entity.id", tile.entity.id, - "entity.items.total", hasItems ? tile.entity.items.total() : null - ); - } + public void draw(Tile tile){ + Draw.rect(region, tile.drawx(), tile.drawy(), rotate ? tile.getRotation() * 90 : 0); + } - @Override - public String getContentTypeName() { - return "block"; - } + public void drawNonLayer(Tile tile){ + } - @Override - public Array getAll() { - return all(); - } + public void drawShadow(Tile tile){ + Draw.rect(shadowRegion, tile.drawx(), tile.drawy()); + } - @Override - public String toString(){ - return name; - } + /** Offset for placing and drawing multiblocks. */ + public float offset(){ + return ((size + 1) % 2) * tilesize / 2; + } - public static Array all(){ - return blocks; - } + public boolean isMultiblock(){ + return size > 1; + } - public static Block getByName(String name){ - return map.get(name); - } + public Array getDebugInfo(Tile tile){ + return Array.with( + "block", tile.block().name, + "floor", tile.floor().name, + "x", tile.x, + "y", tile.y, + "entity.name", ClassReflection.getSimpleName(tile.entity.getClass()), + "entity.x", tile.entity.x, + "entity.y", tile.entity.y, + "entity.id", tile.entity.id, + "entity.items.total", hasItems ? tile.entity.items.total() : null + ); + } - public static Block getByID(int id){ - if(id < 0){ //offset negative values by 256, as they are a product of byte overflow - id += 256; - } - if(id >= blocks.size || id < 0){ - throw new RuntimeException("No block with ID '" + id + "' found!"); - } - return blocks.get(id); - } -} + @Override + public String getContentTypeName(){ + return "block"; + } + + @Override + public Array getAll(){ + return all(); + } + + @Override + public String toString(){ + return name; + } +} \ No newline at end of file diff --git a/core/src/io/anuke/mindustry/world/Build.java b/core/src/io/anuke/mindustry/world/Build.java index aa075581ae..d0fab8e84e 100644 --- a/core/src/io/anuke/mindustry/world/Build.java +++ b/core/src/io/anuke/mindustry/world/Build.java @@ -12,11 +12,13 @@ import io.anuke.ucore.entities.Entities; import static io.anuke.mindustry.Vars.*; -public class Build { +public class Build{ private static final Rectangle rect = new Rectangle(); private static final Rectangle hitrect = new Rectangle(); - /**Returns block type that was broken, or null if unsuccesful.*/ + /** + * Returns block type that was broken, or null if unsuccesful. + */ //@Remote(targets = Loc.both, forward = true, called = Loc.server, in = In.blocks) public static void beginBreak(Team team, int x, int y){ if(!validBreak(team, x, y)){ @@ -38,17 +40,17 @@ public class Build { tile.entity().setDeconstruct(previous); tile.setTeam(team); - if (previous.isMultiblock()) { + if(previous.isMultiblock()){ int offsetx = -(previous.size - 1) / 2; int offsety = -(previous.size - 1) / 2; - for (int dx = 0; dx < previous.size; dx++) { - for (int dy = 0; dy < previous.size; dy++) { + for(int dx = 0; dx < previous.size; dx++){ + for(int dy = 0; dy < previous.size; dy++){ int worldx = dx + offsetx + x; int worldy = dy + offsety + y; - if (!(worldx == x && worldy == y)) { + if(!(worldx == x && worldy == y)){ Tile toplace = world.tile(worldx, worldy); - if (toplace != null) { + if(toplace != null){ toplace.setLinked((byte) (dx + offsetx), (byte) (dy + offsety)); toplace.setTeam(team); } @@ -59,7 +61,9 @@ public class Build { } - /**Places a BuildBlock at this location.*/ + /** + * Places a BuildBlock at this location. + */ //@Remote(targets = Loc.both, forward = true, called = Loc.server, in = In.blocks) public static void beginPlace(Team team, int x, int y, Recipe recipe, int rotation){ if(!validPlace(team, x, y, recipe.result, rotation)){ @@ -80,17 +84,17 @@ public class Build { tile.entity().setConstruct(previous, recipe); tile.setTeam(team); - if (result.isMultiblock()) { + if(result.isMultiblock()){ int offsetx = -(result.size - 1) / 2; int offsety = -(result.size - 1) / 2; - for (int dx = 0; dx < result.size; dx++) { - for (int dy = 0; dy < result.size; dy++) { + for(int dx = 0; dx < result.size; dx++){ + for(int dy = 0; dy < result.size; dy++){ int worldx = dx + offsetx + x; int worldy = dy + offsety + y; - if (!(worldx == x && worldy == y)) { + if(!(worldx == x && worldy == y)){ Tile toplace = world.tile(worldx, worldy); - if (toplace != null) { + if(toplace != null){ toplace.setLinked((byte) (dx + offsetx), (byte) (dy + offsety)); toplace.setTeam(team); } @@ -103,35 +107,37 @@ public class Build { threads.runDelay(() -> Events.fire(BlockBuildEvent.class, team, tile)); } - /**Returns whether a tile can be placed at this location by this team.*/ - public static boolean validPlace(Team team, int x, int y, Block type, int rotation) { + /** + * Returns whether a tile can be placed at this location by this team. + */ + public static boolean validPlace(Team team, int x, int y, Block type, int rotation){ Recipe recipe = Recipe.getByResult(type); - if (recipe == null || (recipe.debugOnly && !debug)) { + if(recipe == null || (recipe.debugOnly && !debug)){ return false; } rect.setSize(type.size * tilesize, type.size * tilesize); rect.setCenter(type.offset() + x * tilesize, type.offset() + y * tilesize); - if (type.solid || type.solidifes) { - synchronized (Entities.entityLock) { - try { + if(type.solid || type.solidifes){ + synchronized(Entities.entityLock){ + try{ rect.setSize(tilesize * type.size).setCenter(x * tilesize + type.offset(), y * tilesize + type.offset()); boolean[] result = {false}; Units.getNearby(rect, e -> { - if (e == null) return; //not sure why this happens? + if(e == null) return; //not sure why this happens? e.getHitbox(hitrect); - if (rect.overlaps(hitrect) && !e.isFlying()) { + if(rect.overlaps(hitrect) && !e.isFlying()){ result[0] = true; } }); - if (result[0]) return false; - } catch (Exception e) { + if(result[0]) return false; + }catch(Exception e){ return false; } } @@ -139,10 +145,10 @@ public class Build { Tile tile = world.tile(x, y); - if (tile == null) return false; + if(tile == null) return false; - if (type.isMultiblock()) { - if (type.canReplace(tile.block()) && tile.block().size == type.size) { + if(type.isMultiblock()){ + if(type.canReplace(tile.block()) && tile.block().size == type.size){ return true; } @@ -152,18 +158,18 @@ public class Build { int offsetx = -(type.size - 1) / 2; int offsety = -(type.size - 1) / 2; - for (int dx = 0; dx < type.size; dx++) { - for (int dy = 0; dy < type.size; dy++) { + for(int dx = 0; dx < type.size; dx++){ + for(int dy = 0; dy < type.size; dy++){ Tile other = world.tile(x + dx + offsetx, y + dy + offsety); - if (other == null || (other.block() != Blocks.air && !other.block().alwaysReplace) - || other.cliffs != 0 || !other.floor().placeableOn || - (tile.floor().liquidDrop != null && !type.floating)) { + if(other == null || (other.block() != Blocks.air && !other.block().alwaysReplace) + || other.cliffs != 0 || !other.floor().placeableOn || + (tile.floor().liquidDrop != null && !type.floating)){ return false; } } } return true; - } else { + }else{ return (tile.getTeam() == Team.none || tile.getTeam() == team) && (tile.floor().liquidDrop == null || type.floating) && tile.floor().placeableOn && tile.cliffs == 0 @@ -173,8 +179,10 @@ public class Build { } } - /**Returns whether the tile at this position is breakable by this team*/ - public static boolean validBreak(Team team, int x, int y) { + /** + * Returns whether the tile at this position is breakable by this team + */ + public static boolean validBreak(Team team, int x, int y){ Tile tile = world.tile(x, y); return tile != null && !tile.block().unbreakable diff --git a/core/src/io/anuke/mindustry/world/ColorMapper.java b/core/src/io/anuke/mindustry/world/ColorMapper.java index 74b20c6308..012caefe05 100644 --- a/core/src/io/anuke/mindustry/world/ColorMapper.java +++ b/core/src/io/anuke/mindustry/world/ColorMapper.java @@ -8,30 +8,30 @@ import io.anuke.mindustry.game.Content; import io.anuke.mindustry.type.ContentList; public class ColorMapper implements ContentList{ - private static IntMap blockMap = new IntMap<>(); - private static ObjectIntMap colorMap = new ObjectIntMap<>(); + private static IntMap blockMap = new IntMap<>(); + private static ObjectIntMap colorMap = new ObjectIntMap<>(); - @Override - public void load() { - for(Block block : Block.all()){ - int color = Color.rgba8888(block.minimapColor); - if(color == 0) continue; //skip blocks that are not mapped + public static Block getByColor(int color){ + return blockMap.get(color); + } - blockMap.put(color, block); - colorMap.put(block, color); - } - } + public static int getBlockColor(Block block){ + return colorMap.get(block, 0); + } - @Override - public Array getAll() { - return new Array<>(); - } + @Override + public void load(){ + for(Block block : Block.all()){ + int color = Color.rgba8888(block.minimapColor); + if(color == 0) continue; //skip blocks that are not mapped - public static Block getByColor(int color){ - return blockMap.get(color); - } + blockMap.put(color, block); + colorMap.put(block, color); + } + } - public static int getBlockColor(Block block){ - return colorMap.get(block, 0); - } + @Override + public Array getAll(){ + return new Array<>(); + } } diff --git a/core/src/io/anuke/mindustry/world/Edges.java b/core/src/io/anuke/mindustry/world/Edges.java index f8f0fe045b..6c0bbbdc94 100644 --- a/core/src/io/anuke/mindustry/world/Edges.java +++ b/core/src/io/anuke/mindustry/world/Edges.java @@ -9,57 +9,58 @@ import java.util.Arrays; import static io.anuke.mindustry.Vars.world; -public class Edges { +public class Edges{ private static final int maxSize = 11; private static final int maxRadius = 12; private static GridPoint2[][] edges = new GridPoint2[maxSize][0]; private static GridPoint2[][] edgeInside = new GridPoint2[maxSize][0]; - private static Vector2[][] polygons = new Vector2[maxRadius*2][0]; + private static Vector2[][] polygons = new Vector2[maxRadius * 2][0]; static{ - for(int i = 0; i < maxRadius*2; i ++){ - polygons[i] = Geometry.pixelCircle((i + 1)/2f); + for(int i = 0; i < maxRadius * 2; i++){ + polygons[i] = Geometry.pixelCircle((i + 1) / 2f); } - for(int i = 0; i < maxSize; i ++){ - int bot = -(int)(i/2f) - 1; - int top = (int)(i/2f+0.5f) + 1; + for(int i = 0; i < maxSize; i++){ + int bot = -(int) (i / 2f) - 1; + int top = (int) (i / 2f + 0.5f) + 1; edges[i] = new GridPoint2[(i + 1) * 4]; int idx = 0; - for(int j = 0; j < i + 1; j ++){ + for(int j = 0; j < i + 1; j++){ //bottom - edges[i][idx ++] = new GridPoint2(bot + 1 + j, bot); + edges[i][idx++] = new GridPoint2(bot + 1 + j, bot); //top - edges[i][idx ++] = new GridPoint2(bot + 1 + j, top); + edges[i][idx++] = new GridPoint2(bot + 1 + j, top); //left - edges[i][idx ++] = new GridPoint2(bot, bot + j + 1); + edges[i][idx++] = new GridPoint2(bot, bot + j + 1); //right - edges[i][idx ++] = new GridPoint2(top, bot + j + 1); + edges[i][idx++] = new GridPoint2(top, bot + j + 1); } Arrays.sort(edges[i], (e1, e2) -> Float.compare(Mathf.atan2(e1.x, e1.y), Mathf.atan2(e2.x, e2.y))); edgeInside[i] = new GridPoint2[edges[i].length]; - for(int j = 0; j < edges[i].length; j ++){ + for(int j = 0; j < edges[i].length; j++){ GridPoint2 point = edges[i][j]; - edgeInside[i][j] = new GridPoint2(Mathf.clamp(point.x, -(int)((i)/2f), (int)(i/2f + 0.5f)), - Mathf.clamp(point.y, -(int)((i)/2f), (int)(i/2f + 0.5f))); + edgeInside[i][j] = new GridPoint2(Mathf.clamp(point.x, -(int) ((i) / 2f), (int) (i / 2f + 0.5f)), + Mathf.clamp(point.y, -(int) ((i) / 2f), (int) (i / 2f + 0.5f))); } } } public static Tile getFacingEdge(Tile tile, Tile other){ int size = tile.block().size; - return world.tile(tile.x + Mathf.clamp(other.x - tile.x, -(size-1) / 2, (size / 2)), - tile.y + Mathf.clamp(other.y - tile.y, -(size-1) / 2, (size / 2))); + return world.tile(tile.x + Mathf.clamp(other.x - tile.x, -(size - 1) / 2, (size / 2)), + tile.y + Mathf.clamp(other.y - tile.y, -(size - 1) / 2, (size / 2))); } public static Vector2[] getPixelPolygon(float radius){ - if(radius < 1 || radius > maxRadius) throw new RuntimeException("Polygon size must be between 1 and " + maxRadius); - return polygons[(int)(radius*2) - 1]; + if(radius < 1 || radius > maxRadius) + throw new RuntimeException("Polygon size must be between 1 and " + maxRadius); + return polygons[(int) (radius * 2) - 1]; } public static synchronized GridPoint2[] getEdges(int size){ diff --git a/core/src/io/anuke/mindustry/world/ItemBuffer.java b/core/src/io/anuke/mindustry/world/ItemBuffer.java index d09583d6d1..d3ba23f394 100644 --- a/core/src/io/anuke/mindustry/world/ItemBuffer.java +++ b/core/src/io/anuke/mindustry/world/ItemBuffer.java @@ -5,7 +5,7 @@ import io.anuke.mindustry.type.Item; import io.anuke.ucore.core.Timers; import io.anuke.ucore.util.Bits; -public class ItemBuffer { +public class ItemBuffer{ private final float speed; private long[] buffer; @@ -22,11 +22,11 @@ public class ItemBuffer { public void accept(Item item, short data){ //if(!accepts()) return; - buffer[index ++] = Bits.packLong(NumberUtils.floatToIntBits(Timers.time()), Bits.packInt((short)item.id, data)); + buffer[index++] = Bits.packLong(NumberUtils.floatToIntBits(Timers.time()), Bits.packInt((short) item.id, data)); } public void accept(Item item){ - accept(item, (short)-1); + accept(item, (short) -1); } public Item poll(){ @@ -55,6 +55,6 @@ public class ItemBuffer { public void remove(){ System.arraycopy(buffer, 1, buffer, 0, index - 1); - index --; + index--; } } diff --git a/core/src/io/anuke/mindustry/world/Tile.java b/core/src/io/anuke/mindustry/world/Tile.java index 28b0fd0217..4ea601b896 100644 --- a/core/src/io/anuke/mindustry/world/Tile.java +++ b/core/src/io/anuke/mindustry/world/Tile.java @@ -24,419 +24,426 @@ import static io.anuke.mindustry.Vars.tilesize; import static io.anuke.mindustry.Vars.world; -public class Tile implements PosTrait, TargetTrait { - public static final Object tileSetLock = new Object(); - - /**Block ID data.*/ - private Block wall; - private Floor floor; - /**Rotation, 0-3. Also used to store offload location for routers, in which case it can be any number.*/ - private byte rotation; - /**Team ordinal.*/ - private byte team; - /**The coordinates of the core tile this is linked to, in the form of two bytes packed into one. - * This is relative to the block it is linked to; negate coords to find the link.*/ - public byte link = 0; - public short x, y; - /**Tile traversal cost.*/ - public byte cost = 1; - /**Elevation of tile.*/ - public byte elevation; - /**Position of cliffs around the tile, packed into bits 0-8.*/ - public byte cliffs; - /**Tile entity, usually null.*/ - public TileEntity entity; - - public Tile(int x, int y){ - this.x = (short)x; - this.y = (short)y; - } +public class Tile implements PosTrait, TargetTrait{ + public static final Object tileSetLock = new Object(); + /** + * The coordinates of the core tile this is linked to, in the form of two bytes packed into one. + * This is relative to the block it is linked to; negate coords to find the link. + */ + public byte link = 0; + public short x, y; + /** Tile traversal cost. */ + public byte cost = 1; + /** Elevation of tile. */ + public byte elevation; + /** Position of cliffs around the tile, packed into bits 0-8. */ + public byte cliffs; + /** Tile entity, usually null. */ + public TileEntity entity; + /** Block ID data. */ + private Block wall; + private Floor floor; + /** Rotation, 0-3. Also used to store offload location for routers, in which case it can be any number. */ + private byte rotation; + /** Team ordinal. */ + private byte team; - public Tile(int x, int y, byte floor, byte wall){ - this(x, y); - this.floor = (Floor) Block.getByID(floor); - this.wall = Block.getByID(wall); - changed(); - } - - public Tile(int x, int y, byte floor, byte wall, byte rotation, byte team, byte elevation){ - this(x, y); - this.floor =(Floor) Block.getByID(floor); - this.wall = Block.getByID(wall); - this.rotation = rotation; - this.elevation = elevation; - changed(); - this.team = team; - } + public Tile(int x, int y){ + this.x = (short) x; + this.y = (short) y; + } - public int packedPosition(){ - return x + y * world.width(); - } - - public byte getWallID(){ - return (byte)wall.id; - } - - public byte getFloorID(){ - return (byte)floor.id; - } - - /**Return relative rotation to a coordinate. Returns -1 if the coordinate is not near this tile.*/ - public byte relativeTo(int cx, int cy){ - if(x == cx && y == cy - 1) return 1; - if(x == cx && y == cy + 1) return 3; - if(x == cx - 1 && y == cy) return 0; - if(x == cx + 1 && y == cy) return 2; - return -1; - } + public Tile(int x, int y, byte floor, byte wall){ + this(x, y); + this.floor = (Floor) Block.getByID(floor); + this.wall = Block.getByID(wall); + changed(); + } - public byte absoluteRelativeTo(int cx, int cy){ - if(x == cx && y <= cy - 1) return 1; - if(x == cx && y >= cy + 1) return 3; - if(x <= cx - 1 && y == cy) return 0; - if(x >= cx + 1 && y == cy) return 2; - return -1; - } + public Tile(int x, int y, byte floor, byte wall, byte rotation, byte team, byte elevation){ + this(x, y); + this.floor = (Floor) Block.getByID(floor); + this.wall = Block.getByID(wall); + this.rotation = rotation; + this.elevation = elevation; + changed(); + this.team = team; + } - public byte sizedRelativeTo(int cx, int cy){ - if(x == cx && y == cy - 1 - block().size/2) return 1; - if(x == cx && y == cy + 1 + block().size/2) return 3; - if(x == cx - 1 - block().size/2 && y == cy) return 0; - if(x == cx + 1 + block().size/2 && y == cy) return 2; - return -1; - } - - public T entity(){ - return (T)entity; - } - - public int id(){ - return x + y * world.width(); - } - - public float worldx(){ - return x * tilesize; - } - - public float worldy(){ - return y * tilesize; - } + public int packedPosition(){ + return x + y * world.width(); + } - public float drawx(){ - return block().offset() + worldx(); - } + public byte getWallID(){ + return (byte) wall.id; + } - public float drawy(){ - return block().offset() + worldy(); - } - - public Floor floor(){ - return floor; - } - - public Block block(){ - return wall; - } + public byte getFloorID(){ + return (byte) floor.id; + } - public Team getTeam(){ - return Team.all[team]; - } + /** Return relative rotation to a coordinate. Returns -1 if the coordinate is not near this tile. */ + public byte relativeTo(int cx, int cy){ + if(x == cx && y == cy - 1) return 1; + if(x == cx && y == cy + 1) return 3; + if(x == cx - 1 && y == cy) return 0; + if(x == cx + 1 && y == cy) return 2; + return -1; + } - public byte getTeamID(){ - return team; - } + public byte absoluteRelativeTo(int cx, int cy){ + if(x == cx && y <= cy - 1) return 1; + if(x == cx && y >= cy + 1) return 3; + if(x <= cx - 1 && y == cy) return 0; + if(x >= cx + 1 && y == cy) return 2; + return -1; + } - public void setTeam(Team team){ - this.team = (byte)team.ordinal(); - } - - /**Returns the break time of the block, or the breaktime of the linked block, if this tile is linked.*/ - public float getBreakTime(){ - Block block = target().block(); - if(Recipe.getByResult(block) != null){ - return Recipe.getByResult(block).cost; - }else{ - return 15f; - } - } - - public void setBlock(Block type, int rotation){ - synchronized (tileSetLock) { - preChanged(); - if(rotation < 0) rotation = (-rotation + 2); - this.wall = type; - this.link = 0; - setRotation((byte) (rotation % 4)); - changed(); - } - } - - public void setBlock(Block type){ - synchronized (tileSetLock) { - preChanged(); - this.wall = type; - this.link = 0; - changed(); - } - } - - public void setFloor(Floor type){ - this.floor = type; - } - - public void setRotation(byte rotation){ - this.rotation = rotation; - } - - public void setDump(byte dump){ - this.rotation = dump; - } - - public byte getRotation(){ - return rotation; - } - - public byte getDump(){ - return rotation; - } + public byte sizedRelativeTo(int cx, int cy){ + if(x == cx && y == cy - 1 - block().size / 2) return 1; + if(x == cx && y == cy + 1 + block().size / 2) return 3; + if(x == cx - 1 - block().size / 2 && y == cy) return 0; + if(x == cx + 1 + block().size / 2 && y == cy) return 2; + return -1; + } - public boolean passable(){ - Block block = block(); - Block floor = floor(); - return isLinked() || !((floor.solid && (block == Blocks.air || block.solidifes)) || (block.solid && (!block.destructible && !block.update))); - } + public T entity(){ + return (T) entity; + } - /**Whether this block was placed by a player/unit.*/ - public boolean synthetic(){ - Block block = block(); - return block.update || block.destructible; - } - - public boolean solid(){ - Block block = block(); - Block floor = floor(); - return block.solid || cliffs != 0 || (floor.solid && (block == Blocks.air || block.solidifes)) || block.isSolidFor(this) - || (isLinked() && getLinked().block().isSolidFor(getLinked())); - } - - public boolean breakable(){ - Block block = block(); - if(link == 0){ - return (block.destructible || block.breakable || block.update); - }else{ - return getLinked().breakable(); - } - } - - public boolean isLinked(){ - return link != 0; - } - - /**Sets this to a linked tile, which sets the block to a blockpart. dx and dy can only be -8-7.*/ - public void setLinked(byte dx, byte dy){ - setBlock(Blocks.blockpart); - link = Bits.packByte((byte)(dx + 8), (byte)(dy + 8)); - } - - /**Returns the list of all tiles linked to this multiblock, or an empty array if it's not a multiblock. - * This array contains all linked tiles, including this tile itself.*/ - public synchronized Array getLinkedTiles(Array tmpArray){ - Block block = block(); - tmpArray.clear(); - if(block.isMultiblock()){ - int offsetx = -(block.size-1)/2; - int offsety = -(block.size-1)/2; - for(int dx = 0; dx < block.size; dx ++){ - for(int dy = 0; dy < block.size; dy ++){ - Tile other = world.tile(x + dx + offsetx, y + dy + offsety); - tmpArray.add(other); - } - } - }else{ - tmpArray.add(this); - } - return tmpArray; - } + public int id(){ + return x + y * world.width(); + } - /**Returns the list of all tiles linked to this multiblock if it were this block, or an empty array if it's not a multiblock. - * This array contains all linked tiles, including this tile itself.*/ - public synchronized Array getLinkedTilesAs(Block block, Array tmpArray){ - tmpArray.clear(); - if(block.isMultiblock()){ - int offsetx = -(block.size-1)/2; - int offsety = -(block.size-1)/2; - for(int dx = 0; dx < block.size; dx ++){ - for(int dy = 0; dy < block.size; dy ++){ - Tile other = world.tile(x + dx + offsetx, y + dy + offsety); - tmpArray.add(other); - } - } - }else{ - tmpArray.add(this); - } - return tmpArray; - } - - /**Returns the block the multiblock is linked to, or null if it is not linked to any block.*/ - public Tile getLinked(){ - if(link == 0){ - return null; - }else{ - byte dx = Bits.getLeftByte(link); - byte dy = Bits.getRightByte(link); - return world.tile(x - (dx - 8), y - (dy - 8)); - } - } + public float worldx(){ + return x * tilesize; + } - public void allNearby(Consumer cons){ - for(GridPoint2 point : Edges.getEdges(block().size)){ - Tile tile = world.tile(x + point.x, y + point.y); - if(tile != null){ - cons.accept(tile.target()); - } - } - } + public float worldy(){ + return y * tilesize; + } - public void allInside(Consumer cons){ - for(GridPoint2 point : Edges.getInsideEdges(block().size)){ - Tile tile = world.tile(x + point.x, y + point.y); - if(tile != null){ - cons.accept(tile); - } - } - } + public float drawx(){ + return block().offset() + worldx(); + } - public Tile target(){ - Tile link = getLinked(); - return link == null ? this : link; - } + public float drawy(){ + return block().offset() + worldy(); + } - public Tile getNearby(GridPoint2 relative){ - return world.tile(x + relative.x, y + relative.y); - } + public Floor floor(){ + return floor; + } - public Tile getNearby(int dx, int dy){ - return world.tile(x + dx, y + dy); - } + public Block block(){ + return wall; + } - public Tile getNearby(int rotation){ - if(rotation == 0) return world.tile(x + 1, y); - if(rotation == 1) return world.tile(x, y + 1); - if(rotation == 2) return world.tile(x - 1, y); - if(rotation == 3) return world.tile(x, y - 1); - return null; - } + public Team getTeam(){ + return Team.all[team]; + } - public Tile[] getNearby(Tile[] temptiles){ - temptiles[0] = world.tile(x+1, y); - temptiles[1] = world.tile(x, y+1); - temptiles[2] = world.tile(x-1, y); - temptiles[3] = world.tile(x, y-1); - return temptiles; - } + public void setTeam(Team team){ + this.team = (byte) team.ordinal(); + } - public void updateOcclusion(){ - cost = 1; - cliffs = 0; - boolean occluded = false; + public byte getTeamID(){ + return team; + } - //check for occlusion - for(int i = 0; i < 8; i ++){ - GridPoint2 point = Geometry.d8[i]; - Tile tile = world.tile(x + point.x, y + point.y); - if(tile != null && tile.solid()){ - occluded = true; - break; - } - } + /** Returns the break time of the block, or the breaktime of the linked block, if this tile is linked. */ + public float getBreakTime(){ + Block block = target().block(); + if(Recipe.getByResult(block) != null){ + return Recipe.getByResult(block).cost; + }else{ + return 15f; + } + } - //check for bitmasking cliffs - for(int i = 0; i < 4; i ++){ - GridPoint2 pc = Geometry.d4[i]; - GridPoint2 pcprev = Geometry.d4[Mathf.mod(i - 1, 4)]; - GridPoint2 pcnext = Geometry.d4[(i + 1) % 4]; + public void setBlock(Block type, int rotation){ + synchronized(tileSetLock){ + preChanged(); + if(rotation < 0) rotation = (-rotation + 2); + this.wall = type; + this.link = 0; + setRotation((byte) (rotation % 4)); + changed(); + } + } - Tile tc = world.tile(x + pc.x, y + pc.y); - Tile tprev = world.tile(x + pcprev.x, y + pcprev.y); - Tile tnext = world.tile(x + pcnext.x, y + pcnext.y); + public void setBlock(Block type){ + synchronized(tileSetLock){ + preChanged(); + this.wall = type; + this.link = 0; + changed(); + } + } - //check for cardinal direction elevation changes and bitmask that - if(tc != null && tprev != null && tnext != null && ((tc.elevation < elevation && tc.elevation != -1))){ - cliffs |= (1 << (i*2)); - } - } - if(occluded){ - cost += 1; - } - } + public void setFloor(Floor type){ + this.floor = type; + } - private void preChanged(){ - synchronized (tileSetLock) { - if (entity != null) { - entity.removeFromProximity(); - } - } - } - - private void changed(){ + public byte getRotation(){ + return rotation; + } - synchronized (tileSetLock) { - if (entity != null) { - entity.remove(); - entity = null; - } + public void setRotation(byte rotation){ + this.rotation = rotation; + } - team = 0; + public byte getDump(){ + return rotation; + } - Block block = block(); + public void setDump(byte dump){ + this.rotation = dump; + } - if (block.hasEntity()) { - entity = block.getEntity().init(this, block.update); - entity.cons = new ConsumeModule(); - if(block.hasItems) entity.items = new InventoryModule(); - if(block.hasLiquids) entity.liquids = new LiquidModule(); - if(block.hasPower) entity.power = new PowerModule(); - entity.updateProximity(); - } + public boolean passable(){ + Block block = block(); + Block floor = floor(); + return isLinked() || !((floor.solid && (block == Blocks.air || block.solidifes)) || (block.solid && (!block.destructible && !block.update))); + } - updateOcclusion(); - } + /** Whether this block was placed by a player/unit. */ + public boolean synthetic(){ + Block block = block(); + return block.update || block.destructible; + } - world.notifyChanged(this); - } + public boolean solid(){ + Block block = block(); + Block floor = floor(); + return block.solid || cliffs != 0 || (floor.solid && (block == Blocks.air || block.solidifes)) || block.isSolidFor(this) + || (isLinked() && getLinked().block().isSolidFor(getLinked())); + } - @Override - public boolean isDead() { - return false; //tiles never die - } + public boolean breakable(){ + Block block = block(); + if(link == 0){ + return (block.destructible || block.breakable || block.update); + }else{ + return getLinked().breakable(); + } + } - @Override - public Vector2 getVelocity() { - return Vector2.Zero; - } + public boolean isLinked(){ + return link != 0; + } - @Override - public float getX() { - return drawx(); - } + /** Sets this to a linked tile, which sets the block to a blockpart. dx and dy can only be -8-7. */ + public void setLinked(byte dx, byte dy){ + setBlock(Blocks.blockpart); + link = Bits.packByte((byte) (dx + 8), (byte) (dy + 8)); + } - @Override - public float getY() { - return drawy(); - } + /** + * Returns the list of all tiles linked to this multiblock, or an empty array if it's not a multiblock. + * This array contains all linked tiles, including this tile itself. + */ + public synchronized Array getLinkedTiles(Array tmpArray){ + Block block = block(); + tmpArray.clear(); + if(block.isMultiblock()){ + int offsetx = -(block.size - 1) / 2; + int offsety = -(block.size - 1) / 2; + for(int dx = 0; dx < block.size; dx++){ + for(int dy = 0; dy < block.size; dy++){ + Tile other = world.tile(x + dx + offsetx, y + dy + offsety); + tmpArray.add(other); + } + } + }else{ + tmpArray.add(this); + } + return tmpArray; + } - @Override - public void setX(float x) {} + /** + * Returns the list of all tiles linked to this multiblock if it were this block, or an empty array if it's not a multiblock. + * This array contains all linked tiles, including this tile itself. + */ + public synchronized Array getLinkedTilesAs(Block block, Array tmpArray){ + tmpArray.clear(); + if(block.isMultiblock()){ + int offsetx = -(block.size - 1) / 2; + int offsety = -(block.size - 1) / 2; + for(int dx = 0; dx < block.size; dx++){ + for(int dy = 0; dy < block.size; dy++){ + Tile other = world.tile(x + dx + offsetx, y + dy + offsety); + tmpArray.add(other); + } + } + }else{ + tmpArray.add(this); + } + return tmpArray; + } - @Override - public void setY(float y) {} + /** Returns the block the multiblock is linked to, or null if it is not linked to any block. */ + public Tile getLinked(){ + if(link == 0){ + return null; + }else{ + byte dx = Bits.getLeftByte(link); + byte dy = Bits.getRightByte(link); + return world.tile(x - (dx - 8), y - (dy - 8)); + } + } - @Override - public String toString(){ - Block block = block(); - Block floor = floor(); - - return floor.name() + ":" + block.name() + "[" + x + "," + y + "] " + "entity=" + (entity == null ? "null" : ClassReflection.getSimpleName(entity.getClass())) + - (link != 0 ? " link=[" + (Bits.getLeftByte(link) - 8) + ", " + (Bits.getRightByte(link) - 8) + "]" : ""); - } -} + public void allNearby(Consumer cons){ + for(GridPoint2 point : Edges.getEdges(block().size)){ + Tile tile = world.tile(x + point.x, y + point.y); + if(tile != null){ + cons.accept(tile.target()); + } + } + } + + public void allInside(Consumer cons){ + for(GridPoint2 point : Edges.getInsideEdges(block().size)){ + Tile tile = world.tile(x + point.x, y + point.y); + if(tile != null){ + cons.accept(tile); + } + } + } + + public Tile target(){ + Tile link = getLinked(); + return link == null ? this : link; + } + + public Tile getNearby(GridPoint2 relative){ + return world.tile(x + relative.x, y + relative.y); + } + + public Tile getNearby(int dx, int dy){ + return world.tile(x + dx, y + dy); + } + + public Tile getNearby(int rotation){ + if(rotation == 0) return world.tile(x + 1, y); + if(rotation == 1) return world.tile(x, y + 1); + if(rotation == 2) return world.tile(x - 1, y); + if(rotation == 3) return world.tile(x, y - 1); + return null; + } + + public Tile[] getNearby(Tile[] temptiles){ + temptiles[0] = world.tile(x + 1, y); + temptiles[1] = world.tile(x, y + 1); + temptiles[2] = world.tile(x - 1, y); + temptiles[3] = world.tile(x, y - 1); + return temptiles; + } + + public void updateOcclusion(){ + cost = 1; + cliffs = 0; + boolean occluded = false; + + //check for occlusion + for(int i = 0; i < 8; i++){ + GridPoint2 point = Geometry.d8[i]; + Tile tile = world.tile(x + point.x, y + point.y); + if(tile != null && tile.solid()){ + occluded = true; + break; + } + } + + //check for bitmasking cliffs + for(int i = 0; i < 4; i++){ + GridPoint2 pc = Geometry.d4[i]; + GridPoint2 pcprev = Geometry.d4[Mathf.mod(i - 1, 4)]; + GridPoint2 pcnext = Geometry.d4[(i + 1) % 4]; + + Tile tc = world.tile(x + pc.x, y + pc.y); + Tile tprev = world.tile(x + pcprev.x, y + pcprev.y); + Tile tnext = world.tile(x + pcnext.x, y + pcnext.y); + + //check for cardinal direction elevation changes and bitmask that + if(tc != null && tprev != null && tnext != null && ((tc.elevation < elevation && tc.elevation != -1))){ + cliffs |= (1 << (i * 2)); + } + } + if(occluded){ + cost += 1; + } + } + + private void preChanged(){ + synchronized(tileSetLock){ + if(entity != null){ + entity.removeFromProximity(); + } + } + } + + private void changed(){ + + synchronized(tileSetLock){ + if(entity != null){ + entity.remove(); + entity = null; + } + + team = 0; + + Block block = block(); + + if(block.hasEntity()){ + entity = block.getEntity().init(this, block.update); + entity.cons = new ConsumeModule(); + if(block.hasItems) entity.items = new InventoryModule(); + if(block.hasLiquids) entity.liquids = new LiquidModule(); + if(block.hasPower) entity.power = new PowerModule(); + entity.updateProximity(); + } + + updateOcclusion(); + } + + world.notifyChanged(this); + } + + @Override + public boolean isDead(){ + return false; //tiles never die + } + + @Override + public Vector2 getVelocity(){ + return Vector2.Zero; + } + + @Override + public float getX(){ + return drawx(); + } + + @Override + public void setX(float x){ + } + + @Override + public float getY(){ + return drawy(); + } + + @Override + public void setY(float y){ + } + + @Override + public String toString(){ + Block block = block(); + Block floor = floor(); + + return floor.name() + ":" + block.name() + "[" + x + "," + y + "] " + "entity=" + (entity == null ? "null" : ClassReflection.getSimpleName(entity.getClass())) + + (link != 0 ? " link=[" + (Bits.getLeftByte(link) - 8) + ", " + (Bits.getRightByte(link) - 8) + "]" : ""); + } +} \ No newline at end of file diff --git a/core/src/io/anuke/mindustry/world/blocks/BlockPart.java b/core/src/io/anuke/mindustry/world/blocks/BlockPart.java index 37788c5f23..dd90451dec 100644 --- a/core/src/io/anuke/mindustry/world/blocks/BlockPart.java +++ b/core/src/io/anuke/mindustry/world/blocks/BlockPart.java @@ -5,75 +5,77 @@ import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; -/**Used for multiblocks. Each block that is not the center of the multiblock is a blockpart. +/** + * Used for multiblocks. Each block that is not the center of the multiblock is a blockpart. * Think of these as delegates to the actual block; all events are passed to the target block. - * They are made to share all properties from the linked tile/block.*/ + * They are made to share all properties from the linked tile/block. + */ public class BlockPart extends Block{ - public BlockPart() { - super("blockpart"); - solid = false; - hasPower = hasItems = hasLiquids = true; - } - - @Override - public void draw(Tile tile){ - //do nothing - } + public BlockPart(){ + super("blockpart"); + solid = false; + hasPower = hasItems = hasLiquids = true; + } - @Override - public void drawShadow(Tile tile){ - //also do nothing - } - - @Override - public boolean isSolidFor(Tile tile){ - return tile.getLinked() == null - || (tile.getLinked().block() instanceof BlockPart || tile.getLinked().solid() - || tile.getLinked().block().isSolidFor(tile.getLinked())); - } - - @Override - public void handleItem(Item item, Tile tile, Tile source){ - tile.getLinked().block().handleItem(item, tile.getLinked(), source); - } - - @Override - public boolean acceptItem(Item item, Tile tile, Tile source){ - return tile.getLinked().block().acceptItem(item, tile.getLinked(), source); - } + @Override + public void draw(Tile tile){ + //do nothing + } - @Override - public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){ - Block block = linked(tile); - return block.hasLiquids - && block.acceptLiquid(tile.getLinked(), source, liquid, amount); - } + @Override + public void drawShadow(Tile tile){ + //also do nothing + } - @Override - public void handleLiquid(Tile tile, Tile source, Liquid liquid, float amount){ - Block block = linked(tile); - block.handleLiquid(tile.getLinked(), source, liquid, amount); - } + @Override + public boolean isSolidFor(Tile tile){ + return tile.getLinked() == null + || (tile.getLinked().block() instanceof BlockPart || tile.getLinked().solid() + || tile.getLinked().block().isSolidFor(tile.getLinked())); + } - @Override - public float addPower(Tile tile, float amount){ - Block block = linked(tile); - if(block.hasPower){ - return block.addPower(tile.getLinked(), amount); - }else{ - return amount; - } - } - - @Override - public boolean acceptPower(Tile tile, Tile from, float amount) { + @Override + public void handleItem(Item item, Tile tile, Tile source){ + tile.getLinked().block().handleItem(item, tile.getLinked(), source); + } + + @Override + public boolean acceptItem(Item item, Tile tile, Tile source){ + return tile.getLinked().block().acceptItem(item, tile.getLinked(), source); + } + + @Override + public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){ + Block block = linked(tile); + return block.hasLiquids + && block.acceptLiquid(tile.getLinked(), source, liquid, amount); + } + + @Override + public void handleLiquid(Tile tile, Tile source, Liquid liquid, float amount){ + Block block = linked(tile); + block.handleLiquid(tile.getLinked(), source, liquid, amount); + } + + @Override + public float addPower(Tile tile, float amount){ + Block block = linked(tile); + if(block.hasPower){ + return block.addPower(tile.getLinked(), amount); + }else{ + return amount; + } + } + + @Override + public boolean acceptPower(Tile tile, Tile from, float amount){ Block block = linked(tile); return block.hasPower && block.acceptPower(tile.getLinked(), from, amount); } - - private Block linked(Tile tile){ - return tile.getLinked().block(); - } + + private Block linked(Tile tile){ + return tile.getLinked().block(); + } } diff --git a/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java b/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java index 810049b4b6..6456b886ad 100644 --- a/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java @@ -35,30 +35,51 @@ import java.io.IOException; import static io.anuke.mindustry.Vars.*; -public class BuildBlock extends Block { - public BuildBlock(String name) { +public class BuildBlock extends Block{ + public BuildBlock(String name){ super(name); update = true; - size = Integer.parseInt(name.charAt(name.length()-1) + ""); + size = Integer.parseInt(name.charAt(name.length() - 1) + ""); health = 1; layer = Layer.placement; consumesTap = true; solidifes = true; } + @Remote(called = Loc.server, in = In.blocks) + public static void onDeconstructFinish(Tile tile, Block block){ + Effects.effect(Fx.breakBlock, tile.drawx(), tile.drawy(), block.size); + world.removeBlock(tile); + } + + @Remote(called = Loc.server, in = In.blocks) + public static void onConstructFinish(Tile tile, Block block, int builderID, byte rotation, Team team){ + world.setBlock(tile, block, team); + tile.setRotation(rotation); + tile.setTeam(team); + Effects.effect(Fx.placeBlock, tile.drawx(), tile.drawy(), block.size); + + //last builder was this local client player, call placed() + if(!headless && builderID == players[0].id){ + //this is run delayed, since if this is called on the server, all clients need to recieve the onBuildFinish() + //event first before they can recieve the placed() event modification results + threads.runDelay(() -> tile.block().placed(tile)); + } + } + @Override - public boolean isSolidFor(Tile tile) { + public boolean isSolidFor(Tile tile){ BuildEntity entity = tile.entity(); return entity == null || entity.recipe == null || entity.recipe.result.solid || entity.previous.solid; } @Override - public CursorType getCursor(Tile tile) { + public CursorType getCursor(Tile tile){ return CursorType.hand; } @Override - public void tapped(Tile tile, Player player) { + public void tapped(Tile tile, Player player){ BuildEntity entity = tile.entity(); //if the target is constructible, begin constructing @@ -84,7 +105,7 @@ public class BuildBlock extends Block { @Override public void afterDestroyed(Tile tile, TileEntity e){ - BuildEntity entity = (BuildEntity)e; + BuildEntity entity = (BuildEntity) e; if(entity.previous != null && entity.previous.synthetic()){ tile.setBlock(entity.previous); @@ -102,13 +123,13 @@ public class BuildBlock extends Block { if(entity.previous == null) return; - for (TextureRegion region : entity.previous.getBlockIcon()) { + for(TextureRegion region : entity.previous.getBlockIcon()){ Draw.rect(region, tile.drawx(), tile.drawy(), entity.previous.rotate ? tile.getRotation() * 90 : 0); } } @Override - public void drawLayer(Tile tile) { + public void drawLayer(Tile tile){ BuildEntity entity = tile.entity(); @@ -120,7 +141,7 @@ public class BuildBlock extends Block { for(TextureRegion region : target.getBlockIcon()){ Shaders.blockbuild.region = region; - Shaders.blockbuild.progress = (float)entity.progress; + Shaders.blockbuild.progress = (float) entity.progress; Shaders.blockbuild.apply(); Draw.rect(region, tile.drawx(), tile.drawy(), target.rotate ? tile.getRotation() * 90 : 0); @@ -130,7 +151,7 @@ public class BuildBlock extends Block { } @Override - public void drawShadow(Tile tile) { + public void drawShadow(Tile tile){ BuildEntity entity = tile.entity(); Recipe recipe = entity.recipe; @@ -144,45 +165,28 @@ public class BuildBlock extends Block { } @Override - public void update(Tile tile) { + public void update(Tile tile){ } @Override - public TileEntity getEntity() { + public TileEntity getEntity(){ return new BuildEntity(); } - @Remote(called = Loc.server, in = In.blocks) - public static void onDeconstructFinish(Tile tile, Block block){ - Effects.effect(Fx.breakBlock, tile.drawx(), tile.drawy(), block.size); - world.removeBlock(tile); - } - - @Remote(called = Loc.server, in = In.blocks) - public static void onConstructFinish(Tile tile, Block block, int builderID, byte rotation, Team team){ - world.setBlock(tile, block, team); - tile.setRotation(rotation); - tile.setTeam(team); - Effects.effect(Fx.placeBlock, tile.drawx(), tile.drawy(), block.size); - - //last builder was this local client player, call placed() - if(!headless && builderID == players[0].id){ - //this is run delayed, since if this is called on the server, all clients need to recieve the onBuildFinish() - //event first before they can recieve the placed() event modification results - threads.runDelay(() -> tile.block().placed(tile)); - } - } - public class BuildEntity extends TileEntity{ - /**The recipe of the block that is being constructed. - * If there is no recipe for this block, as is the case with rocks, 'previous' is used.*/ + /** + * The recipe of the block that is being constructed. + * If there is no recipe for this block, as is the case with rocks, 'previous' is used. + */ public Recipe recipe; public float progress = 0; public float buildCost; - /**The block that used to be here. - * If a non-recipe block is being deconstructed, this is the block that is being deconstructed.*/ + /** + * The block that used to be here. + * If a non-recipe block is being deconstructed, this is the block that is being deconstructed. + */ public Block previous; public int builderID = -1; @@ -191,8 +195,8 @@ public class BuildBlock extends Block { public void construct(Unit builder, TileEntity core, float amount){ float maxProgress = checkRequired(core.items, amount, false); - for (int i = 0; i < recipe.requirements.length; i++) { - accumulator[i] += recipe.requirements[i].amount*maxProgress; //add min amount progressed to the accumulator + for(int i = 0; i < recipe.requirements.length; i++){ + accumulator[i] += recipe.requirements[i].amount * maxProgress; //add min amount progressed to the accumulator } maxProgress = checkRequired(core.items, maxProgress, true); @@ -211,14 +215,14 @@ public class BuildBlock extends Block { public void deconstruct(Unit builder, TileEntity core, float amount){ Recipe recipe = Recipe.getByResult(previous); - if(recipe != null) { + if(recipe != null){ ItemStack[] requirements = recipe.requirements; - for (int i = 0; i < requirements.length; i++) { + for(int i = 0; i < requirements.length; i++){ accumulator[i] += requirements[i].amount * amount / 2f; //add scaled amount progressed to the accumulator int accumulated = (int) (accumulator[i]); //get amount - if (amount > 0) { //if it's positive, add it to the core + if(amount > 0){ //if it's positive, add it to the core int accepting = core.tile.block().acceptStack(requirements[i].item, accumulated, core.tile, builder); core.tile.block().handleStack(requirements[i].item, accepting, core.tile, builder); @@ -237,8 +241,8 @@ public class BuildBlock extends Block { private float checkRequired(InventoryModule inventory, float amount, boolean remove){ float maxProgress = amount; - for(int i = 0; i < recipe.requirements.length; i ++){ - int required = (int)(accumulator[i]); //calculate items that are required now + for(int i = 0; i < recipe.requirements.length; i++){ + int required = (int) (accumulator[i]); //calculate items that are required now if(inventory.get(recipe.requirements[i].item) == 0){ maxProgress = 0f; @@ -246,15 +250,15 @@ public class BuildBlock extends Block { //calculate how many items it can actually use int maxUse = Math.min(required, inventory.get(recipe.requirements[i].item)); //get this as a fraction - float fraction = maxUse / (float)required; + float fraction = maxUse / (float) required; //move max progress down if this fraction is less than 1 - maxProgress = Math.min(maxProgress, maxProgress*fraction); + maxProgress = Math.min(maxProgress, maxProgress * fraction); accumulator[i] -= maxUse; //remove stuff that is actually used - if(remove) { + if(remove){ inventory.remove(recipe.requirements[i].item, maxUse); } } @@ -288,7 +292,7 @@ public class BuildBlock extends Block { } @Override - public void write(DataOutputStream stream) throws IOException { + public void write(DataOutputStream stream) throws IOException{ stream.writeFloat(progress); stream.writeShort(previous == null ? -1 : previous.id); stream.writeShort(recipe == null ? -1 : recipe.result.id); @@ -304,15 +308,15 @@ public class BuildBlock extends Block { } @Override - public void read(DataInputStream stream) throws IOException { + public void read(DataInputStream stream) throws IOException{ progress = stream.readFloat(); short pid = stream.readShort(); short rid = stream.readShort(); byte acsize = stream.readByte(); - + if(acsize != -1){ accumulator = new float[acsize]; - for (int i = 0; i < acsize; i++) { + for(int i = 0; i < acsize; i++){ accumulator[i] = stream.readFloat(); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/Floor.java b/core/src/io/anuke/mindustry/world/blocks/Floor.java index 37c2938516..c03745e90d 100644 --- a/core/src/io/anuke/mindustry/world/blocks/Floor.java +++ b/core/src/io/anuke/mindustry/world/blocks/Floor.java @@ -20,175 +20,173 @@ import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.world; public class Floor extends Block{ - //TODO implement proper bitmasking - protected static IntIntMap bitmask = Mathf.mapInt(2, 1, 8, 2, 10, 3, 11, 4, 16, 5, 18, 6, 22, 7, 24, 8, - 26, 9, 27, 10, 30, 11, 31, 12, 64, 13, 66, 14, 72, 15, 74, 16, 75, 17, 80, 18, - 82, 19, 86, 20, 88, 21, 90, 22, 91, 23, 94, 24, 95, 25, 104, 26, 106, 27, 107, 28, - 120, 29, 122, 30, 123, 31, 126, 32, 127, 33, 208, 34, 210, 35, 214, 36, 216, 37, - 218, 38, 219, 39, 222, 40, 223, 41, 248, 42, 250, 43, 251, 44, 254, 45, 255, 46, 0, 47); - - protected TextureRegion edgeRegion; - protected TextureRegion[] edgeRegions; - protected TextureRegion[] cliffRegions; - protected TextureRegion[] variantRegions; - protected Vector2[] offsets; - protected Predicate blends = block -> block != this && !block.blendOverride(this); - protected boolean blend = true; - - /**number of different variant regions to use*/ - public int variants = 0; - /**edge fallback, used mainly for ores*/ + //TODO implement proper bitmasking + protected static IntIntMap bitmask = Mathf.mapInt(2, 1, 8, 2, 10, 3, 11, 4, 16, 5, 18, 6, 22, 7, 24, 8, + 26, 9, 27, 10, 30, 11, 31, 12, 64, 13, 66, 14, 72, 15, 74, 16, 75, 17, 80, 18, + 82, 19, 86, 20, 88, 21, 90, 22, 91, 23, 94, 24, 95, 25, 104, 26, 106, 27, 107, 28, + 120, 29, 122, 30, 123, 31, 126, 32, 127, 33, 208, 34, 210, 35, 214, 36, 216, 37, + 218, 38, 219, 39, 222, 40, 223, 41, 248, 42, 250, 43, 251, 44, 254, 45, 255, 46, 0, 47); + /** number of different variant regions to use */ + public int variants = 0; + /** edge fallback, used mainly for ores */ public String edge = "stone"; - /**Multiplies unit velocity by this when walked on.*/ - public float speedMultiplier = 1f; - /**Multiplies unit drag by this when walked on.*/ - public float dragMultiplier = 1f; - /**Damage taken per tick on this tile.*/ - public float damageTaken = 0f; - /**How many ticks it takes to drown on this.*/ - public float drownTime = 0f; - /**Effect when walking on this floor.*/ - public Effect walkEffect = BlockFx.ripple; - /**Effect displayed when drowning on this floor.*/ + /** Multiplies unit velocity by this when walked on. */ + public float speedMultiplier = 1f; + /** Multiplies unit drag by this when walked on. */ + public float dragMultiplier = 1f; + /** Damage taken per tick on this tile. */ + public float damageTaken = 0f; + /** How many ticks it takes to drown on this. */ + public float drownTime = 0f; + /** Effect when walking on this floor. */ + public Effect walkEffect = BlockFx.ripple; + /** Effect displayed when drowning on this floor. */ public Effect drownUpdateEffect = BlockFx.bubble; - /**Status effect applied when walking on.*/ - public StatusEffect status = StatusEffects.none; - /**Intensity of applied status effect.*/ - public float statusIntensity = 0.6f; - /**Color of this floor's liquid. Used for tinting sprites.*/ - public Color liquidColor; - /**liquids that drop from this block, used for pumps*/ - public Liquid liquidDrop = null; - /**Whether ores generate on this block.*/ - public boolean hasOres = false; - /**whether this block can be drowned in*/ - public boolean isLiquid; - /**if true, this block cannot be mined by players. useful for annoying things like stone.*/ - public boolean playerUnmineable = false; - - public Floor(String name) { - super(name); - variants = 3; - } + /** Status effect applied when walking on. */ + public StatusEffect status = StatusEffects.none; + /** Intensity of applied status effect. */ + public float statusIntensity = 0.6f; + /** Color of this floor's liquid. Used for tinting sprites. */ + public Color liquidColor; + /** liquids that drop from this block, used for pumps */ + public Liquid liquidDrop = null; + /** Whether ores generate on this block. */ + public boolean hasOres = false; + /** whether this block can be drowned in */ + public boolean isLiquid; + /** if true, this block cannot be mined by players. useful for annoying things like stone. */ + public boolean playerUnmineable = false; + protected TextureRegion edgeRegion; + protected TextureRegion[] edgeRegions; + protected TextureRegion[] cliffRegions; + protected TextureRegion[] variantRegions; + protected Vector2[] offsets; + protected Predicate blends = block -> block != this && !block.blendOverride(this); + protected boolean blend = true; - @Override - public void load() { - super.load(); + public Floor(String name){ + super(name); + variants = 3; + } - if(blend) { - edgeRegion = Draw.hasRegion(name + "edge") ? Draw.region(name + "edge") : Draw.region(edge + "edge"); - edgeRegions = new TextureRegion[8]; - offsets = new Vector2[8]; + @Override + public void load(){ + super.load(); - for(int i = 0; i < 8; i ++){ - int dx = Geometry.d8[i].x, dy = Geometry.d8[i].y; + if(blend){ + edgeRegion = Draw.hasRegion(name + "edge") ? Draw.region(name + "edge") : Draw.region(edge + "edge"); + edgeRegions = new TextureRegion[8]; + offsets = new Vector2[8]; - TextureRegion result = new TextureRegion(); + for(int i = 0; i < 8; i++){ + int dx = Geometry.d8[i].x, dy = Geometry.d8[i].y; - int sx = -dx*8+2, sy = -dy*8+2; - int x = Mathf.clamp(sx, 0, 12); - int y = Mathf.clamp(sy, 0, 12); - int w = Mathf.clamp(sx+8, 0, 12) - x, h = Mathf.clamp(sy+8, 0, 12) - y; + TextureRegion result = new TextureRegion(); - float rx = Mathf.clamp(dx*8, 0, 8-w); - float ry = Mathf.clamp(dy*8, 0, 8-h); + int sx = -dx * 8 + 2, sy = -dy * 8 + 2; + int x = Mathf.clamp(sx, 0, 12); + int y = Mathf.clamp(sy, 0, 12); + int w = Mathf.clamp(sx + 8, 0, 12) - x, h = Mathf.clamp(sy + 8, 0, 12) - y; - result.setTexture(edgeRegion.getTexture()); - result.setRegion(edgeRegion.getRegionX()+x, edgeRegion.getRegionY()+y+h, w, -h); + float rx = Mathf.clamp(dx * 8, 0, 8 - w); + float ry = Mathf.clamp(dy * 8, 0, 8 - h); - edgeRegions[i] = result; - offsets[i] = new Vector2(-4 + rx, -4 + ry); - } + result.setTexture(edgeRegion.getTexture()); + result.setRegion(edgeRegion.getRegionX() + x, edgeRegion.getRegionY() + y + h, w, -h); - cliffRegions = new TextureRegion[4]; - cliffRegions[0] = Draw.region(name + "-cliff-edge-2"); - cliffRegions[1] = Draw.region(name + "-cliff-edge"); - cliffRegions[2] = Draw.region(name + "-cliff-edge-1"); - cliffRegions[3] = Draw.region(name + "-cliff-side"); - } + edgeRegions[i] = result; + offsets[i] = new Vector2(-4 + rx, -4 + ry); + } - //load variant regions for drawing - if(variants > 0){ - variantRegions = new TextureRegion[variants]; + cliffRegions = new TextureRegion[4]; + cliffRegions[0] = Draw.region(name + "-cliff-edge-2"); + cliffRegions[1] = Draw.region(name + "-cliff-edge"); + cliffRegions[2] = Draw.region(name + "-cliff-edge-1"); + cliffRegions[3] = Draw.region(name + "-cliff-side"); + } - for (int i = 0; i < variants; i++) { - variantRegions[i] = Draw.region(name + (i + 1)); - } - }else{ - variantRegions = new TextureRegion[1]; - variantRegions[0] = Draw.region(name); - } - } + //load variant regions for drawing + if(variants > 0){ + variantRegions = new TextureRegion[variants]; - @Override - public void init(){ - super.init(); + for(int i = 0; i < variants; i++){ + variantRegions[i] = Draw.region(name + (i + 1)); + } + }else{ + variantRegions = new TextureRegion[1]; + variantRegions[0] = Draw.region(name); + } + } - if(isLiquid && liquidColor == null){ - throw new RuntimeException("All liquids must define a liquidColor! Problematic block: " + name); - } - } + @Override + public void init(){ + super.init(); - @Override - public void drawNonLayer(Tile tile){ - MathUtils.random.setSeed(tile.id()); + if(isLiquid && liquidColor == null){ + throw new RuntimeException("All liquids must define a liquidColor! Problematic block: " + name); + } + } - drawEdges(tile, true); - } - - @Override - public void draw(Tile tile){ - MathUtils.random.setSeed(tile.id()); + @Override + public void drawNonLayer(Tile tile){ + MathUtils.random.setSeed(tile.id()); - Draw.rect(variantRegions[Mathf.randomSeed(tile.id(), 0, Math.max(0, variantRegions.length-1))], tile.worldx(), tile.worldy()); + drawEdges(tile, true); + } - if(tile.cliffs != 0 && cliffRegions != null){ - for(int i = 0; i < 4; i ++){ - if((tile.cliffs & (1 << i*2)) != 0) { - Draw.colorl(i > 1 ? 0.6f : 1f); + @Override + public void draw(Tile tile){ + MathUtils.random.setSeed(tile.id()); - boolean above = (tile.cliffs & (1 << ((i+1)%4)*2)) != 0, below = (tile.cliffs & (1 << (Mathf.mod(i-1, 4))*2)) != 0; + Draw.rect(variantRegions[Mathf.randomSeed(tile.id(), 0, Math.max(0, variantRegions.length - 1))], tile.worldx(), tile.worldy()); - if(above && below){ - Draw.rect(cliffRegions[0], tile.worldx(), tile.worldy(), i * 90); - }else if(above){ - Draw.rect(cliffRegions[1], tile.worldx(), tile.worldy(), i * 90); - }else if(below){ - Draw.rect(cliffRegions[2], tile.worldx(), tile.worldy(), i * 90); - }else{ - Draw.rect(cliffRegions[3], tile.worldx(), tile.worldy(), i * 90); - } - } - } - } - Draw.reset(); + if(tile.cliffs != 0 && cliffRegions != null){ + for(int i = 0; i < 4; i++){ + if((tile.cliffs & (1 << i * 2)) != 0){ + Draw.colorl(i > 1 ? 0.6f : 1f); - drawEdges(tile, false); - } + boolean above = (tile.cliffs & (1 << ((i + 1) % 4) * 2)) != 0, below = (tile.cliffs & (1 << (Mathf.mod(i - 1, 4)) * 2)) != 0; - public boolean blendOverride(Block block){ - return false; - } + if(above && below){ + Draw.rect(cliffRegions[0], tile.worldx(), tile.worldy(), i * 90); + }else if(above){ + Draw.rect(cliffRegions[1], tile.worldx(), tile.worldy(), i * 90); + }else if(below){ + Draw.rect(cliffRegions[2], tile.worldx(), tile.worldy(), i * 90); + }else{ + Draw.rect(cliffRegions[3], tile.worldx(), tile.worldy(), i * 90); + } + } + } + } + Draw.reset(); - protected void drawEdges(Tile tile, boolean sameLayer){ - if(!blend || tile.cliffs > 0) return; + drawEdges(tile, false); + } - for(int i = 0; i < 8; i ++){ - int dx = Geometry.d8[i].x, dy = Geometry.d8[i].y; + public boolean blendOverride(Block block){ + return false; + } - Tile other = world.tile(tile.x+dx, tile.y+dy); + protected void drawEdges(Tile tile, boolean sameLayer){ + if(!blend || tile.cliffs > 0) return; - if(other == null) continue; + for(int i = 0; i < 8; i++){ + int dx = Geometry.d8[i].x, dy = Geometry.d8[i].y; - Floor floor = other.floor(); + Tile other = world.tile(tile.x + dx, tile.y + dy); - if(floor.id <= this.id || !blends.test(floor) || (floor.cacheLayer.ordinal() > this.cacheLayer.ordinal() && !sameLayer) || - (sameLayer && floor.cacheLayer == this.cacheLayer)) continue; + if(other == null) continue; - TextureRegion region = floor.edgeRegions[i]; + Floor floor = other.floor(); - Draw.crect(region, tile.worldx() + floor.offsets[i].x, tile.worldy() + floor.offsets[i].y, region.getRegionWidth(), region.getRegionHeight()); - } - } + if(floor.id <= this.id || !blends.test(floor) || (floor.cacheLayer.ordinal() > this.cacheLayer.ordinal() && !sameLayer) || + (sameLayer && floor.cacheLayer == this.cacheLayer)) continue; -} + TextureRegion region = floor.edgeRegions[i]; + + Draw.crect(region, tile.worldx() + floor.offsets[i].x, tile.worldy() + floor.offsets[i].y, region.getRegionWidth(), region.getRegionHeight()); + } + } + +} \ No newline at end of file diff --git a/core/src/io/anuke/mindustry/world/blocks/LiquidBlock.java b/core/src/io/anuke/mindustry/world/blocks/LiquidBlock.java index 11b98f66b3..1d640466c6 100644 --- a/core/src/io/anuke/mindustry/world/blocks/LiquidBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/LiquidBlock.java @@ -2,52 +2,52 @@ package io.anuke.mindustry.world.blocks; import com.badlogic.gdx.graphics.g2d.TextureRegion; import io.anuke.mindustry.world.Block; -import io.anuke.mindustry.world.meta.BlockGroup; import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.meta.BlockGroup; import io.anuke.mindustry.world.modules.LiquidModule; import io.anuke.ucore.graphics.Draw; public class LiquidBlock extends Block{ - protected TextureRegion liquidRegion, bottomRegion, topRegion; - - public LiquidBlock(String name) { - super(name); - update = true; - solid = true; - hasLiquids = true; - group = BlockGroup.liquids; - outputsLiquid = true; - } + protected TextureRegion liquidRegion, bottomRegion, topRegion; - @Override - public void load() { - super.load(); + public LiquidBlock(String name){ + super(name); + update = true; + solid = true; + hasLiquids = true; + group = BlockGroup.liquids; + outputsLiquid = true; + } - liquidRegion = Draw.region(name + "-liquid"); - topRegion = Draw.region(name + "-top"); - bottomRegion = Draw.region(name + "-bottom"); - } + @Override + public void load(){ + super.load(); - @Override - public TextureRegion[] getIcon(){ - return new TextureRegion[]{Draw.region(name() + "-bottom"), Draw.region(name() + "-top")}; - } - - @Override - public void draw(Tile tile){ - LiquidModule mod = tile.entity.liquids; + liquidRegion = Draw.region(name + "-liquid"); + topRegion = Draw.region(name + "-top"); + bottomRegion = Draw.region(name + "-bottom"); + } - int rotation = rotate ? tile.getRotation() * 90 : 0; - - Draw.rect(bottomRegion, tile.drawx(), tile.drawy(), rotation); - - if(mod.total() > 0.001f){ - Draw.color(mod.current().color); - Draw.alpha(mod.total() / liquidCapacity); - Draw.rect(liquidRegion, tile.drawx(), tile.drawy(), rotation); - Draw.color(); - } - - Draw.rect(topRegion, tile.drawx(), tile.drawy(), rotation); - } + @Override + public TextureRegion[] getIcon(){ + return new TextureRegion[]{Draw.region(name() + "-bottom"), Draw.region(name() + "-top")}; + } + + @Override + public void draw(Tile tile){ + LiquidModule mod = tile.entity.liquids; + + int rotation = rotate ? tile.getRotation() * 90 : 0; + + Draw.rect(bottomRegion, tile.drawx(), tile.drawy(), rotation); + + if(mod.total() > 0.001f){ + Draw.color(mod.current().color); + Draw.alpha(mod.total() / liquidCapacity); + Draw.rect(liquidRegion, tile.drawx(), tile.drawy(), rotation); + Draw.color(); + } + + Draw.rect(topRegion, tile.drawx(), tile.drawy(), rotation); + } } diff --git a/core/src/io/anuke/mindustry/world/blocks/Ore.java b/core/src/io/anuke/mindustry/world/blocks/Ore.java index ff0f155849..398771f070 100644 --- a/core/src/io/anuke/mindustry/world/blocks/Ore.java +++ b/core/src/io/anuke/mindustry/world/blocks/Ore.java @@ -4,9 +4,9 @@ import io.anuke.mindustry.content.blocks.Blocks; public class Ore extends Floor{ - public Ore(String name) { - super(name); - blends = block -> block != this && block != Blocks.stone; - } + public Ore(String name){ + super(name); + blends = block -> block != this && block != Blocks.stone; + } } diff --git a/core/src/io/anuke/mindustry/world/blocks/OreBlock.java b/core/src/io/anuke/mindustry/world/blocks/OreBlock.java index 18fcd86711..57c7f67aa2 100644 --- a/core/src/io/anuke/mindustry/world/blocks/OreBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/OreBlock.java @@ -9,7 +9,7 @@ import io.anuke.mindustry.world.Tile; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.util.Mathf; -public class OreBlock extends Floor { +public class OreBlock extends Floor{ public Floor base; public OreBlock(Item ore, Floor base){ @@ -32,7 +32,7 @@ public class OreBlock extends Floor { @Override public void draw(Tile tile){ - Draw.rect(variantRegions[Mathf.randomSeed(tile.id(), 0, Math.max(0, variantRegions.length-1))], tile.worldx(), tile.worldy()); + Draw.rect(variantRegions[Mathf.randomSeed(tile.id(), 0, Math.max(0, variantRegions.length - 1))], tile.worldx(), tile.worldy()); drawEdges(tile, false); } @@ -45,7 +45,7 @@ public class OreBlock extends Floor { } @Override - public boolean blendOverride(Block block) { + public boolean blendOverride(Block block){ return block == base; } } diff --git a/core/src/io/anuke/mindustry/world/blocks/PowerBlock.java b/core/src/io/anuke/mindustry/world/blocks/PowerBlock.java index 095aa42034..83e550a7e4 100644 --- a/core/src/io/anuke/mindustry/world/blocks/PowerBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/PowerBlock.java @@ -4,12 +4,12 @@ import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.meta.BlockGroup; public abstract class PowerBlock extends Block{ - - public PowerBlock(String name) { - super(name); - update = true; - solid = true; - hasPower = true; - group = BlockGroup.power; - } + + public PowerBlock(String name){ + super(name); + update = true; + solid = true; + hasPower = true; + group = BlockGroup.power; + } } diff --git a/core/src/io/anuke/mindustry/world/blocks/Rock.java b/core/src/io/anuke/mindustry/world/blocks/Rock.java index 976e398a68..f5771124fe 100644 --- a/core/src/io/anuke/mindustry/world/blocks/Rock.java +++ b/core/src/io/anuke/mindustry/world/blocks/Rock.java @@ -6,28 +6,28 @@ import io.anuke.mindustry.world.Tile; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.util.Mathf; -public class Rock extends Block { +public class Rock extends Block{ protected TextureRegion[] shadowRegions, regions; protected int variants; - public Rock(String name) { + public Rock(String name){ super(name); breakable = true; alwaysReplace = true; } @Override - public void draw(Tile tile) { + public void draw(Tile tile){ if(variants > 0){ - Draw.rect(regions[Mathf.randomSeed(tile.id(), 0, Math.max(0, regions.length-1))], tile.worldx(), tile.worldy()); + Draw.rect(regions[Mathf.randomSeed(tile.id(), 0, Math.max(0, regions.length - 1))], tile.worldx(), tile.worldy()); }else{ Draw.rect(region, tile.worldx(), tile.worldy()); } } @Override - public void drawShadow(Tile tile) { - if(shadowRegions != null) { + public void drawShadow(Tile tile){ + if(shadowRegions != null){ Draw.rect(shadowRegions[(Mathf.randomSeed(tile.id(), 0, variants - 1))], tile.worldx(), tile.worldy()); }else if(shadowRegion != null){ Draw.rect(shadowRegion, tile.drawx(), tile.drawy()); @@ -35,16 +35,16 @@ public class Rock extends Block { } @Override - public void load() { + public void load(){ super.load(); if(variants > 0){ shadowRegions = new TextureRegion[variants]; regions = new TextureRegion[variants]; - for (int i = 0; i < variants; i++) { - shadowRegions[i] = Draw.region(name + "shadow" + (i+1)); - regions[i] = Draw.region(name + (i+1)); + for(int i = 0; i < variants; i++){ + shadowRegions[i] = Draw.region(name + "shadow" + (i + 1)); + regions[i] = Draw.region(name + (i + 1)); } } } diff --git a/core/src/io/anuke/mindustry/world/blocks/SelectionTrait.java b/core/src/io/anuke/mindustry/world/blocks/SelectionTrait.java index 615acb974a..45ba5bb105 100644 --- a/core/src/io/anuke/mindustry/world/blocks/SelectionTrait.java +++ b/core/src/io/anuke/mindustry/world/blocks/SelectionTrait.java @@ -12,7 +12,7 @@ import io.anuke.ucore.scene.ui.layout.Table; import static io.anuke.mindustry.Vars.control; -public interface SelectionTrait { +public interface SelectionTrait{ default void buildItemTable(Table table, Supplier holder, Consumer consumer){ @@ -32,7 +32,7 @@ public interface SelectionTrait { button.getStyle().imageUp = new TextureRegionDrawable(new TextureRegion(items.get(i).region)); button.setChecked(holder.get().id == f); - if(i++%4 == 3){ + if(i++ % 4 == 3){ cont.row(); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/StaticBlock.java b/core/src/io/anuke/mindustry/world/blocks/StaticBlock.java index 61f11a5549..c39015cff9 100644 --- a/core/src/io/anuke/mindustry/world/blocks/StaticBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/StaticBlock.java @@ -5,9 +5,9 @@ import io.anuke.mindustry.world.Block; public class StaticBlock extends Block{ - public StaticBlock(String name) { - super(name); - cacheLayer = CacheLayer.walls; - } + public StaticBlock(String name){ + super(name); + cacheLayer = CacheLayer.walls; + } } diff --git a/core/src/io/anuke/mindustry/world/blocks/Wall.java b/core/src/io/anuke/mindustry/world/blocks/Wall.java index e28fc5d7e5..e2cb089f92 100644 --- a/core/src/io/anuke/mindustry/world/blocks/Wall.java +++ b/core/src/io/anuke/mindustry/world/blocks/Wall.java @@ -5,16 +5,16 @@ import io.anuke.mindustry.world.meta.BlockGroup; public class Wall extends Block{ - public Wall(String name) { - super(name); - solid = true; - destructible = true; - group = BlockGroup.walls; - } + public Wall(String name){ + super(name); + solid = true; + destructible = true; + group = BlockGroup.walls; + } - @Override - public boolean canReplace(Block other){ - return super.canReplace(other) && health > other.health; - } + @Override + public boolean canReplace(Block other){ + return super.canReplace(other) && health > other.health; + } } diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/DeflectorWall.java b/core/src/io/anuke/mindustry/world/blocks/defense/DeflectorWall.java index 1f39e386f9..c8c72c9439 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/DeflectorWall.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/DeflectorWall.java @@ -16,13 +16,13 @@ import io.anuke.ucore.util.Physics; import static io.anuke.mindustry.Vars.tilesize; -public class DeflectorWall extends Wall { +public class DeflectorWall extends Wall{ static final float hitTime = 10f; protected float maxDamageDeflect = 5f; protected Rectangle rect = new Rectangle(); - public DeflectorWall(String name) { + public DeflectorWall(String name){ super(name); } @@ -41,7 +41,7 @@ public class DeflectorWall extends Wall { Draw.rect("blank", tile.drawx(), tile.drawy(), tilesize * size, tilesize * size); Draw.reset(); - entity.hit = Mathf.clamp(entity.hit - Timers.delta()/hitTime); + entity.hit = Mathf.clamp(entity.hit - Timers.delta() / hitTime); Graphics.setNormalBlending(); } @@ -56,13 +56,13 @@ public class DeflectorWall extends Wall { float penX = Math.abs(entity.x - bullet.x), penY = Math.abs(entity.y - bullet.y); Vector2 position = Physics.raycastRect(bullet.lastPosition().x, bullet.lastPosition().y, bullet.x, bullet.y, - rect.setCenter(entity.x, entity.y).setSize(size * tilesize + bullet.hitbox.width + bullet.hitbox.height)); + rect.setCenter(entity.x, entity.y).setSize(size * tilesize + bullet.hitbox.width + bullet.hitbox.height)); if(position != null){ bullet.set(position.x, position.y); } - if(penX > penY) { + if(penX > penY){ bullet.getVelocity().x *= -1; }else{ bullet.getVelocity().y *= -1; @@ -73,11 +73,11 @@ public class DeflectorWall extends Wall { bullet.scaleTime(1f); bullet.supressCollision(); - ((DeflectorEntity)entity).hit = 1f; + ((DeflectorEntity) entity).hit = 1f; } @Override - public TileEntity getEntity() { + public TileEntity getEntity(){ return new DeflectorEntity(); } diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/Door.java b/core/src/io/anuke/mindustry/world/blocks/defense/Door.java index 824fbaa961..d186815e23 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/Door.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/Door.java @@ -20,86 +20,86 @@ import java.io.IOException; import static io.anuke.mindustry.Vars.threads; public class Door extends Wall{ - protected final Rectangle rect = new Rectangle(); + protected final Rectangle rect = new Rectangle(); - protected Effect openfx = BlockFx.dooropen; - protected Effect closefx = BlockFx.doorclose; + protected Effect openfx = BlockFx.dooropen; + protected Effect closefx = BlockFx.doorclose; - protected TextureRegion openRegion; + protected TextureRegion openRegion; - public Door(String name) { - super(name); - solid = false; - solidifes = true; - consumesTap = true; - } + public Door(String name){ + super(name); + solid = false; + solidifes = true; + consumesTap = true; + } - @Override - public void load() { - super.load(); - openRegion = Draw.region(name + "-open"); - } + @Override + public void load(){ + super.load(); + openRegion = Draw.region(name + "-open"); + } - @Override - public void draw(Tile tile){ - DoorEntity entity = tile.entity(); - - if(!entity.open){ - Draw.rect(region, tile.drawx(), tile.drawy()); - }else{ - Draw.rect(openRegion, tile.drawx(), tile.drawy()); - } - } + @Override + public void draw(Tile tile){ + DoorEntity entity = tile.entity(); - @Override - public CursorType getCursor(Tile tile){ - return CursorType.hand; - } - - @Override - public boolean isSolidFor(Tile tile){ - DoorEntity entity = tile.entity(); - return !entity.open; - } + if(!entity.open){ + Draw.rect(region, tile.drawx(), tile.drawy()); + }else{ + Draw.rect(openRegion, tile.drawx(), tile.drawy()); + } + } - @Override - public void tapped(Tile tile, Player player){ - DoorEntity entity = tile.entity(); + @Override + public CursorType getCursor(Tile tile){ + return CursorType.hand; + } - threads.run(() -> { + @Override + public boolean isSolidFor(Tile tile){ + DoorEntity entity = tile.entity(); + return !entity.open; + } - if(Units.anyEntities(tile) && entity.open){ - return; - } + @Override + public void tapped(Tile tile, Player player){ + DoorEntity entity = tile.entity(); - entity.open = !entity.open; - if(!entity.open){ - Effects.effect(closefx, tile.drawx(), tile.drawy()); - }else{ - Effects.effect(openfx, tile.drawx(), tile.drawy()); - } - }); - } - - @Override - public TileEntity getEntity(){ - return new DoorEntity(); - } - - public class DoorEntity extends TileEntity{ - public boolean open = false; - - @Override - public void write(DataOutputStream stream) throws IOException{ - super.write(stream); - stream.writeBoolean(open); - } - - @Override - public void read(DataInputStream stream) throws IOException{ - super.read(stream); - open = stream.readBoolean(); - } - } + threads.run(() -> { + + if(Units.anyEntities(tile) && entity.open){ + return; + } + + entity.open = !entity.open; + if(!entity.open){ + Effects.effect(closefx, tile.drawx(), tile.drawy()); + }else{ + Effects.effect(openfx, tile.drawx(), tile.drawy()); + } + }); + } + + @Override + public TileEntity getEntity(){ + return new DoorEntity(); + } + + public class DoorEntity extends TileEntity{ + public boolean open = false; + + @Override + public void write(DataOutputStream stream) throws IOException{ + super.write(stream); + stream.writeBoolean(open); + } + + @Override + public void read(DataInputStream stream) throws IOException{ + super.read(stream); + open = stream.readBoolean(); + } + } } diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/PhaseWall.java b/core/src/io/anuke/mindustry/world/blocks/defense/PhaseWall.java index 073968c565..6127a8b469 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/PhaseWall.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/PhaseWall.java @@ -5,16 +5,16 @@ import io.anuke.mindustry.world.blocks.Wall; import io.anuke.ucore.core.Timers; import io.anuke.ucore.util.Mathf; -public class PhaseWall extends Wall { +public class PhaseWall extends Wall{ protected float regenSpeed = 0.25f; - public PhaseWall(String name) { + public PhaseWall(String name){ super(name); update = true; } @Override - public void update(Tile tile) { + public void update(Tile tile){ tile.entity.health = Mathf.clamp(tile.entity.health + regenSpeed * Timers.delta(), 0f, health); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/ShieldBlock.java b/core/src/io/anuke/mindustry/world/blocks/defense/ShieldBlock.java index 80984d505f..b87dc6ac4e 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/ShieldBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/ShieldBlock.java @@ -11,71 +11,71 @@ import io.anuke.ucore.util.Mathf; //TODO remove public class ShieldBlock extends PowerBlock{ - public float shieldRadius = 40f; - public float powerDrain = 0.005f; - public float powerPerDamage = 0.06f; - public float maxRadius = 40f; - public float radiusScale = 300f; - - public ShieldBlock(String name) { - super(name); - powerCapacity = 80f; - } - - @Override - public void setStats(){ - super.setStats(); - //stats.add("powersecond", Strings.toFixed(powerDrain*60, 2)); - //stats.add("powerdraindamage", Strings.toFixed(powerPerDamage, 2)); - //stats.add("shieldradius", (int)shieldRadius); - } + public float shieldRadius = 40f; + public float powerDrain = 0.005f; + public float powerPerDamage = 0.06f; + public float maxRadius = 40f; + public float radiusScale = 300f; - @Override - public void update(Tile tile){ - ShieldEntity entity = tile.entity(); + public ShieldBlock(String name){ + super(name); + powerCapacity = 80f; + } - if(entity.shield == null){ - entity.shield = new Shield(tile); - if(Vars.infiniteAmmo && Vars.debug) - entity.shield.add(); - } + @Override + public void setStats(){ + super.setStats(); + //stats.add("powersecond", Strings.toFixed(powerDrain*60, 2)); + //stats.add("powerdraindamage", Strings.toFixed(powerPerDamage, 2)); + //stats.add("shieldradius", (int)shieldRadius); + } - if(entity.power.amount > powerPerDamage){ - if(!entity.shield.active){ - entity.shield.add(); - } + @Override + public void update(Tile tile){ + ShieldEntity entity = tile.entity(); - entity.power.amount -= powerDrain * Timers.delta(); - }else{ - if(entity.shield.active && !(Vars.infiniteAmmo && Vars.debug)){ - entity.shield.removeDelay(); - } - } - - entity.shield.radius = Mathf.lerp(entity.shield.radius, Math.min(entity.power.amount / powerCapacity * radiusScale, maxRadius), Timers.delta() * 0.05f); + if(entity.shield == null){ + entity.shield = new Shield(tile); + if(Vars.infiniteAmmo && Vars.debug) + entity.shield.add(); + } - } + if(entity.power.amount > powerPerDamage){ + if(!entity.shield.active){ + entity.shield.add(); + } - @Override - public TileEntity getEntity(){ - return new ShieldEntity(); - } - - public void handleBullet(Tile tile, BulletEntity bullet){ - ShieldEntity entity = tile.entity(); - - if(entity.power.amount < bullet.getDamage() * powerPerDamage){ - return; - } - - bullet.remove(); - //Effects.effect(bullet.damage > 5 ? BulletFx.shieldhit : BulletFx.laserhit, bullet); - //if(!headless) renderer.addShieldHit(bullet.x, bullet.y); - - entity.power.amount -= bullet.getDamage() * powerPerDamage; - } + entity.power.amount -= powerDrain * Timers.delta(); + }else{ + if(entity.shield.active && !(Vars.infiniteAmmo && Vars.debug)){ + entity.shield.removeDelay(); + } + } - static class ShieldEntity extends TileEntity{ - Shield shield; - } + entity.shield.radius = Mathf.lerp(entity.shield.radius, Math.min(entity.power.amount / powerCapacity * radiusScale, maxRadius), Timers.delta() * 0.05f); + + } + + @Override + public TileEntity getEntity(){ + return new ShieldEntity(); + } + + public void handleBullet(Tile tile, BulletEntity bullet){ + ShieldEntity entity = tile.entity(); + + if(entity.power.amount < bullet.getDamage() * powerPerDamage){ + return; + } + + bullet.remove(); + //Effects.effect(bullet.damage > 5 ? BulletFx.shieldhit : BulletFx.laserhit, bullet); + //if(!headless) renderer.addShieldHit(bullet.x, bullet.y); + + entity.power.amount -= bullet.getDamage() * powerPerDamage; + } + + static class ShieldEntity extends TileEntity{ + Shield shield; + } } diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/ShieldedWallBlock.java b/core/src/io/anuke/mindustry/world/blocks/defense/ShieldedWallBlock.java index 261836887b..9416aa1258 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/ShieldedWallBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/ShieldedWallBlock.java @@ -11,66 +11,66 @@ import static io.anuke.mindustry.Vars.tilesize; //TODO remove public class ShieldedWallBlock extends PowerBlock{ - static final float hitTime = 18f; - static final Color hitColor = Color.SKY.cpy().mul(1.2f); - public float powerPerDamage = 0.08f; + static final float hitTime = 18f; + static final Color hitColor = Color.SKY.cpy().mul(1.2f); + public float powerPerDamage = 0.08f; - public ShieldedWallBlock(String name) { - super(name); - destructible = true; - update = false; - } - - @Override - public float handleDamage(Tile tile, float amount){ - float drain = amount * powerPerDamage; - ShieldedWallEntity entity = tile.entity(); - - if(entity.power.amount > drain){ - entity.power.amount -= drain; - entity.hit = hitTime; - return 0; - }else if(entity.power.amount > 0){ - int reduction = (int)(entity.power.amount / powerPerDamage); - entity.power.amount = 0; - - return amount - reduction; - } - - return amount; - } + public ShieldedWallBlock(String name){ + super(name); + destructible = true; + update = false; + } - @Override - public void setStats(){ - super.setStats(); - //stats.add("powerdraindamage", Strings.toFixed(powerPerDamage, 2)); - } - - @Override - public void draw(Tile tile){ - super.draw(tile); - - ShieldedWallEntity entity = tile.entity(); - - if(entity.power.amount > powerPerDamage){ - //renderer.addShield(() -> Draw.rect("blank", tile.worldx(), tile.worldy(), tilesize, tilesize)); - } - - Draw.color(hitColor); - Draw.alpha(entity.hit / hitTime * 0.9f); - Draw.rect("blank", tile.worldx(), tile.worldy(), tilesize, tilesize); - Draw.reset(); - - entity.hit -= Timers.delta(); - entity.hit = Math.max(entity.hit, 0); - } - - @Override - public TileEntity getEntity(){ - return new ShieldedWallEntity(); - } - - static class ShieldedWallEntity extends TileEntity{ - public float hit; - } + @Override + public float handleDamage(Tile tile, float amount){ + float drain = amount * powerPerDamage; + ShieldedWallEntity entity = tile.entity(); + + if(entity.power.amount > drain){ + entity.power.amount -= drain; + entity.hit = hitTime; + return 0; + }else if(entity.power.amount > 0){ + int reduction = (int) (entity.power.amount / powerPerDamage); + entity.power.amount = 0; + + return amount - reduction; + } + + return amount; + } + + @Override + public void setStats(){ + super.setStats(); + //stats.add("powerdraindamage", Strings.toFixed(powerPerDamage, 2)); + } + + @Override + public void draw(Tile tile){ + super.draw(tile); + + ShieldedWallEntity entity = tile.entity(); + + if(entity.power.amount > powerPerDamage){ + //renderer.addShield(() -> Draw.rect("blank", tile.worldx(), tile.worldy(), tilesize, tilesize)); + } + + Draw.color(hitColor); + Draw.alpha(entity.hit / hitTime * 0.9f); + Draw.rect("blank", tile.worldx(), tile.worldy(), tilesize, tilesize); + Draw.reset(); + + entity.hit -= Timers.delta(); + entity.hit = Math.max(entity.hit, 0); + } + + @Override + public TileEntity getEntity(){ + return new ShieldedWallEntity(); + } + + static class ShieldedWallEntity extends TileEntity{ + public float hit; + } } diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ArtilleryTurret.java b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ArtilleryTurret.java index 853695ba46..3e1f66e7dc 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ArtilleryTurret.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ArtilleryTurret.java @@ -9,11 +9,13 @@ import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.tilesize; -/**Artillery turrets have special shooting calculations done to hit targets.*/ -public class ArtilleryTurret extends ItemTurret { +/** + * Artillery turrets have special shooting calculations done to hit targets. + */ +public class ArtilleryTurret extends ItemTurret{ protected float velocityInaccuracy = 0f; - public ArtilleryTurret(String name) { + public ArtilleryTurret(String name){ super(name); targetAir = false; } @@ -34,9 +36,9 @@ public class ArtilleryTurret extends ItemTurret { float dst = entity.distanceTo(predict.x, predict.y); float maxTraveled = type.bullet.lifetime * type.bullet.speed; - for (int i = 0; i < shots; i++) { + for(int i = 0; i < shots; i++){ Bullet.create(ammo.bullet, tile.entity, tile.getTeam(), tile.drawx() + tr.x, tile.drawy() + tr.y, - entity.rotation + Mathf.range(inaccuracy + type.inaccuracy), dst/maxTraveled + Mathf.range(velocityInaccuracy)); + entity.rotation + Mathf.range(inaccuracy + type.inaccuracy), dst / maxTraveled + Mathf.range(velocityInaccuracy)); } effects(tile); diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/BurstTurret.java b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/BurstTurret.java index 1093721863..c31fe33cd4 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/BurstTurret.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/BurstTurret.java @@ -7,11 +7,11 @@ import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.tilesize; -public class BurstTurret extends ItemTurret { +public class BurstTurret extends ItemTurret{ protected float burstSpacing = 5; protected float xRand = 0f; - public BurstTurret(String name) { + public BurstTurret(String name){ super(name); } @@ -21,7 +21,7 @@ public class BurstTurret extends ItemTurret { entity.heat = 1f; - for (int i = 0; i < shots; i++) { + for(int i = 0; i < shots; i++){ Timers.run(burstSpacing * i, () -> { if(!(tile.entity instanceof TurretEntity) || !hasAmmo(tile)) return; diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/CooledTurret.java b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/CooledTurret.java index d7f0e8dd89..62c832f6ac 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/CooledTurret.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/CooledTurret.java @@ -12,14 +12,18 @@ import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.tilesize; -public class CooledTurret extends Turret { - /**How much reload is lowered by for each unit of liquid of heat capacity 1.*/ +public class CooledTurret extends Turret{ + /** + * How much reload is lowered by for each unit of liquid of heat capacity 1. + */ protected float coolantMultiplier = 1f; - /**Max coolant used per tick.*/ + /** + * Max coolant used per tick. + */ protected float maxUsed = 1f; protected Effect coolEffect = BlockFx.fuelburn; - public CooledTurret(String name) { + public CooledTurret(String name){ super(name); hasLiquids = true; liquidCapacity = 20f; @@ -28,7 +32,7 @@ public class CooledTurret extends Turret { } @Override - protected void updateShooting(Tile tile) { + protected void updateShooting(Tile tile){ super.updateShooting(tile); TurretEntity entity = tile.entity(); @@ -39,7 +43,7 @@ public class CooledTurret extends Turret { entity.liquids.remove(liquid, used); if(Mathf.chance(0.04 * used)){ - Effects.effect(coolEffect, tile.drawx() + Mathf.range(size * tilesize/2f), tile.drawy() + Mathf.range(size * tilesize/2f)); + Effects.effect(coolEffect, tile.drawx() + Mathf.range(size * tilesize / 2f), tile.drawy() + Mathf.range(size * tilesize / 2f)); } //don't use oil as coolant, thanks @@ -49,7 +53,7 @@ public class CooledTurret extends Turret { } @Override - public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount) { + public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){ return super.acceptLiquid(tile, source, liquid, amount) && liquid.temperature <= 0.5f; } } diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/DoubleTurret.java b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/DoubleTurret.java index 1a46cb7be9..1601b15a4c 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/DoubleTurret.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/DoubleTurret.java @@ -6,10 +6,10 @@ import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.tilesize; -public class DoubleTurret extends ItemTurret { +public class DoubleTurret extends ItemTurret{ protected float shotWidth = 2f; - public DoubleTurret(String name) { + public DoubleTurret(String name){ super(name); shots = 2; } @@ -17,7 +17,7 @@ public class DoubleTurret extends ItemTurret { @Override protected void shoot(Tile tile, AmmoType ammo){ TurretEntity entity = tile.entity(); - entity.shots ++; + entity.shots++; int i = Mathf.signs[entity.shots % 2]; diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ItemTurret.java b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ItemTurret.java index d1b1fde9c8..b982ff5a0b 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ItemTurret.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ItemTurret.java @@ -11,18 +11,18 @@ import io.anuke.mindustry.world.meta.BlockBar; import io.anuke.mindustry.world.meta.BlockStat; import io.anuke.mindustry.world.meta.values.ItemFilterValue; -public class ItemTurret extends CooledTurret { +public class ItemTurret extends CooledTurret{ protected int maxAmmo = 50; protected AmmoType[] ammoTypes; protected ObjectMap ammoMap = new ObjectMap<>(); - public ItemTurret(String name) { + public ItemTurret(String name){ super(name); hasItems = true; } @Override - public void setStats() { + public void setStats(){ super.setStats(); stats.remove(BlockStat.itemCapacity); @@ -31,31 +31,31 @@ public class ItemTurret extends CooledTurret { } @Override - public int acceptStack(Item item, int amount, Tile tile, Unit source) { + public int acceptStack(Item item, int amount, Tile tile, Unit source){ TurretEntity entity = tile.entity(); AmmoType type = ammoMap.get(item); if(type == null) return 0; - return Math.min((int)((maxAmmo - entity.totalAmmo) / ammoMap.get(item).quantityMultiplier), amount); + return Math.min((int) ((maxAmmo - entity.totalAmmo) / ammoMap.get(item).quantityMultiplier), amount); } - + @Override public void handleStack(Item item, int amount, Tile tile, Unit source){ - for (int i = 0; i < amount; i++) { + for(int i = 0; i < amount; i++){ handleItem(item, tile, null); } } //currently can't remove items from turrets. @Override - public int removeStack(Tile tile, Item item, int amount) { + public int removeStack(Tile tile, Item item, int amount){ return 0; } @Override - public void handleItem(Item item, Tile tile, Tile source) { + public void handleItem(Item item, Tile tile, Tile source){ TurretEntity entity = tile.entity(); AmmoType type = ammoMap.get(item); @@ -63,19 +63,19 @@ public class ItemTurret extends CooledTurret { entity.items.add(item, 1); //find ammo entry by type - for(int i = 0; i < entity.ammo.size; i ++){ + for(int i = 0; i < entity.ammo.size; i++){ AmmoEntry entry = entity.ammo.get(i); //if found, put it to the right if(entry.type == type){ entry.amount += type.quantityMultiplier; - entity.ammo.swap(i, entity.ammo.size-1); + entity.ammo.swap(i, entity.ammo.size - 1); return; } } //must not be found - AmmoEntry entry = new AmmoEntry(type, (int)type.quantityMultiplier); + AmmoEntry entry = new AmmoEntry(type, (int) type.quantityMultiplier); entity.ammo.add(entry); } @@ -89,19 +89,19 @@ public class ItemTurret extends CooledTurret { @Override public void setBars(){ super.setBars(); - bars.replace(new BlockBar(BarType.inventory, true, tile -> (float)tile.entity().totalAmmo / maxAmmo)); + bars.replace(new BlockBar(BarType.inventory, true, tile -> (float) tile.entity().totalAmmo / maxAmmo)); } @Override public void init(){ super.init(); - if(ammoTypes != null) { - for (AmmoType type : ammoTypes) { + if(ammoTypes != null){ + for(AmmoType type : ammoTypes){ if(type.item == null) continue; - if (ammoMap.containsKey(type.item)) { + if(ammoMap.containsKey(type.item)){ throw new RuntimeException("Turret \"" + name + "\" has two conflicting ammo entries on item type " + type.item + "!"); - } else { + }else{ ammoMap.put(type.item, type); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/LaserTurret.java b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/LaserTurret.java index 1b69866132..63115407cf 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/LaserTurret.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/LaserTurret.java @@ -10,7 +10,7 @@ import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.tilesize; -public class LaserTurret extends PowerTurret { +public class LaserTurret extends PowerTurret{ protected float chargeTime = 30f; protected int chargeEffects = 5; @@ -18,7 +18,7 @@ public class LaserTurret extends PowerTurret { protected Effect chargeEffect = Fx.none; protected Effect chargeBeginEffect = Fx.none; - public LaserTurret(String name) { + public LaserTurret(String name){ super(name); } @@ -31,7 +31,7 @@ public class LaserTurret extends PowerTurret { tr.trns(entity.rotation, size * tilesize / 2); Effects.effect(chargeBeginEffect, tile.drawx() + tr.x, tile.drawy() + tr.y, entity.rotation); - for(int i = 0; i < chargeEffects; i ++){ + for(int i = 0; i < chargeEffects; i++){ Timers.run(Mathf.random(chargeMaxDelay), () -> { if(!isTurret(tile)) return; tr.trns(entity.rotation, size * tilesize / 2); diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/LiquidTurret.java b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/LiquidTurret.java index e4ac82acfb..e053be47e1 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/LiquidTurret.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/LiquidTurret.java @@ -11,24 +11,24 @@ import io.anuke.mindustry.world.meta.BlockStat; import io.anuke.mindustry.world.meta.values.LiquidFilterValue; import io.anuke.ucore.core.Effects; -public abstract class LiquidTurret extends Turret { +public abstract class LiquidTurret extends Turret{ protected AmmoType[] ammoTypes; protected ObjectMap liquidAmmoMap = new ObjectMap<>(); - public LiquidTurret(String name) { + public LiquidTurret(String name){ super(name); hasLiquids = true; } @Override - public void setStats() { + public void setStats(){ super.setStats(); stats.add(BlockStat.inputLiquid, new LiquidFilterValue(item -> liquidAmmoMap.containsKey(item))); } @Override - public void setBars() { + public void setBars(){ super.setBars(); bars.remove(BarType.inventory); bars.replace(new BlockBar(BarType.liquid, true, tile -> tile.entity.liquids.total() / liquidCapacity)); @@ -43,7 +43,7 @@ public abstract class LiquidTurret extends Turret { Effects.effect(shootEffect, type.liquid.color, tile.drawx() + tr.x, tile.drawy() + tr.y, entity.rotation); Effects.effect(smokeEffect, type.liquid.color, tile.drawx() + tr.x, tile.drawy() + tr.y, entity.rotation); - if (shootShake > 0) { + if(shootShake > 0){ Effects.shake(shootShake, shootShake, tile.entity); } @@ -73,17 +73,17 @@ public abstract class LiquidTurret extends Turret { public void init(){ super.init(); - for (AmmoType type : ammoTypes) { - if (liquidAmmoMap.containsKey(type.liquid)) { + for(AmmoType type : ammoTypes){ + if(liquidAmmoMap.containsKey(type.liquid)){ throw new RuntimeException("Turret \"" + name + "\" has two conflicting ammo entries on liquid type " + type.liquid + "!"); - } else { + }else{ liquidAmmoMap.put(type.liquid, type); } } } @Override - public boolean acceptItem(Item item, Tile tile, Tile source) { + public boolean acceptItem(Item item, Tile tile, Tile source){ return false; } diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/PowerTurret.java b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/PowerTurret.java index da4580cd2b..0c1b84698f 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/PowerTurret.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/PowerTurret.java @@ -5,35 +5,35 @@ import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.meta.BlockStat; import io.anuke.mindustry.world.meta.StatUnit; -public abstract class PowerTurret extends CooledTurret { - protected float powerUsed = 0.5f; - protected AmmoType shootType; +public abstract class PowerTurret extends CooledTurret{ + protected float powerUsed = 0.5f; + protected AmmoType shootType; - public PowerTurret(String name) { - super(name); - hasPower = true; - } - - @Override - public void setStats(){ - super.setStats(); + public PowerTurret(String name){ + super(name); + hasPower = true; + } - stats.add(BlockStat.powerShot, powerUsed, StatUnit.powerUnits); - } - - @Override - public boolean hasAmmo(Tile tile){ - return tile.entity.power.amount >= powerUsed; - } + @Override + public void setStats(){ + super.setStats(); - @Override - public AmmoType useAmmo(Tile tile){ - tile.entity.power.amount -= powerUsed; - return shootType; - } + stats.add(BlockStat.powerShot, powerUsed, StatUnit.powerUnits); + } - @Override - public AmmoType peekAmmo(Tile tile) { - return shootType; - } + @Override + public boolean hasAmmo(Tile tile){ + return tile.entity.power.amount >= powerUsed; + } + + @Override + public AmmoType useAmmo(Tile tile){ + tile.entity.power.amount -= powerUsed; + return shootType; + } + + @Override + public AmmoType peekAmmo(Tile tile){ + return shootType; + } } diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/Turret.java b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/Turret.java index abebf95b80..a6171e6cb5 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/Turret.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/Turret.java @@ -39,298 +39,304 @@ import java.io.IOException; import static io.anuke.mindustry.Vars.tilesize; public abstract class Turret extends Block{ - protected static final int targetInterval = 15; - - protected final int timerTarget = timers++; + protected static final int targetInterval = 15; - protected Color heatColor = Palette.turretHeat; - protected Effect shootEffect = Fx.none; - protected Effect smokeEffect = Fx.none; - protected Effect ammoUseEffect = Fx.none; + protected final int timerTarget = timers++; + + protected Color heatColor = Palette.turretHeat; + protected Effect shootEffect = Fx.none; + protected Effect smokeEffect = Fx.none; + protected Effect ammoUseEffect = Fx.none; protected int ammoPerShot = 1; protected float ammoEjectBack = 1f; - protected float range = 50f; - protected float reload = 10f; - protected float inaccuracy = 0f; - protected int shots = 1; - protected float recoil = 1f; - protected float restitution = 0.02f; - protected float cooldown = 0.02f; - protected float rotatespeed = 5f; //in degrees per tick - protected float shootCone = 8f; - protected float shootShake = 0f; - protected boolean targetAir = true; + protected float range = 50f; + protected float reload = 10f; + protected float inaccuracy = 0f; + protected int shots = 1; + protected float recoil = 1f; + protected float restitution = 0.02f; + protected float cooldown = 0.02f; + protected float rotatespeed = 5f; //in degrees per tick + protected float shootCone = 8f; + protected float shootShake = 0f; + protected boolean targetAir = true; - protected Translator tr = new Translator(); - protected Translator tr2 = new Translator(); + protected Translator tr = new Translator(); + protected Translator tr2 = new Translator(); - protected TextureRegion baseRegion; - protected TextureRegion heatRegion; - protected TextureRegion baseTopRegion; + protected TextureRegion baseRegion; + protected TextureRegion heatRegion; + protected TextureRegion baseTopRegion; protected BiConsumer drawer = (tile, entity) -> Draw.rect(region, tile.drawx() + tr2.x, tile.drawy() + tr2.y, entity.rotation - 90); - protected BiConsumer heatDrawer = (tile, entity) ->{ - if(entity.heat <= 0.00001f) return; - Graphics.setAdditiveBlending(); - Draw.color(heatColor); - Draw.alpha(entity.heat); - Draw.rect(heatRegion, tile.drawx() + tr2.x, tile.drawy() + tr2.y, entity.rotation - 90); - Graphics.setNormalBlending(); - }; + protected BiConsumer heatDrawer = (tile, entity) -> { + if(entity.heat <= 0.00001f) return; + Graphics.setAdditiveBlending(); + Draw.color(heatColor); + Draw.alpha(entity.heat); + Draw.rect(heatRegion, tile.drawx() + tr2.x, tile.drawy() + tr2.y, entity.rotation - 90); + Graphics.setNormalBlending(); + }; - public Turret(String name) { - super(name); - update = true; - solid = true; - layer = Layer.turret; - group = BlockGroup.turrets; - } + public Turret(String name){ + super(name); + update = true; + solid = true; + layer = Layer.turret; + group = BlockGroup.turrets; + } - @Override - public void init() { - super.init(); - viewRange = range; - } + @Override + public void init(){ + super.init(); + viewRange = range; + } - @Override - public void load() { - super.load(); + @Override + public void load(){ + super.load(); - baseRegion = Draw.region("block-" + size); - baseTopRegion = Draw.region("block-" +size + "-top"); - heatRegion = Draw.region(name + "-heat"); - } + baseRegion = Draw.region("block-" + size); + baseTopRegion = Draw.region("block-" + size + "-top"); + heatRegion = Draw.region(name + "-heat"); + } - @Override - public void setStats(){ - super.setStats(); + @Override + public void setStats(){ + super.setStats(); /* if(ammo != null) stats.add("ammo", ammo); if(ammo != null) stats.add("ammocapacity", maxAmmo); if(ammo != null) stats.add("ammoitem", ammoMultiplier);*/ - stats.add(BlockStat.shootRange, range, StatUnit.blocks); - stats.add(BlockStat.inaccuracy, (int)inaccuracy, StatUnit.degrees); - stats.add(BlockStat.reload, 60f/reload, StatUnit.seconds); - stats.add(BlockStat.shots, shots, StatUnit.none); - stats.add(BlockStat.targetsAir, targetAir); - } - - @Override - public void draw(Tile tile){ - Draw.rect(baseRegion, tile.drawx(), tile.drawy()); - Draw.color(tile.getTeam().color, Color.WHITE, 0.45f); - Draw.rect(baseTopRegion, tile.drawx(), tile.drawy()); - Draw.color(); - } - - @Override - public void drawLayer(Tile tile){ - TurretEntity entity = tile.entity(); + stats.add(BlockStat.shootRange, range, StatUnit.blocks); + stats.add(BlockStat.inaccuracy, (int) inaccuracy, StatUnit.degrees); + stats.add(BlockStat.reload, 60f / reload, StatUnit.seconds); + stats.add(BlockStat.shots, shots, StatUnit.none); + stats.add(BlockStat.targetsAir, targetAir); + } - tr2.trns(entity.rotation, -entity.recoil); + @Override + public void draw(Tile tile){ + Draw.rect(baseRegion, tile.drawx(), tile.drawy()); + Draw.color(tile.getTeam().color, Color.WHITE, 0.45f); + Draw.rect(baseTopRegion, tile.drawx(), tile.drawy()); + Draw.color(); + } - drawer.accept(tile, entity); + @Override + public void drawLayer(Tile tile){ + TurretEntity entity = tile.entity(); - if(heatRegion != null){ - heatDrawer.accept(tile, entity); - } + tr2.trns(entity.rotation, -entity.recoil); - Draw.color(); - } + drawer.accept(tile, entity); - @Override + if(heatRegion != null){ + heatDrawer.accept(tile, entity); + } + + Draw.color(); + } + + @Override public TextureRegion[] getBlockIcon(){ - if(blockIcon == null){ - blockIcon = new TextureRegion[]{Draw.region("block-icon-" + name)}; + if(blockIcon == null){ + blockIcon = new TextureRegion[]{Draw.region("block-icon-" + name)}; } return blockIcon; } @Override - public TextureRegion[] getCompactIcon(){ - if(compactIcon == null) { - compactIcon = new TextureRegion[]{iconRegion(Draw.region("block-icon-" + name))}; - } - return compactIcon; - } + public TextureRegion[] getCompactIcon(){ + if(compactIcon == null){ + compactIcon = new TextureRegion[]{iconRegion(Draw.region("block-icon-" + name))}; + } + return compactIcon; + } - @Override - public void drawSelect(Tile tile){ - Draw.color(tile.getTeam().color); - Lines.dashCircle(tile.drawx(), tile.drawy(), range); - Draw.reset(); - } - - @Override - public void drawPlace(int x, int y, int rotation, boolean valid){ - Draw.color(Palette.placing); - Lines.stroke(1f); - Lines.dashCircle(x * tilesize + offset(), y * tilesize + offset(), range); - } + @Override + public void drawSelect(Tile tile){ + Draw.color(tile.getTeam().color); + Lines.dashCircle(tile.drawx(), tile.drawy(), range); + Draw.reset(); + } - @Override - public void update(Tile tile){ - TurretEntity entity = tile.entity(); - - if(entity.target != null && entity.target.isDead()) - entity.target = null; + @Override + public void drawPlace(int x, int y, int rotation, boolean valid){ + Draw.color(Palette.placing); + Lines.stroke(1f); + Lines.dashCircle(x * tilesize + offset(), y * tilesize + offset(), range); + } - entity.recoil = Mathf.lerpDelta(entity.recoil, 0f, restitution); - entity.heat = Mathf.lerpDelta(entity.heat, 0f, cooldown); - - if(hasAmmo(tile)){ - - if(entity.timer.get(timerTarget, targetInterval)){ - entity.target = Units.getClosestEnemy(tile.getTeam(), - tile.drawx(), tile.drawy(), range, e -> !e.isDead() && (!e.isFlying() || targetAir)); - } - - if(entity.target != null){ - AmmoType type = peekAmmo(tile); - float speed = type.bullet.speed; - if(speed < 0.1f) speed = 9999999f; + @Override + public void update(Tile tile){ + TurretEntity entity = tile.entity(); - Vector2 result = Predict.intercept(entity, entity.target, speed); - if(result.isZero()){ - result.set(entity.target.getX(), entity.target.getY()); - } - - float targetRot = result.sub(tile.drawx(), tile.drawy()).angle(); - - if(Float.isNaN(entity.rotation)){ - entity.rotation = 0; - } + if(entity.target != null && entity.target.isDead()) + entity.target = null; - entity.rotation = Angles.moveToward(entity.rotation, targetRot, rotatespeed * Timers.delta()); + entity.recoil = Mathf.lerpDelta(entity.recoil, 0f, restitution); + entity.heat = Mathf.lerpDelta(entity.heat, 0f, cooldown); - if(Angles.angleDist(entity.rotation, targetRot) < shootCone){ - updateShooting(tile); - } - } - } - } + if(hasAmmo(tile)){ - /**Consume ammo and return a type.*/ - public AmmoType useAmmo(Tile tile){ + if(entity.timer.get(timerTarget, targetInterval)){ + entity.target = Units.getClosestEnemy(tile.getTeam(), + tile.drawx(), tile.drawy(), range, e -> !e.isDead() && (!e.isFlying() || targetAir)); + } + + if(entity.target != null){ + AmmoType type = peekAmmo(tile); + float speed = type.bullet.speed; + if(speed < 0.1f) speed = 9999999f; + + Vector2 result = Predict.intercept(entity, entity.target, speed); + if(result.isZero()){ + result.set(entity.target.getX(), entity.target.getY()); + } + + float targetRot = result.sub(tile.drawx(), tile.drawy()).angle(); + + if(Float.isNaN(entity.rotation)){ + entity.rotation = 0; + } + + entity.rotation = Angles.moveToward(entity.rotation, targetRot, rotatespeed * Timers.delta()); + + if(Angles.angleDist(entity.rotation, targetRot) < shootCone){ + updateShooting(tile); + } + } + } + } + + /** + * Consume ammo and return a type. + */ + public AmmoType useAmmo(Tile tile){ TurretEntity entity = tile.entity(); AmmoEntry entry = entity.ammo.peek(); entry.amount -= ammoPerShot; if(entry.amount == 0) entity.ammo.pop(); entity.totalAmmo -= ammoPerShot; - Timers.run(reload/2f, () -> ejectEffects(tile)); + Timers.run(reload / 2f, () -> ejectEffects(tile)); return entry.type; } - /**Get the ammo type that will be returned if useAmmo is called.*/ + /** + * Get the ammo type that will be returned if useAmmo is called. + */ public AmmoType peekAmmo(Tile tile){ TurretEntity entity = tile.entity(); return entity.ammo.peek().type; } - /**Returns whether the turret has ammo.*/ - public boolean hasAmmo(Tile tile){ - TurretEntity entity = tile.entity(); - return entity.ammo.size > 0 && entity.ammo.peek().amount >= ammoPerShot; - } - - protected void updateShooting(Tile tile){ - TurretEntity entity = tile.entity(); + /** + * Returns whether the turret has ammo. + */ + public boolean hasAmmo(Tile tile){ + TurretEntity entity = tile.entity(); + return entity.ammo.size > 0 && entity.ammo.peek().amount >= ammoPerShot; + } - if(entity.reload >= reload) { - AmmoType type = peekAmmo(tile); + protected void updateShooting(Tile tile){ + TurretEntity entity = tile.entity(); + + if(entity.reload >= reload){ + AmmoType type = peekAmmo(tile); shoot(tile, type); entity.reload = 0f; }else{ - entity.reload += Timers.delta() * peekAmmo(tile).reloadMultiplier; - } - } + entity.reload += Timers.delta() * peekAmmo(tile).reloadMultiplier; + } + } - protected void shoot(Tile tile, AmmoType ammo){ - TurretEntity entity = tile.entity(); + protected void shoot(Tile tile, AmmoType ammo){ + TurretEntity entity = tile.entity(); - entity.recoil = recoil; - entity.heat = 1f; + entity.recoil = recoil; + entity.heat = 1f; - AmmoType type = peekAmmo(tile); - useAmmo(tile); + AmmoType type = peekAmmo(tile); + useAmmo(tile); - tr.trns(entity.rotation, size * tilesize / 2); + tr.trns(entity.rotation, size * tilesize / 2); - bullet(tile, ammo.bullet, entity.rotation + Mathf.range(inaccuracy + type.inaccuracy)); + bullet(tile, ammo.bullet, entity.rotation + Mathf.range(inaccuracy + type.inaccuracy)); - effects(tile); - } - - protected void bullet(Tile tile, BulletType type, float angle){ - Bullet.create(type, tile.entity, tile.getTeam(), tile.drawx() + tr.x, tile.drawy() + tr.y, angle); - } + effects(tile); + } - protected void effects(Tile tile){ - Effect shootEffect = this.shootEffect == Fx.none ? peekAmmo(tile).shootEffect : this.shootEffect; - Effect smokeEffect = this.smokeEffect == Fx.none ? peekAmmo(tile).smokeEffect : this.smokeEffect; + protected void bullet(Tile tile, BulletType type, float angle){ + Bullet.create(type, tile.entity, tile.getTeam(), tile.drawx() + tr.x, tile.drawy() + tr.y, angle); + } - TurretEntity entity = tile.entity(); + protected void effects(Tile tile){ + Effect shootEffect = this.shootEffect == Fx.none ? peekAmmo(tile).shootEffect : this.shootEffect; + Effect smokeEffect = this.smokeEffect == Fx.none ? peekAmmo(tile).smokeEffect : this.smokeEffect; - Effects.effect(shootEffect, tile.drawx() + tr.x, tile.drawy() + tr.y, entity.rotation); - Effects.effect(smokeEffect, tile.drawx() + tr.x, tile.drawy() + tr.y, entity.rotation); + TurretEntity entity = tile.entity(); - if (shootShake > 0) { - Effects.shake(shootShake, shootShake, tile.entity); - } + Effects.effect(shootEffect, tile.drawx() + tr.x, tile.drawy() + tr.y, entity.rotation); + Effects.effect(smokeEffect, tile.drawx() + tr.x, tile.drawy() + tr.y, entity.rotation); - entity.recoil = recoil; - } + if(shootShake > 0){ + Effects.shake(shootShake, shootShake, tile.entity); + } - protected void ejectEffects(Tile tile){ - if(!isTurret(tile)) return; - TurretEntity entity = tile.entity(); + entity.recoil = recoil; + } - Effects.effect(ammoUseEffect, tile.drawx() - Angles.trnsx(entity.rotation, ammoEjectBack), - tile.drawy() - Angles.trnsy(entity.rotation, ammoEjectBack), entity.rotation); - } + protected void ejectEffects(Tile tile){ + if(!isTurret(tile)) return; + TurretEntity entity = tile.entity(); - protected boolean isTurret(Tile tile){ - return (tile.entity instanceof TurretEntity); - } + Effects.effect(ammoUseEffect, tile.drawx() - Angles.trnsx(entity.rotation, ammoEjectBack), + tile.drawy() - Angles.trnsy(entity.rotation, ammoEjectBack), entity.rotation); + } - @Override - public TileEntity getEntity(){ - return new TurretEntity(); - } - - public static class TurretEntity extends TileEntity{ - public TileEntity blockTarget; - public Array ammo = new ThreadArray<>(); - public int totalAmmo; - public float reload; - public float rotation = 90; - public float recoil = 0f; - public float heat; - public int shots; - public Unit target; - - @Override - public void write(DataOutputStream stream) throws IOException{ - stream.writeByte(ammo.size); - for(AmmoEntry entry : ammo){ + protected boolean isTurret(Tile tile){ + return (tile.entity instanceof TurretEntity); + } + + @Override + public TileEntity getEntity(){ + return new TurretEntity(); + } + + public static class TurretEntity extends TileEntity{ + public TileEntity blockTarget; + public Array ammo = new ThreadArray<>(); + public int totalAmmo; + public float reload; + public float rotation = 90; + public float recoil = 0f; + public float heat; + public int shots; + public Unit target; + + @Override + public void write(DataOutputStream stream) throws IOException{ + stream.writeByte(ammo.size); + for(AmmoEntry entry : ammo){ stream.writeByte(entry.type.id); stream.writeShort(entry.amount); } - } - - @Override - public void read(DataInputStream stream) throws IOException{ - byte amount = stream.readByte(); - for(int i = 0; i < amount; i ++){ - AmmoType type = AmmoType.getByID(stream.readByte()); - short ta = stream.readShort(); - ammo.add(new AmmoEntry(type, ta)); - totalAmmo += ta; + } + + @Override + public void read(DataInputStream stream) throws IOException{ + byte amount = stream.readByte(); + for(int i = 0; i < amount; i++){ + AmmoType type = AmmoType.getByID(stream.readByte()); + short ta = stream.readShort(); + ammo.add(new AmmoEntry(type, ta)); + totalAmmo += ta; } - } - } + } + } } diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/BufferedItemBridge.java b/core/src/io/anuke/mindustry/world/blocks/distribution/BufferedItemBridge.java index c16ae2f2bf..bd5a6bfb8e 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/BufferedItemBridge.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/BufferedItemBridge.java @@ -10,13 +10,13 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; -public class BufferedItemBridge extends ExtendingItemBridge { - protected int timerAccept = timers ++; +public class BufferedItemBridge extends ExtendingItemBridge{ + protected int timerAccept = timers++; protected float speed = 40f; protected int bufferCapacity = 50; - public BufferedItemBridge(String name) { + public BufferedItemBridge(String name){ super(name); hasPower = false; hasItems = true; @@ -41,7 +41,7 @@ public class BufferedItemBridge extends ExtendingItemBridge { } @Override - public TileEntity getEntity() { + public TileEntity getEntity(){ return new BufferedItemBridgeEntity(); } @@ -49,12 +49,12 @@ public class BufferedItemBridge extends ExtendingItemBridge { ItemBuffer buffer = new ItemBuffer(bufferCapacity, speed); @Override - public void write(DataOutputStream stream) throws IOException { + public void write(DataOutputStream stream) throws IOException{ super.write(stream); } @Override - public void read(DataInputStream stream) throws IOException { + public void read(DataInputStream stream) throws IOException{ super.read(stream); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/Conduit.java b/core/src/io/anuke/mindustry/world/blocks/distribution/Conduit.java index 99b8fbfafc..08f908b2ea 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/Conduit.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/Conduit.java @@ -13,24 +13,24 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; -public class Conduit extends LiquidBlock { +public class Conduit extends LiquidBlock{ protected final int timerFlow = timers++; protected TextureRegion[] topRegions = new TextureRegion[7]; protected TextureRegion[] botRegions = new TextureRegion[7]; - public Conduit(String name) { + public Conduit(String name){ super(name); rotate = true; solid = false; } @Override - public void load() { + public void load(){ super.load(); liquidRegion = Draw.region("conduit-liquid"); - for (int i = 0; i < topRegions.length; i++) { + for(int i = 0; i < topRegions.length; i++){ topRegions[i] = Draw.region(name + "-top-" + i); botRegions[i] = Draw.region("conduit-bottom-" + i); } @@ -40,23 +40,23 @@ public class Conduit extends LiquidBlock { ConduitEntity entity = tile.entity(); entity.blendbits = 0; - if(blends(tile, 2) && blends(tile, 1) && blends(tile, 3)) { + if(blends(tile, 2) && blends(tile, 1) && blends(tile, 3)){ entity.blendbits = 3; - }else if(blends(tile, 1) && blends(tile, 2)) { + }else if(blends(tile, 1) && blends(tile, 2)){ entity.blendbits = 2; - }else if(blends(tile, 3) && blends(tile, 2)) { + }else if(blends(tile, 3) && blends(tile, 2)){ entity.blendbits = 4; }else if(blends(tile, 0)){ - if(blends(tile, 1) && blends(tile, 3)) { + if(blends(tile, 1) && blends(tile, 3)){ entity.blendbits = 6; - }else if(blends(tile, 1)) { + }else if(blends(tile, 1)){ entity.blendbits = 5; - }else if(blends(tile, 3)) { + }else if(blends(tile, 3)){ entity.blendbits = 1; } - }else if(blends(tile, 1)) { + }else if(blends(tile, 1)){ entity.blendbits = 5; - }else if(blends(tile, 3)) { + }else if(blends(tile, 3)){ entity.blendbits = 1; } } @@ -90,7 +90,7 @@ public class Conduit extends LiquidBlock { @Override public void update(Tile tile){ ConduitEntity entity = tile.entity(); - entity.smoothLiquid = Mathf.lerpDelta(entity.smoothLiquid, entity.liquids.total()/liquidCapacity, 0.05f); + entity.smoothLiquid = Mathf.lerpDelta(entity.smoothLiquid, entity.liquids.total() / liquidCapacity, 0.05f); if(tile.entity.liquids.total() > 0.001f && tile.entity.timer.get(timerFlow, 1)){ tryMoveLiquid(tile, tile.getNearby(tile.getRotation()), true, tile.entity.liquids.current()); @@ -109,27 +109,27 @@ public class Conduit extends LiquidBlock { } @Override - public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount) { + public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){ tile.entity.wakeUp(); return super.acceptLiquid(tile, source, liquid, amount) && ((2 + source.relativeTo(tile.x, tile.y)) % 4 != tile.getRotation()); } @Override - public TileEntity getEntity() { + public TileEntity getEntity(){ return new ConduitEntity(); } - public static class ConduitEntity extends TileEntity { + public static class ConduitEntity extends TileEntity{ public float smoothLiquid; public byte blendbits; @Override - public void write(DataOutputStream stream) throws IOException { + public void write(DataOutputStream stream) throws IOException{ stream.writeFloat(smoothLiquid); } @Override - public void read(DataInputStream stream) throws IOException { + public void read(DataInputStream stream) throws IOException{ smoothLiquid = stream.readFloat(); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java b/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java index d47d269d16..d62e936095 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java @@ -25,410 +25,410 @@ import static io.anuke.mindustry.Vars.itemSize; import static io.anuke.mindustry.Vars.tilesize; public class Conveyor extends Block{ - private static ItemPos drawpos = new ItemPos(); - private static ItemPos pos1 = new ItemPos(); - private static ItemPos pos2 = new ItemPos(); - - private static final float itemSpace = 0.135f * 2.2f; - private static final float offsetScl = 128f*3f; - private static final float minmove = 1f / (Short.MAX_VALUE - 2); - - private final Translator tr1 = new Translator(); - private final Translator tr2 = new Translator(); - private final TextureRegion region1 = new TextureRegion(); - private final TextureRegion region2 = new TextureRegion(); - - protected float speed = 0f; - protected float carryCapacity = 8f; - - protected Conveyor(String name) { - super(name); - rotate = true; - update = true; - layer = Layer.overlay; - group = BlockGroup.transportation; - hasItems = true; - autoSleep = true; - itemCapacity = Math.round(tilesize/ itemSpace); - } - - @Override - public void setBars() {} - - @Override - public void setStats(){ - super.setStats(); - stats.add(BlockStat.itemSpeed, speed * 60, StatUnit.pixelsSecond); - } - - @Override - public void draw(Tile tile){ - ConveyorEntity entity = tile.entity(); - byte rotation = tile.getRotation(); - - GridPoint2 point = Geometry.d4[rotation]; - - int offset = entity.clogHeat <= 0.5f ? (int)((Timers.time()/4f)%8) : 0; - TextureRegion region = Draw.region(name); - - region1.setRegion(region, 0, 0, region.getRegionWidth() - offset, region.getRegionHeight()); - region2.setRegion(region, region.getRegionWidth() - offset, 0, offset, region.getRegionHeight()); - - float x = tile.drawx(), y = tile.drawy(); - - if(offset % 2 == 1){ - if(point.x < 0) x += 0.75f; - if(point.y < 0) - y += 0.5f; - else if(point.y > 0) - y -= 0.5f; - } - - Draw.rect(region1, - x + (point.x * (tilesize/2f - region1.getRegionWidth()/2f)), - y + (point.y * (tilesize/2f - region1.getRegionWidth()/2f)), rotation * 90); - Draw.rect(region2, - x - (point.x * (tilesize/2f - region2.getRegionWidth()/2f)), - y - (point.y * (tilesize/2f - region2.getRegionWidth()/2f)), rotation * 90); - } - - @Override - public boolean isLayer(Tile tile){ - return tile.entity().convey.size > 0; - } - - @Override - public void drawLayer(Tile tile){ - ConveyorEntity entity = tile.entity(); - - byte rotation = tile.getRotation(); - - try { - - for (int i = 0; i < entity.convey.size; i++) { - ItemPos pos = drawpos.set(entity.convey.get(i), ItemPos.drawShorts); - - if (pos.item == null) continue; - - tr1.trns(rotation * 90, tilesize, 0); - tr2.trns(rotation * 90, -tilesize / 2, pos.x * tilesize / 2); - - Draw.rect(pos.item.region, - (int)(tile.x * tilesize + tr1.x * pos.y + tr2.x), - (int)(tile.y * tilesize + tr1.y * pos.y + tr2.y), itemSize, itemSize); - } - - }catch (IndexOutOfBoundsException e){ - Log.err(e); - } - } - - @Override - public void unitOn(Tile tile, Unit unit) { - ConveyorEntity entity = tile.entity(); - - entity.wakeUp(); - - float speed = this.speed * tilesize / 2.3f; - float tx = Geometry.d4[tile.getRotation()].x, ty = Geometry.d4[tile.getRotation()].y; - - float min; - - if(Math.abs(tx) > Math.abs(ty)){ - float rx = tile.worldx() - tx/2f*tilesize; - min = Mathf.clamp((unit.x - rx) * tx / tilesize); - }else{ - float ry = tile.worldy() - ty/2f*tilesize; - min = Mathf.clamp((unit.y - ry) * ty / tilesize); - } - - entity.minCarry = Math.min(entity.minCarry, min); - entity.carrying += unit.getMass(); - - if(entity.convey.size * itemSpace < 0.9f){ - unit.getVelocity().add(tx * speed * Timers.delta(), ty * speed * Timers.delta()); - } - } - - @Override - public synchronized void update(Tile tile){ - - ConveyorEntity entity = tile.entity(); - entity.minitem = 1f; - - int minremove = Integer.MAX_VALUE; - float speed = Math.max(this.speed - (1f - (carryCapacity - entity.carrying) / carryCapacity), 0f); - float totalMoved = 0f; - - for (int i = entity.convey.size - 1; i >= 0; i--) { - long value = entity.convey.get(i); - ItemPos pos = pos1.set(value, ItemPos.updateShorts); - - //..this should never happen, but in case it does, remove it and stop here - if (pos.item == null) { - entity.convey.removeValue(value); - break; - } - - float nextpos = (i == entity.convey.size - 1 ? 100f : pos2.set(entity.convey.get(i + 1), ItemPos.updateShorts).y) - itemSpace; - if (entity.minCarry >= pos.y && entity.minCarry <= nextpos) { - nextpos = entity.minCarry; - } - float maxmove = Math.min(nextpos - pos.y, speed * Timers.delta()); - - if (maxmove > minmove) { - pos.y += maxmove; - pos.x = Mathf.lerpDelta(pos.x, 0, 0.06f); - totalMoved += maxmove; - } else { - pos.x = Mathf.lerpDelta(pos.x, pos.seed / offsetScl, 0.1f); - } - - pos.y = Mathf.clamp(pos.y); - - if (pos.y >= 0.9999f && offloadDir(tile, pos.item)) { - minremove = Math.min(i, minremove); - totalMoved = 1f; - tile.entity.items.remove(pos.item, 1); - } else { - value = pos.pack(); - - if (pos.y < entity.minitem) - entity.minitem = pos.y; - entity.convey.set(i, value); - } - } - - if(entity.minitem < itemSpace){ - entity.clogHeat = Mathf.lerpDelta(entity.clogHeat, 1f, 0.02f); - }else{ - entity.clogHeat = Mathf.lerpDelta(entity.clogHeat, 0f, 1f); - } - - entity.carrying = 0f; - entity.minCarry = 2f; - - if(totalMoved <= 0.0001f){ - entity.sleep(); - } - - if (minremove != Integer.MAX_VALUE) entity.convey.truncate(minremove); - } - - @Override - public boolean isAccessible(){ - return true; - } - - @Override - public synchronized int removeStack(Tile tile, Item item, int amount) { - ConveyorEntity entity = tile.entity(); - entity.wakeUp(); - int removed = 0; - - for(int j = 0; j < amount; j ++) { - for (int i = 0; i < entity.convey.size; i++) { - long val = entity.convey.get(i); - ItemPos pos = pos1.set(val, ItemPos.drawShorts); - if(pos.item == item){ - entity.convey.removeValue(val); - entity.items.remove(item, 1); - removed ++; - break; - } - } - } - return removed; - } - - @Override - public void getStackOffset(Item item, Tile tile, Translator trns) { - trns.trns(tile.getRotation()*90 + 180f, tilesize/2f); - } - - @Override - public synchronized int acceptStack(Item item, int amount, Tile tile, Unit source) { - ConveyorEntity entity = tile.entity(); - return entity.minitem > itemSpace ? 1 : 0; - } - - @Override - public synchronized void handleStack(Item item, int amount, Tile tile, Unit source) { - ConveyorEntity entity = tile.entity(); - - long result = ItemPos.packItem(item, 0f, 0f, (byte)Mathf.random(255)); - entity.convey.insert(0, result); - entity.items.add(item, 1); - entity.wakeUp(); - } - - @Override - public boolean acceptItem(Item item, Tile tile, Tile source){ - int direction = source == null ? 0 : Math.abs(source.relativeTo(tile.x, tile.y) - tile.getRotation()); - float minitem = tile.entity().minitem; - return (((direction == 0) && minitem > itemSpace) || - ((direction %2 == 1) && minitem > 0.52f)) && (source == null || !(source.block().rotate && (source.getRotation() + 2) % 4 == tile.getRotation())); - } - - @Override - public void handleItem(Item item, Tile tile, Tile source){ - byte rotation = tile.getRotation(); - - int ch = Math.abs(source.relativeTo(tile.x, tile.y) - rotation); - int ang = ((source.relativeTo(tile.x, tile.y) - rotation)); - - float pos = ch == 0 ? 0 : ch % 2 == 1 ? 0.5f : 1f; - float y = (ang == -1 || ang == 3) ? 1 : (ang == 1 || ang == -3) ? -1 : 0; - - ConveyorEntity entity = tile.entity(); - entity.wakeUp(); - long result = ItemPos.packItem(item, y*0.9f, pos, (byte)Mathf.random(255)); - boolean inserted = false; - - tile.entity.items.add(item, 1); - - for(int i = 0; i < entity.convey.size; i ++){ - if(compareItems(result, entity.convey.get(i)) < 0){ - entity.convey.insert(i, result); - inserted = true; - break; - } - } - - //this item must be greater than anything there... - if(!inserted){ - entity.convey.add(result); - } - } - - @Override - public Array getDebugInfo(Tile tile) { - ConveyorEntity entity = tile.entity(); - Array arr = super.getDebugInfo(tile); - arr.addAll(Array.with( - "mincarry", entity.minCarry, - "minitem", entity.minCarry, - "carrying", entity.carrying, - "clogHeat", entity.clogHeat, - "sleeping", entity.isSleeping() - )); - return arr; - } - - @Override - public TileEntity getEntity(){ - return new ConveyorEntity(); - } - - public static class ConveyorEntity extends TileEntity{ - - LongArray convey = new LongArray(); - float minitem = 1; - float carrying; - float minCarry = 2f; - - float clogHeat = 0f; - - @Override - public void write(DataOutputStream stream) throws IOException{ - stream.writeInt(convey.size); - - for(int i = 0; i < convey.size; i ++){ - stream.writeInt(ItemPos.toInt(convey.get(i))); - } - } - - @Override - public void read(DataInputStream stream) throws IOException{ - convey.clear(); - int amount = stream.readInt(); - convey.ensureCapacity(amount); - - for(int i = 0; i < amount; i ++){ - convey.add(ItemPos.toLong(stream.readInt())); - } - } - } - - private static int compareItems(Long a, Long b){ - pos1.set(a, ItemPos.packShorts); - pos2.set(b, ItemPos.packShorts); - return Float.compare(pos1.y, pos2.y); - } - - //Container class. Do not instantiate. - static class ItemPos{ - private static short[] writeShort = new short[4]; - private static byte[] writeByte = new byte[4]; - - private static short[] packShorts = new short[4]; - private static short[] drawShorts = new short[4]; - private static short[] updateShorts = new short[4]; - - Item item; - float x, y; - byte seed; - - private ItemPos(){} - - ItemPos set(long lvalue, short[] values){ - Bits.getShorts(lvalue, values); - - if(values[0] >= Item.all().size || values[0] < 0) - item = null; - else - item = Item.all().get(values[0]); - - x = values[1] / (float)Short.MAX_VALUE; - y = ((float)values[2]) / Short.MAX_VALUE + 1f; - seed = (byte)values[3]; - return this; - } - - long pack(){ - return packItem(item, x, y, seed); - } - - static long packItem(Item item, float x, float y, byte seed){ - short[] shorts = packShorts; - shorts[0] = (short)item.id; - shorts[1] = (short)(x*Short.MAX_VALUE); - shorts[2] = (short)((y - 1f)*Short.MAX_VALUE); - shorts[3] = seed; - return Bits.packLong(shorts); - } - - static int toInt(long value){ - short[] values = Bits.getShorts(value, writeShort); - - short itemid = values[0]; - float x = values[1] / (float)Short.MAX_VALUE; - float y = ((float)values[2]) / Short.MAX_VALUE + 1f; - byte seed = (byte)values[3]; - - byte[] bytes = writeByte; - bytes[0] = (byte)itemid; - bytes[1] = (byte)(x*127); - bytes[2] = (byte)(y*255-128); - bytes[3] = seed; - - return Bits.packInt(bytes); - } - - static long toLong(int value){ - byte[] values = Bits.getBytes(value, writeByte); - - byte itemid = values[0]; - float x = values[1] / 127f; - float y = ((int)values[2] + 128) / 255f; - byte seed = values[3]; - - short[] shorts = writeShort; - shorts[0] = (short)itemid; - shorts[1] = (short)(x*Short.MAX_VALUE); - shorts[2] = (short)((y - 1f)*Short.MAX_VALUE); - shorts[3] = seed; - return Bits.packLong(shorts); - } - } + private static final float itemSpace = 0.135f * 2.2f; + private static final float offsetScl = 128f * 3f; + private static final float minmove = 1f / (Short.MAX_VALUE - 2); + private static ItemPos drawpos = new ItemPos(); + private static ItemPos pos1 = new ItemPos(); + private static ItemPos pos2 = new ItemPos(); + private final Translator tr1 = new Translator(); + private final Translator tr2 = new Translator(); + private final TextureRegion region1 = new TextureRegion(); + private final TextureRegion region2 = new TextureRegion(); + + protected float speed = 0f; + protected float carryCapacity = 8f; + + protected Conveyor(String name){ + super(name); + rotate = true; + update = true; + layer = Layer.overlay; + group = BlockGroup.transportation; + hasItems = true; + autoSleep = true; + itemCapacity = Math.round(tilesize / itemSpace); + } + + private static int compareItems(Long a, Long b){ + pos1.set(a, ItemPos.packShorts); + pos2.set(b, ItemPos.packShorts); + return Float.compare(pos1.y, pos2.y); + } + + @Override + public void setBars(){ + } + + @Override + public void setStats(){ + super.setStats(); + stats.add(BlockStat.itemSpeed, speed * 60, StatUnit.pixelsSecond); + } + + @Override + public void draw(Tile tile){ + ConveyorEntity entity = tile.entity(); + byte rotation = tile.getRotation(); + + GridPoint2 point = Geometry.d4[rotation]; + + int offset = entity.clogHeat <= 0.5f ? (int) ((Timers.time() / 4f) % 8) : 0; + TextureRegion region = Draw.region(name); + + region1.setRegion(region, 0, 0, region.getRegionWidth() - offset, region.getRegionHeight()); + region2.setRegion(region, region.getRegionWidth() - offset, 0, offset, region.getRegionHeight()); + + float x = tile.drawx(), y = tile.drawy(); + + if(offset % 2 == 1){ + if(point.x < 0) x += 0.75f; + if(point.y < 0) + y += 0.5f; + else if(point.y > 0) + y -= 0.5f; + } + + Draw.rect(region1, + x + (point.x * (tilesize / 2f - region1.getRegionWidth() / 2f)), + y + (point.y * (tilesize / 2f - region1.getRegionWidth() / 2f)), rotation * 90); + Draw.rect(region2, + x - (point.x * (tilesize / 2f - region2.getRegionWidth() / 2f)), + y - (point.y * (tilesize / 2f - region2.getRegionWidth() / 2f)), rotation * 90); + } + + @Override + public boolean isLayer(Tile tile){ + return tile.entity().convey.size > 0; + } + + @Override + public void drawLayer(Tile tile){ + ConveyorEntity entity = tile.entity(); + + byte rotation = tile.getRotation(); + + try{ + + for(int i = 0; i < entity.convey.size; i++){ + ItemPos pos = drawpos.set(entity.convey.get(i), ItemPos.drawShorts); + + if(pos.item == null) continue; + + tr1.trns(rotation * 90, tilesize, 0); + tr2.trns(rotation * 90, -tilesize / 2, pos.x * tilesize / 2); + + Draw.rect(pos.item.region, + (int) (tile.x * tilesize + tr1.x * pos.y + tr2.x), + (int) (tile.y * tilesize + tr1.y * pos.y + tr2.y), itemSize, itemSize); + } + + }catch(IndexOutOfBoundsException e){ + Log.err(e); + } + } + + @Override + public void unitOn(Tile tile, Unit unit){ + ConveyorEntity entity = tile.entity(); + + entity.wakeUp(); + + float speed = this.speed * tilesize / 2.3f; + float tx = Geometry.d4[tile.getRotation()].x, ty = Geometry.d4[tile.getRotation()].y; + + float min; + + if(Math.abs(tx) > Math.abs(ty)){ + float rx = tile.worldx() - tx / 2f * tilesize; + min = Mathf.clamp((unit.x - rx) * tx / tilesize); + }else{ + float ry = tile.worldy() - ty / 2f * tilesize; + min = Mathf.clamp((unit.y - ry) * ty / tilesize); + } + + entity.minCarry = Math.min(entity.minCarry, min); + entity.carrying += unit.getMass(); + + if(entity.convey.size * itemSpace < 0.9f){ + unit.getVelocity().add(tx * speed * Timers.delta(), ty * speed * Timers.delta()); + } + } + + @Override + public synchronized void update(Tile tile){ + + ConveyorEntity entity = tile.entity(); + entity.minitem = 1f; + + int minremove = Integer.MAX_VALUE; + float speed = Math.max(this.speed - (1f - (carryCapacity - entity.carrying) / carryCapacity), 0f); + float totalMoved = 0f; + + for(int i = entity.convey.size - 1; i >= 0; i--){ + long value = entity.convey.get(i); + ItemPos pos = pos1.set(value, ItemPos.updateShorts); + + //..this should never happen, but in case it does, remove it and stop here + if(pos.item == null){ + entity.convey.removeValue(value); + break; + } + + float nextpos = (i == entity.convey.size - 1 ? 100f : pos2.set(entity.convey.get(i + 1), ItemPos.updateShorts).y) - itemSpace; + if(entity.minCarry >= pos.y && entity.minCarry <= nextpos){ + nextpos = entity.minCarry; + } + float maxmove = Math.min(nextpos - pos.y, speed * Timers.delta()); + + if(maxmove > minmove){ + pos.y += maxmove; + pos.x = Mathf.lerpDelta(pos.x, 0, 0.06f); + totalMoved += maxmove; + }else{ + pos.x = Mathf.lerpDelta(pos.x, pos.seed / offsetScl, 0.1f); + } + + pos.y = Mathf.clamp(pos.y); + + if(pos.y >= 0.9999f && offloadDir(tile, pos.item)){ + minremove = Math.min(i, minremove); + totalMoved = 1f; + tile.entity.items.remove(pos.item, 1); + }else{ + value = pos.pack(); + + if(pos.y < entity.minitem) + entity.minitem = pos.y; + entity.convey.set(i, value); + } + } + + if(entity.minitem < itemSpace){ + entity.clogHeat = Mathf.lerpDelta(entity.clogHeat, 1f, 0.02f); + }else{ + entity.clogHeat = Mathf.lerpDelta(entity.clogHeat, 0f, 1f); + } + + entity.carrying = 0f; + entity.minCarry = 2f; + + if(totalMoved <= 0.0001f){ + entity.sleep(); + } + + if(minremove != Integer.MAX_VALUE) entity.convey.truncate(minremove); + } + + @Override + public boolean isAccessible(){ + return true; + } + + @Override + public synchronized int removeStack(Tile tile, Item item, int amount){ + ConveyorEntity entity = tile.entity(); + entity.wakeUp(); + int removed = 0; + + for(int j = 0; j < amount; j++){ + for(int i = 0; i < entity.convey.size; i++){ + long val = entity.convey.get(i); + ItemPos pos = pos1.set(val, ItemPos.drawShorts); + if(pos.item == item){ + entity.convey.removeValue(val); + entity.items.remove(item, 1); + removed++; + break; + } + } + } + return removed; + } + + @Override + public void getStackOffset(Item item, Tile tile, Translator trns){ + trns.trns(tile.getRotation() * 90 + 180f, tilesize / 2f); + } + + @Override + public synchronized int acceptStack(Item item, int amount, Tile tile, Unit source){ + ConveyorEntity entity = tile.entity(); + return entity.minitem > itemSpace ? 1 : 0; + } + + @Override + public synchronized void handleStack(Item item, int amount, Tile tile, Unit source){ + ConveyorEntity entity = tile.entity(); + + long result = ItemPos.packItem(item, 0f, 0f, (byte) Mathf.random(255)); + entity.convey.insert(0, result); + entity.items.add(item, 1); + entity.wakeUp(); + } + + @Override + public boolean acceptItem(Item item, Tile tile, Tile source){ + int direction = source == null ? 0 : Math.abs(source.relativeTo(tile.x, tile.y) - tile.getRotation()); + float minitem = tile.entity().minitem; + return (((direction == 0) && minitem > itemSpace) || + ((direction % 2 == 1) && minitem > 0.52f)) && (source == null || !(source.block().rotate && (source.getRotation() + 2) % 4 == tile.getRotation())); + } + + @Override + public void handleItem(Item item, Tile tile, Tile source){ + byte rotation = tile.getRotation(); + + int ch = Math.abs(source.relativeTo(tile.x, tile.y) - rotation); + int ang = ((source.relativeTo(tile.x, tile.y) - rotation)); + + float pos = ch == 0 ? 0 : ch % 2 == 1 ? 0.5f : 1f; + float y = (ang == -1 || ang == 3) ? 1 : (ang == 1 || ang == -3) ? -1 : 0; + + ConveyorEntity entity = tile.entity(); + entity.wakeUp(); + long result = ItemPos.packItem(item, y * 0.9f, pos, (byte) Mathf.random(255)); + boolean inserted = false; + + tile.entity.items.add(item, 1); + + for(int i = 0; i < entity.convey.size; i++){ + if(compareItems(result, entity.convey.get(i)) < 0){ + entity.convey.insert(i, result); + inserted = true; + break; + } + } + + //this item must be greater than anything there... + if(!inserted){ + entity.convey.add(result); + } + } + + @Override + public Array getDebugInfo(Tile tile){ + ConveyorEntity entity = tile.entity(); + Array arr = super.getDebugInfo(tile); + arr.addAll(Array.with( + "mincarry", entity.minCarry, + "minitem", entity.minCarry, + "carrying", entity.carrying, + "clogHeat", entity.clogHeat, + "sleeping", entity.isSleeping() + )); + return arr; + } + + @Override + public TileEntity getEntity(){ + return new ConveyorEntity(); + } + + public static class ConveyorEntity extends TileEntity{ + + LongArray convey = new LongArray(); + float minitem = 1; + float carrying; + float minCarry = 2f; + + float clogHeat = 0f; + + @Override + public void write(DataOutputStream stream) throws IOException{ + stream.writeInt(convey.size); + + for(int i = 0; i < convey.size; i++){ + stream.writeInt(ItemPos.toInt(convey.get(i))); + } + } + + @Override + public void read(DataInputStream stream) throws IOException{ + convey.clear(); + int amount = stream.readInt(); + convey.ensureCapacity(amount); + + for(int i = 0; i < amount; i++){ + convey.add(ItemPos.toLong(stream.readInt())); + } + } + } + + //Container class. Do not instantiate. + static class ItemPos{ + private static short[] writeShort = new short[4]; + private static byte[] writeByte = new byte[4]; + + private static short[] packShorts = new short[4]; + private static short[] drawShorts = new short[4]; + private static short[] updateShorts = new short[4]; + + Item item; + float x, y; + byte seed; + + private ItemPos(){ + } + + static long packItem(Item item, float x, float y, byte seed){ + short[] shorts = packShorts; + shorts[0] = (short) item.id; + shorts[1] = (short) (x * Short.MAX_VALUE); + shorts[2] = (short) ((y - 1f) * Short.MAX_VALUE); + shorts[3] = seed; + return Bits.packLong(shorts); + } + + static int toInt(long value){ + short[] values = Bits.getShorts(value, writeShort); + + short itemid = values[0]; + float x = values[1] / (float) Short.MAX_VALUE; + float y = ((float) values[2]) / Short.MAX_VALUE + 1f; + byte seed = (byte) values[3]; + + byte[] bytes = writeByte; + bytes[0] = (byte) itemid; + bytes[1] = (byte) (x * 127); + bytes[2] = (byte) (y * 255 - 128); + bytes[3] = seed; + + return Bits.packInt(bytes); + } + + static long toLong(int value){ + byte[] values = Bits.getBytes(value, writeByte); + + byte itemid = values[0]; + float x = values[1] / 127f; + float y = ((int) values[2] + 128) / 255f; + byte seed = values[3]; + + short[] shorts = writeShort; + shorts[0] = (short) itemid; + shorts[1] = (short) (x * Short.MAX_VALUE); + shorts[2] = (short) ((y - 1f) * Short.MAX_VALUE); + shorts[3] = seed; + return Bits.packLong(shorts); + } + + ItemPos set(long lvalue, short[] values){ + Bits.getShorts(lvalue, values); + + if(values[0] >= Item.all().size || values[0] < 0) + item = null; + else + item = Item.all().get(values[0]); + + x = values[1] / (float) Short.MAX_VALUE; + y = ((float) values[2]) / Short.MAX_VALUE + 1f; + seed = (byte) values[3]; + return this; + } + + long pack(){ + return packItem(item, x, y, seed); + } + } } \ No newline at end of file diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/ExtendingItemBridge.java b/core/src/io/anuke/mindustry/world/blocks/distribution/ExtendingItemBridge.java index 4c7309859d..a072628481 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/ExtendingItemBridge.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/ExtendingItemBridge.java @@ -10,15 +10,15 @@ import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.tilesize; import static io.anuke.mindustry.Vars.world; -public class ExtendingItemBridge extends ItemBridge { +public class ExtendingItemBridge extends ItemBridge{ - public ExtendingItemBridge(String name) { + public ExtendingItemBridge(String name){ super(name); hasItems = true; } @Override - public void drawLayer(Tile tile) { + public void drawLayer(Tile tile){ ItemBridgeEntity entity = tile.entity(); Tile other = world.tile(entity.link); @@ -26,36 +26,36 @@ public class ExtendingItemBridge extends ItemBridge { int i = tile.absoluteRelativeTo(other.x, other.y); - float ex = other.worldx() - tile.worldx() - Geometry.d4[i].x*tilesize/2f, - ey = other.worldy() - tile.worldy() - Geometry.d4[i].y*tilesize/2f; + float ex = other.worldx() - tile.worldx() - Geometry.d4[i].x * tilesize / 2f, + ey = other.worldy() - tile.worldy() - Geometry.d4[i].y * tilesize / 2f; ex *= entity.uptime; ey *= entity.uptime; Lines.stroke(8f); Lines.line(bridgeRegion, - tile.worldx() + Geometry.d4[i].x*tilesize/2f, - tile.worldy() + Geometry.d4[i].y*tilesize/2f, + tile.worldx() + Geometry.d4[i].x * tilesize / 2f, + tile.worldy() + Geometry.d4[i].y * tilesize / 2f, tile.worldx() + ex, tile.worldy() + ey, CapStyle.none, 0f); - Draw.rect(endRegion, tile.drawx(), tile.drawy(), i*90 + 90); + Draw.rect(endRegion, tile.drawx(), tile.drawy(), i * 90 + 90); Draw.rect(endRegion, - tile.worldx() + ex + Geometry.d4[i].x*tilesize/2f, - tile.worldy() + ey + Geometry.d4[i].y*tilesize/2f, i*90 + 270); + tile.worldx() + ex + Geometry.d4[i].x * tilesize / 2f, + tile.worldy() + ey + Geometry.d4[i].y * tilesize / 2f, i * 90 + 270); int dist = Math.max(Math.abs(other.x - tile.x), Math.abs(other.y - tile.y)); - int arrows = (dist)*tilesize/6-1; + int arrows = (dist) * tilesize / 6 - 1; Draw.color(); - for(int a = 0; a < arrows; a ++){ - Draw.alpha(Mathf.absin(a/(float)arrows - entity.time/100f, 0.1f, 1f) * entity.uptime); + for(int a = 0; a < arrows; a++){ + Draw.alpha(Mathf.absin(a / (float) arrows - entity.time / 100f, 0.1f, 1f) * entity.uptime); Draw.rect(arrowRegion, - tile.worldx() + Geometry.d4[i].x*(tilesize/2f + a*6f + 2) * entity.uptime, - tile.worldy() + Geometry.d4[i].y*(tilesize/2f + a*6f + 2) * entity.uptime, - i*90f); + tile.worldx() + Geometry.d4[i].x * (tilesize / 2f + a * 6f + 2) * entity.uptime, + tile.worldy() + Geometry.d4[i].y * (tilesize / 2f + a * 6f + 2) * entity.uptime, + i * 90f); } Draw.reset(); } diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java b/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java index 089e01ced8..f162f1a530 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java @@ -30,7 +30,7 @@ import java.io.IOException; import static io.anuke.mindustry.Vars.tilesize; import static io.anuke.mindustry.Vars.world; -public class ItemBridge extends Block { +public class ItemBridge extends Block{ protected static int lastPlaced; protected int timerTransport = timers++; @@ -40,7 +40,7 @@ public class ItemBridge extends Block { protected TextureRegion endRegion, bridgeRegion, arrowRegion; - public ItemBridge(String name) { + public ItemBridge(String name){ super(name); update = true; solid = true; @@ -52,8 +52,26 @@ public class ItemBridge extends Block { hasItems = true; } + @Remote(targets = Loc.both, called = Loc.both, in = In.blocks, forward = true) + public static void linkItemBridge(Player player, Tile tile, Tile other){ + ItemBridgeEntity entity = tile.entity(); + ItemBridgeEntity oe = other.entity(); + entity.link = other.packedPosition(); + oe.incoming.add(tile.packedPosition()); + } + + @Remote(targets = Loc.both, called = Loc.server, in = In.blocks, forward = true) + public static void unlinkItemBridge(Player player, Tile tile, Tile other){ + ItemBridgeEntity entity = tile.entity(); + entity.link = -1; + if(other != null){ + ItemBridgeEntity oe = other.entity(); + oe.incoming.remove(tile.packedPosition()); + } + } + @Override - public void load() { + public void load(){ super.load(); endRegion = Draw.region(name + "-end"); @@ -62,7 +80,7 @@ public class ItemBridge extends Block { } @Override - public void placed(Tile tile) { + public void placed(Tile tile){ Tile last = world.tile(lastPlaced); if(linkValid(tile, last)){ ItemBridgeEntity entity = last.entity(); @@ -74,13 +92,13 @@ public class ItemBridge extends Block { } @Override - public void drawPlace(int x, int y, int rotation, boolean valid) { + public void drawPlace(int x, int y, int rotation, boolean valid){ Lines.stroke(2f); Draw.color(Palette.placing); - for(int i = 0; i < 4; i ++){ + for(int i = 0; i < 4; i++){ Lines.dashLine( - x * tilesize + Geometry.d4[i].x * (tilesize/2f + 2), - y * tilesize + Geometry.d4[i].y * (tilesize/2f + 2), + x * tilesize + Geometry.d4[i].x * (tilesize / 2f + 2), + y * tilesize + Geometry.d4[i].y * (tilesize / 2f + 2), x * tilesize + Geometry.d4[i].x * range * tilesize, y * tilesize + Geometry.d4[i].y * range * tilesize, range); @@ -98,8 +116,8 @@ public class ItemBridge extends Block { Lines.square(tile.drawx(), tile.drawy(), tile.block().size * tilesize / 2f + 1f); - for(int i = 1; i <= range; i ++){ - for(int j = 0; j < 4; j ++){ + for(int i = 1; i <= range; i++){ + for(int j = 0; j < 4; j++){ Tile other = tile.getNearby(Geometry.d4[j].x * i, Geometry.d4[j].y * i); if(linkValid(tile, other)){ boolean linked = other.packedPosition() == entity.link; @@ -115,7 +133,7 @@ public class ItemBridge extends Block { } @Override - public boolean onConfigureTileTapped(Tile tile, Tile other) { + public boolean onConfigureTileTapped(Tile tile, Tile other){ ItemBridgeEntity entity = tile.entity(); if(linkValid(tile, other)){ @@ -130,11 +148,11 @@ public class ItemBridge extends Block { } @Override - public void update(Tile tile) { + public void update(Tile tile){ ItemBridgeEntity entity = tile.entity(); - entity.time += entity.cycleSpeed*Timers.delta(); - entity.time2 += (entity.cycleSpeed-1f)*Timers.delta(); + entity.time += entity.cycleSpeed * Timers.delta(); + entity.time2 += (entity.cycleSpeed - 1f) * Timers.delta(); removals.clear(); @@ -148,7 +166,7 @@ public class ItemBridge extends Block { } } - for(int j = 0; j < removals.size; j ++) + for(int j = 0; j < removals.size; j++) entity.incoming.remove(removals.get(j)); Tile other = world.tile(entity.link); @@ -183,7 +201,7 @@ public class ItemBridge extends Block { } @Override - public void drawLayer(Tile tile) { + public void drawLayer(Tile tile){ ItemBridgeEntity entity = tile.entity(); Tile other = world.tile(entity.link); @@ -194,35 +212,35 @@ public class ItemBridge extends Block { Draw.color(Color.WHITE, Color.BLACK, Mathf.absin(Timers.time(), 6f, 0.07f)); Draw.alpha(Math.max(entity.uptime, 0.25f)); - Draw.rect(endRegion, tile.drawx(), tile.drawy(), i*90 + 90); - Draw.rect(endRegion, other.drawx(), other.drawy(), i*90 + 270); + Draw.rect(endRegion, tile.drawx(), tile.drawy(), i * 90 + 90); + Draw.rect(endRegion, other.drawx(), other.drawy(), i * 90 + 270); Lines.stroke(8f); Lines.line(bridgeRegion, tile.worldx(), tile.worldy(), other.worldx(), - other.worldy(), CapStyle.none, -tilesize/2f); + other.worldy(), CapStyle.none, -tilesize / 2f); int dist = Math.max(Math.abs(other.x - tile.x), Math.abs(other.y - tile.y)); - float time = entity.time2/1.7f; - int arrows = (dist)*tilesize/4-2; + float time = entity.time2 / 1.7f; + int arrows = (dist) * tilesize / 4 - 2; Draw.color(); - for(int a = 0; a < arrows; a ++){ - Draw.alpha(Mathf.absin(a/(float)arrows - entity.time/100f, 0.1f, 1f) * entity.uptime); + for(int a = 0; a < arrows; a++){ + Draw.alpha(Mathf.absin(a / (float) arrows - entity.time / 100f, 0.1f, 1f) * entity.uptime); Draw.rect(arrowRegion, - tile.worldx() + Geometry.d4[i].x*(tilesize/2f + a*4f + time % 4f), - tile.worldy() + Geometry.d4[i].y*(tilesize/2f + a*4f + time % 4f), - i*90f); + tile.worldx() + Geometry.d4[i].x * (tilesize / 2f + a * 4f + time % 4f), + tile.worldy() + Geometry.d4[i].y * (tilesize / 2f + a * 4f + time % 4f), + i * 90f); } Draw.reset(); } @Override - public boolean acceptItem(Item item, Tile tile, Tile source) { + public boolean acceptItem(Item item, Tile tile, Tile source){ ItemBridgeEntity entity = tile.entity(); Tile other = world.tile(entity.link); @@ -250,7 +268,7 @@ public class ItemBridge extends Block { } @Override - public boolean canDump(Tile tile, Tile to, Item item) { + public boolean canDump(Tile tile, Tile to, Item item){ ItemBridgeEntity entity = tile.entity(); Tile other = world.tile(entity.link); @@ -277,7 +295,7 @@ public class ItemBridge extends Block { } @Override - public TileEntity getEntity() { + public TileEntity getEntity(){ return new ItemBridgeEntity(); } @@ -298,24 +316,6 @@ public class ItemBridge extends Block { return other.block() == this && (!checkDouble || other.entity().link != tile.packedPosition()); } - @Remote(targets = Loc.both, called = Loc.both, in = In.blocks, forward = true) - public static void linkItemBridge(Player player, Tile tile, Tile other){ - ItemBridgeEntity entity = tile.entity(); - ItemBridgeEntity oe = other.entity(); - entity.link = other.packedPosition(); - oe.incoming.add(tile.packedPosition()); - } - - @Remote(targets = Loc.both, called = Loc.server, in = In.blocks, forward = true) - public static void unlinkItemBridge(Player player, Tile tile, Tile other){ - ItemBridgeEntity entity = tile.entity(); - entity.link = -1; - if(other != null) { - ItemBridgeEntity oe = other.entity(); - oe.incoming.remove(tile.packedPosition()); - } - } - public static class ItemBridgeEntity extends TileEntity{ public int link = -1; public IntSet incoming = new IntSet(); @@ -325,7 +325,7 @@ public class ItemBridge extends Block { public float cycleSpeed = 1f; @Override - public void write(DataOutputStream stream) throws IOException { + public void write(DataOutputStream stream) throws IOException{ stream.writeInt(link); stream.writeFloat(uptime); stream.writeByte(incoming.size); @@ -338,11 +338,11 @@ public class ItemBridge extends Block { } @Override - public void read(DataInputStream stream) throws IOException { + public void read(DataInputStream stream) throws IOException{ link = stream.readInt(); uptime = stream.readFloat(); byte links = stream.readByte(); - for(int i = 0; i < links; i ++){ + for(int i = 0; i < links; i++){ incoming.add(stream.readInt()); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/Junction.java b/core/src/io/anuke/mindustry/world/blocks/distribution/Junction.java index d8aa792fe4..f3267a1cf1 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/Junction.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/Junction.java @@ -5,97 +5,98 @@ import com.badlogic.gdx.utils.NumberUtils; import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.Block; -import io.anuke.mindustry.world.meta.BlockGroup; import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.meta.BlockGroup; import io.anuke.ucore.core.Timers; import io.anuke.ucore.function.Consumer; import io.anuke.ucore.util.Bits; public class Junction extends Block{ - protected float speed = 26; //frames taken to go through this junction - protected int capacity = 32; + protected float speed = 26; //frames taken to go through this junction + protected int capacity = 32; - public Junction(String name) { - super(name); - update = true; - solid = true; - instantTransfer = true; - group = BlockGroup.transportation; - } + public Junction(String name){ + super(name); + update = true; + solid = true; + instantTransfer = true; + group = BlockGroup.transportation; + } - @Override - public void update(Tile tile){ - JunctionEntity entity = tile.entity(); + @Override + public void update(Tile tile){ + JunctionEntity entity = tile.entity(); - for(int i = 0; i < 2; i ++){ - Buffer buffer = (i == 0 ? entity.bx : entity.by); + for(int i = 0; i < 2; i++){ + Buffer buffer = (i == 0 ? entity.bx : entity.by); - if(buffer.index > 0){ - if(buffer.index > buffer.items.length) buffer.index = buffer.items.length; - long l = buffer.items[0]; - float time = NumberUtils.intBitsToFloat(Bits.getLeftInt(l)); + if(buffer.index > 0){ + if(buffer.index > buffer.items.length) buffer.index = buffer.items.length; + long l = buffer.items[0]; + float time = NumberUtils.intBitsToFloat(Bits.getLeftInt(l)); - if(Timers.time() >= time + speed || Timers.time() < time){ + if(Timers.time() >= time + speed || Timers.time() < time){ - int val = Bits.getRightInt(l); + int val = Bits.getRightInt(l); - Item item = Item.getByID(Bits.getLeftShort(val)); - int direction = Bits.getRightShort(val); - Tile dest = tile.getNearby(direction); + Item item = Item.getByID(Bits.getLeftShort(val)); + int direction = Bits.getRightShort(val); + Tile dest = tile.getNearby(direction); - if(dest == null || !dest.block().acceptItem(item, dest, tile)){ - if(buffer.index > 1 && Bits.getRightShort(Bits.getRightInt(buffer.items[1])) != direction){ - System.arraycopy(buffer.items, 1, buffer.items, 0, buffer.index - 1); - buffer.index --; - } - continue; - } + if(dest == null || !dest.block().acceptItem(item, dest, tile)){ + if(buffer.index > 1 && Bits.getRightShort(Bits.getRightInt(buffer.items[1])) != direction){ + System.arraycopy(buffer.items, 1, buffer.items, 0, buffer.index - 1); + buffer.index--; + } + continue; + } - dest.block().handleItem(item, dest, tile); - System.arraycopy(buffer.items, 1, buffer.items, 0, buffer.index - 1); - buffer.index --; - } - } - } - } + dest.block().handleItem(item, dest, tile); + System.arraycopy(buffer.items, 1, buffer.items, 0, buffer.index - 1); + buffer.index--; + } + } + } + } - @Override - public void handleItem(Item item, Tile tile, Tile source){ - JunctionEntity entity = tile.entity(); - boolean x = tile.x == source.x; - long value = Bits.packLong(NumberUtils.floatToIntBits(Timers.time()), Bits.packInt((short)item.id, source.relativeTo(tile.x, tile.y))); - if(x){ - entity.bx.add(value); - }else { - entity.by.add(value); - } - } + @Override + public void handleItem(Item item, Tile tile, Tile source){ + JunctionEntity entity = tile.entity(); + boolean x = tile.x == source.x; + long value = Bits.packLong(NumberUtils.floatToIntBits(Timers.time()), Bits.packInt((short) item.id, source.relativeTo(tile.x, tile.y))); + if(x){ + entity.bx.add(value); + }else{ + entity.by.add(value); + } + } - @Override - public boolean acceptItem(Item item, Tile tile, Tile source){ - JunctionEntity entity = tile.entity(); - boolean x = tile.x == source.x; + @Override + public boolean acceptItem(Item item, Tile tile, Tile source){ + JunctionEntity entity = tile.entity(); + boolean x = tile.x == source.x; - if(entity == null || entity.bx == null || entity.by == null || (x && entity.bx.full()) || (!x && entity.by.full())) return false; - int dir = source.relativeTo(tile.x, tile.y); - if(dir == -1) return false; - Tile to = tile.getNearby(dir); - return to != null && to.block().acceptItem(item, to, tile); - } + if(entity == null || entity.bx == null || entity.by == null || (x && entity.bx.full()) || (!x && entity.by.full())) + return false; + int dir = source.relativeTo(tile.x, tile.y); + if(dir == -1) return false; + Tile to = tile.getNearby(dir); + return to != null && to.block().acceptItem(item, to, tile); + } - @Override - public TileEntity getEntity() { - return new JunctionEntity(); - } + @Override + public TileEntity getEntity(){ + return new JunctionEntity(); + } - @Override - public Array getDebugInfo(Tile tile){ - JunctionEntity entity = tile.entity(); - Array arr = super.getDebugInfo(tile); - for(int i = 0; i < 4; i ++){ - arr.add("nearby." + i); - arr.add(tile.getNearby(i)); - } + @Override + public Array getDebugInfo(Tile tile){ + JunctionEntity entity = tile.entity(); + Array arr = super.getDebugInfo(tile); + for(int i = 0; i < 4; i++){ + arr.add("nearby." + i); + arr.add(tile.getNearby(i)); + } Consumer write = b -> { for(int i = 0; i < b.index; i++){ @@ -110,32 +111,32 @@ public class Junction extends Block{ } }; - arr.add("buffer.bx"); - arr.add(entity.bx.index); - write.accept(entity.bx); + arr.add("buffer.bx"); + arr.add(entity.bx.index); + write.accept(entity.bx); arr.add("buffer.by"); arr.add(entity.bx.index); - write.accept(entity.by); + write.accept(entity.by); - return arr; - } + return arr; + } - class JunctionEntity extends TileEntity{ - Buffer bx = new Buffer(); - Buffer by = new Buffer(); - } + class JunctionEntity extends TileEntity{ + Buffer bx = new Buffer(); + Buffer by = new Buffer(); + } - class Buffer{ - long[] items = new long[capacity]; - int index; + class Buffer{ + long[] items = new long[capacity]; + int index; - void add(long id){ - if(full()) return; - items[index++] = id; - } + void add(long id){ + if(full()) return; + items[index++] = id; + } - boolean full(){ - return index >= items.length - 1; - } - } + boolean full(){ + return index >= items.length - 1; + } + } } diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidBridge.java b/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidBridge.java index 8562b0735c..383a86cf03 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidBridge.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidBridge.java @@ -7,9 +7,9 @@ import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.world; -public class LiquidBridge extends ItemBridge { +public class LiquidBridge extends ItemBridge{ - public LiquidBridge(String name) { + public LiquidBridge(String name){ super(name); hasItems = false; hasLiquids = true; @@ -17,11 +17,11 @@ public class LiquidBridge extends ItemBridge { } @Override - public void update(Tile tile) { + public void update(Tile tile){ ItemBridgeEntity entity = tile.entity(); - entity.time += entity.cycleSpeed* Timers.delta(); - entity.time2 += (entity.cycleSpeed-1f)*Timers.delta(); + entity.time += entity.cycleSpeed * Timers.delta(); + entity.time2 += (entity.cycleSpeed - 1f) * Timers.delta(); Tile other = world.tile(entity.link); if(!linkValid(tile, other)){ @@ -46,7 +46,7 @@ public class LiquidBridge extends ItemBridge { } @Override - public boolean acceptItem(Item item, Tile tile, Tile source) { + public boolean acceptItem(Item item, Tile tile, Tile source){ return false; } } diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidExtendingBridge.java b/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidExtendingBridge.java index 5076806347..7be3b85cc5 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidExtendingBridge.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidExtendingBridge.java @@ -7,9 +7,9 @@ import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.world; -public class LiquidExtendingBridge extends ExtendingItemBridge { +public class LiquidExtendingBridge extends ExtendingItemBridge{ - public LiquidExtendingBridge(String name) { + public LiquidExtendingBridge(String name){ super(name); hasItems = false; hasLiquids = true; @@ -17,11 +17,11 @@ public class LiquidExtendingBridge extends ExtendingItemBridge { } @Override - public void update(Tile tile) { + public void update(Tile tile){ ItemBridgeEntity entity = tile.entity(); - entity.time += entity.cycleSpeed* Timers.delta(); - entity.time2 += (entity.cycleSpeed-1f)*Timers.delta(); + entity.time += entity.cycleSpeed * Timers.delta(); + entity.time2 += (entity.cycleSpeed - 1f) * Timers.delta(); Tile other = world.tile(entity.link); if(!linkValid(tile, other)){ @@ -45,7 +45,7 @@ public class LiquidExtendingBridge extends ExtendingItemBridge { } @Override - public boolean acceptItem(Item item, Tile tile, Tile source) { + public boolean acceptItem(Item item, Tile tile, Tile source){ return false; } } diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidJunction.java b/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidJunction.java index 3f99bce32b..4bb6bc1d39 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidJunction.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidJunction.java @@ -9,37 +9,37 @@ import io.anuke.ucore.graphics.Draw; //TODO fix public class LiquidJunction extends LiquidBlock{ - public LiquidJunction(String name) { - super(name); - hasLiquids = true; - } - - @Override - public void draw(Tile tile){ - Draw.rect(name(), tile.worldx(), tile.worldy()); - } + public LiquidJunction(String name){ + super(name); + hasLiquids = true; + } - @Override - public TextureRegion[] getIcon(){ - return new TextureRegion[]{Draw.region(name)}; - } + @Override + public void draw(Tile tile){ + Draw.rect(name(), tile.worldx(), tile.worldy()); + } - @Override - public void handleLiquid(Tile tile, Tile source, Liquid liquid, float amount){ - int dir = source.relativeTo(tile.x, tile.y); - dir = (dir+4)%4; - Tile to = tile.getNearby(dir); + @Override + public TextureRegion[] getIcon(){ + return new TextureRegion[]{Draw.region(name)}; + } + + @Override + public void handleLiquid(Tile tile, Tile source, Liquid liquid, float amount){ + int dir = source.relativeTo(tile.x, tile.y); + dir = (dir + 4) % 4; + Tile to = tile.getNearby(dir); if(to.block().hasLiquids && to.block().acceptLiquid(to, tile, liquid, amount)) to.block().handleLiquid(to, tile, liquid, amount); - } + } - @Override - public boolean acceptLiquid(Tile dest, Tile source, Liquid liquid, float amount){ - int dir = source.relativeTo(dest.x, dest.y); - dir = (dir+4)%4; - Tile to = dest.getNearby(dir); - return to != null && to.block().hasLiquids && - to.block().acceptLiquid(to, dest, liquid, amount); - } + @Override + public boolean acceptLiquid(Tile dest, Tile source, Liquid liquid, float amount){ + int dir = source.relativeTo(dest.x, dest.y); + dir = (dir + 4) % 4; + Tile to = dest.getNearby(dir); + return to != null && to.block().hasLiquids && + to.block().acceptLiquid(to, dest, liquid, amount); + } } diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidRouter.java b/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidRouter.java index 8083564e7c..4ca44a549c 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidRouter.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidRouter.java @@ -5,16 +5,16 @@ import io.anuke.mindustry.world.blocks.LiquidBlock; public class LiquidRouter extends LiquidBlock{ - public LiquidRouter(String name) { - super(name); - } - - @Override - public void update(Tile tile){ - - if(tile.entity.liquids.total() > 0.01f){ - tryDumpLiquid(tile, tile.entity.liquids.current()); - } - } + public LiquidRouter(String name){ + super(name); + } + + @Override + public void update(Tile tile){ + + if(tile.entity.liquids.total() > 0.01f){ + tryDumpLiquid(tile, tile.entity.liquids.current()); + } + } } diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java b/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java index c7703e8f69..ac20aefb83 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java @@ -33,7 +33,7 @@ import java.io.IOException; import static io.anuke.mindustry.Vars.*; -public class MassDriver extends Block { +public class MassDriver extends Block{ protected float range; protected float rotateSpeed = 0.04f; protected float translation = 7f; @@ -45,7 +45,7 @@ public class MassDriver extends Block { protected Effect recieveEffect = BlockFx.smeltsmoke; protected float shake = 3f; - public MassDriver(String name) { + public MassDriver(String name){ super(name); update = true; solid = true; @@ -56,8 +56,52 @@ public class MassDriver extends Block { hasPower = true; } + @Remote(targets = Loc.both, called = Loc.server, in = In.blocks, forward = true) + public static void linkMassDriver(Player player, Tile tile, int position){ + MassDriverEntity entity = tile.entity(); + + //called in main thread to prevent issues + threads.run(() -> entity.link = position); + } + + @Remote(called = Loc.server, in = In.blocks) + public static void onMassDriverFire(Tile tile, Tile target){ + //just in case the client has invalid data + if(!(tile.entity instanceof MassDriverEntity) || !(target.entity instanceof MassDriverEntity)) return; + + MassDriver driver = (MassDriver) tile.block(); + + MassDriverEntity entity = tile.entity(); + MassDriverEntity other = target.entity(); + + entity.reload = 1f; + + DriverBulletData data = Pooling.obtain(DriverBulletData.class); + data.from = entity; + data.to = other; + for(int i = 0; i < Item.all().size; i++){ + data.items[i] = entity.items.get(Item.getByID(i)); + } + entity.items.clear(); + + float angle = tile.angleTo(target); + + other.isRecieving = true; + Bullet.create(TurretBullets.driverBolt, entity, entity.getTeam(), + tile.drawx() + Angles.trnsx(angle, driver.translation), tile.drawy() + Angles.trnsy(angle, driver.translation), + angle, 1f, data); + + Effects.effect(driver.shootEffect, tile.drawx() + Angles.trnsx(angle, driver.translation), + tile.drawy() + Angles.trnsy(angle, driver.translation), angle); + + Effects.effect(driver.smokeEffect, tile.drawx() + Angles.trnsx(angle, driver.translation), + tile.drawy() + Angles.trnsy(angle, driver.translation), angle); + + Effects.shake(driver.shake, driver.shake, entity); + } + @Override - public void update(Tile tile) { + public void update(Tile tile){ MassDriverEntity entity = tile.entity(); Tile link = world.tile(entity.link); @@ -70,19 +114,19 @@ public class MassDriver extends Block { } if(entity.reload > 0f){ - entity.reload = Mathf.clamp(entity.reload - Timers.delta()/reloadTime); + entity.reload = Mathf.clamp(entity.reload - Timers.delta() / reloadTime); } - if(!entity.isRecieving) { + if(!entity.isRecieving){ - if (entity.waiting.size > 0) { //accepting takes priority over shooting + if(entity.waiting.size > 0){ //accepting takes priority over shooting Tile waiter = entity.waiting.first(); entity.rotation = Mathf.slerpDelta(entity.rotation, tile.angleTo(waiter), rotateSpeed); - }else if (tile.entity.items.total() >= minDistribute && - linkValid(tile) && //only fire when at least at half-capacity and power - tile.entity.power.amount >= powerCapacity && - link.block().itemCapacity - link.entity.items.total() >= minDistribute && entity.reload <= 0.0001f) { + }else if(tile.entity.items.total() >= minDistribute && + linkValid(tile) && //only fire when at least at half-capacity and power + tile.entity.power.amount >= powerCapacity && + link.block().itemCapacity - link.entity.items.total() >= minDistribute && entity.reload <= 0.0001f){ MassDriverEntity other = link.entity(); other.waiting.add(tile); @@ -91,8 +135,8 @@ public class MassDriver extends Block { entity.rotation = Mathf.slerpDelta(entity.rotation, target, rotateSpeed); - if (Mathf.angNear(entity.rotation, target, 1f) && - Mathf.angNear(other.rotation, target + 180f, 1f)) { + if(Mathf.angNear(entity.rotation, target, 1f) && + Mathf.angNear(other.rotation, target + 180f, 1f)){ CallBlocks.onMassDriverFire(tile, link); } } @@ -102,7 +146,7 @@ public class MassDriver extends Block { } @Override - public void drawLayer(Tile tile) { + public void drawLayer(Tile tile){ MassDriverEntity entity = tile.entity(); Draw.rect(name + "-turret", @@ -112,7 +156,7 @@ public class MassDriver extends Block { } @Override - public void drawConfigure(Tile tile) { + public void drawConfigure(Tile tile){ super.drawConfigure(tile); MassDriverEntity entity = tile.entity(); @@ -137,7 +181,7 @@ public class MassDriver extends Block { MassDriverEntity entity = tile.entity(); - if(entity.link == other.packedPosition()) { + if(entity.link == other.packedPosition()){ CallBlocks.linkMassDriver(null, tile, -1); return false; }else if(other.block() instanceof MassDriver && other.distanceTo(tile) <= range){ @@ -149,12 +193,12 @@ public class MassDriver extends Block { } @Override - public boolean acceptItem(Item item, Tile tile, Tile source) { + public boolean acceptItem(Item item, Tile tile, Tile source){ return tile.entity.items.total() < itemCapacity; } @Override - public TileEntity getEntity() { + public TileEntity getEntity(){ return new MassDriverEntity(); } @@ -166,48 +210,16 @@ public class MassDriver extends Block { return link != null && link.block() instanceof MassDriver && tile.distanceTo(link) <= range; } - @Remote(targets = Loc.both, called = Loc.server, in = In.blocks, forward = true) - public static void linkMassDriver(Player player, Tile tile, int position){ - MassDriverEntity entity = tile.entity(); + public static class DriverBulletData implements Poolable{ + public MassDriverEntity from, to; + public int[] items = new int[Item.all().size]; - //called in main thread to prevent issues - threads.run(() -> entity.link = position); - } - - @Remote(called = Loc.server, in = In.blocks) - public static void onMassDriverFire(Tile tile, Tile target){ - //just in case the client has invalid data - if(!(tile.entity instanceof MassDriverEntity) || !(target.entity instanceof MassDriverEntity)) return; - - MassDriver driver = (MassDriver)tile.block(); - - MassDriverEntity entity = tile.entity(); - MassDriverEntity other = target.entity(); - - entity.reload = 1f; - - DriverBulletData data = Pooling.obtain(DriverBulletData.class); - data.from = entity; - data.to = other; - for (int i = 0; i < Item.all().size; i++) { - data.items[i] = entity.items.get(Item.getByID(i)); + @Override + public void reset(){ + from = null; + to = null; + ; } - entity.items.clear(); - - float angle = tile.angleTo(target); - - other.isRecieving = true; - Bullet.create(TurretBullets.driverBolt, entity, entity.getTeam(), - tile.drawx() + Angles.trnsx(angle, driver.translation), tile.drawy() + Angles.trnsy(angle, driver.translation), - angle, 1f, data); - - Effects.effect(driver.shootEffect, tile.drawx() + Angles.trnsx(angle, driver.translation), - tile.drawy() + Angles.trnsy(angle, driver.translation), angle); - - Effects.effect(driver.smokeEffect, tile.drawx() + Angles.trnsx(angle, driver.translation), - tile.drawy() + Angles.trnsy(angle, driver.translation), angle); - - Effects.shake(driver.shake, driver.shake, entity); } public class MassDriverEntity extends TileEntity{ @@ -226,7 +238,7 @@ public class MassDriver extends Block { int totalItems = items.total(); //add all the items possible - for(int i = 0; i < data.items.length; i ++){ + for(int i = 0; i < data.items.length; i++){ int maxAdd = Math.min(data.items[i], itemCapacity - totalItems); items.add(Item.getByID(i), maxAdd); data.items[i] -= maxAdd; @@ -238,7 +250,7 @@ public class MassDriver extends Block { } //drop all items remaining on the ground - for(int i = 0; i < data.items.length; i ++){ + for(int i = 0; i < data.items.length; i++){ int amountDropped = Mathf.random(0, data.items[i]); if(amountDropped > 0){ float angle = Mathf.range(180f); @@ -260,24 +272,13 @@ public class MassDriver extends Block { } @Override - public void write(DataOutputStream stream) throws IOException { + public void write(DataOutputStream stream) throws IOException{ stream.writeInt(link); } @Override - public void read(DataInputStream stream) throws IOException { + public void read(DataInputStream stream) throws IOException{ link = stream.readInt(); } } - - public static class DriverBulletData implements Poolable{ - public MassDriverEntity from, to; - public int[] items = new int[Item.all().size]; - - @Override - public void reset() { - from = null; - to = null;; - } - } } diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/OverflowGate.java b/core/src/io/anuke/mindustry/world/blocks/distribution/OverflowGate.java index 60dbf0adc7..c7ebb6e75a 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/OverflowGate.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/OverflowGate.java @@ -4,9 +4,9 @@ import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.Tile; import io.anuke.ucore.util.Mathf; -public class OverflowGate extends Splitter { +public class OverflowGate extends Splitter{ - public OverflowGate(String name) { + public OverflowGate(String name){ super(name); hasItems = true; } @@ -38,11 +38,11 @@ public class OverflowGate extends Splitter { if(dest.getDump() == 0){ to = a; if(flip) - dest.setDump((byte)1); + dest.setDump((byte) 1); }else{ to = b; if(flip) - dest.setDump((byte)0); + dest.setDump((byte) 0); } } } diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/Router.java b/core/src/io/anuke/mindustry/world/blocks/distribution/Router.java index cd23e1990e..5994982a77 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/Router.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/Router.java @@ -8,48 +8,48 @@ import io.anuke.ucore.core.Timers; public class Router extends Block{ - public Router(String name) { - super(name); - update = true; - solid = true; - itemCapacity = 20; - hasItems = true; - group = BlockGroup.transportation; - autoSleep = true; - } - - @Override - public void update(Tile tile){ - int iterations = Math.max(1, (int) (Timers.delta() + 0.4f)); - boolean moved = tile.entity.items.total() > 0; + public Router(String name){ + super(name); + update = true; + solid = true; + itemCapacity = 20; + hasItems = true; + group = BlockGroup.transportation; + autoSleep = true; + } - for(int i = 0; i < iterations; i ++) { - if (tile.entity.items.total() > 0) { - tryDump(tile); - moved = true; - } - } + @Override + public void update(Tile tile){ + int iterations = Math.max(1, (int) (Timers.delta() + 0.4f)); + boolean moved = tile.entity.items.total() > 0; - if(!moved){ - tile.entity.sleep(); - } - } + for(int i = 0; i < iterations; i++){ + if(tile.entity.items.total() > 0){ + tryDump(tile); + moved = true; + } + } - @Override - public boolean canDump(Tile tile, Tile to, Item item) { + if(!moved){ + tile.entity.sleep(); + } + } + + @Override + public boolean canDump(Tile tile, Tile to, Item item){ return !(to.block() instanceof Router) || ((float) to.target().entity.items.total() / to.target().block().itemCapacity) < ((float) tile.entity.items.total() / to.target().block().itemCapacity); } - @Override - public void handleItem(Item item, Tile tile, Tile source){ - super.handleItem(item, tile, source); - tile.entity.wakeUp(); - } + @Override + public void handleItem(Item item, Tile tile, Tile source){ + super.handleItem(item, tile, source); + tile.entity.wakeUp(); + } - @Override - public boolean acceptItem(Item item, Tile tile, Tile source){ - int items = tile.entity.items.total(); - return items < itemCapacity; - } + @Override + public boolean acceptItem(Item item, Tile tile, Tile source){ + int items = tile.entity.items.total(); + return items < itemCapacity; + } } diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/Sorter.java b/core/src/io/anuke/mindustry/world/blocks/distribution/Sorter.java index 29d4324f3f..726aa1aadb 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/Sorter.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/Sorter.java @@ -21,110 +21,110 @@ import java.io.DataOutputStream; import java.io.IOException; public class Sorter extends Block implements SelectionTrait{ - - public Sorter(String name) { - super(name); - update = true; - solid = true; - instantTransfer = true; - group = BlockGroup.transportation; - configurable = true; - } - - @Override - public void draw(Tile tile){ - super.draw(tile); - //TODO call event for change - - SorterEntity entity = tile.entity(); + public Sorter(String name){ + super(name); + update = true; + solid = true; + instantTransfer = true; + group = BlockGroup.transportation; + configurable = true; + } - Draw.color(entity.sortItem.color); - Draw.rect("blank", tile.worldx(), tile.worldy(), 4f, 4f); - Draw.color(); - } - - @Override - public boolean acceptItem(Item item, Tile tile, Tile source){ - Tile to = getTileTarget(item, tile, source, false); - - return to != null && to.block().acceptItem(item, to, tile); - } - - @Override - public void handleItem(Item item, Tile tile, Tile source){ - Tile to = getTileTarget(item, tile, source, true); + @Remote(targets = Loc.both, called = Loc.both, in = In.blocks, forward = true) + public static void setSorterItem(Player player, Tile tile, Item item){ + SorterEntity entity = tile.entity(); + entity.sortItem = item; + } - to.block().handleItem(item, to, tile); - } - - Tile getTileTarget(Item item, Tile dest, Tile source, boolean flip){ - SorterEntity entity = dest.entity(); - - int dir = source.relativeTo(dest.x, dest.y); - if(dir == -1) return null; - Tile to; - - if(item == entity.sortItem){ - to = dest.getNearby(dir); - }else{ - Tile a = dest.getNearby(Mathf.mod(dir - 1, 4)); - Tile b = dest.getNearby(Mathf.mod(dir + 1, 4)); - boolean ac = a != null && !(a.block().instantTransfer && source.block().instantTransfer) && - a.block().acceptItem(item, a, dest); - boolean bc = b != null && !(b.block().instantTransfer && source.block().instantTransfer) && - b.block().acceptItem(item, b, dest); - - if(ac && !bc){ - to = a; - }else if(bc && !ac){ - to = b; - }else if(!bc){ - return null; - }else{ - if(dest.getDump() == 0){ - to = a; - if(flip) - dest.setDump((byte)1); - }else{ - to = b; - if(flip) - dest.setDump((byte)0); - } - } - } - - return to; - } - - @Override - public void buildTable(Tile tile, Table table){ - SorterEntity entity = tile.entity(); - buildItemTable(table, () -> entity.sortItem, item -> CallBlocks.setSorterItem(null, tile, item)); - } - - @Override - public TileEntity getEntity(){ - return new SorterEntity(); - } + @Override + public void draw(Tile tile){ + super.draw(tile); - @Remote(targets = Loc.both, called = Loc.both, in = In.blocks, forward = true) - public static void setSorterItem(Player player, Tile tile, Item item){ - SorterEntity entity = tile.entity(); - entity.sortItem = item; - } + //TODO call event for change - public static class SorterEntity extends TileEntity{ - public Item sortItem = Items.tungsten; - - @Override - public void write(DataOutputStream stream) throws IOException{ - stream.writeByte(sortItem.id); - } - - @Override - public void read(DataInputStream stream) throws IOException{ - sortItem = Item.all().get(stream.readByte()); - } - } + SorterEntity entity = tile.entity(); + + Draw.color(entity.sortItem.color); + Draw.rect("blank", tile.worldx(), tile.worldy(), 4f, 4f); + Draw.color(); + } + + @Override + public boolean acceptItem(Item item, Tile tile, Tile source){ + Tile to = getTileTarget(item, tile, source, false); + + return to != null && to.block().acceptItem(item, to, tile); + } + + @Override + public void handleItem(Item item, Tile tile, Tile source){ + Tile to = getTileTarget(item, tile, source, true); + + to.block().handleItem(item, to, tile); + } + + Tile getTileTarget(Item item, Tile dest, Tile source, boolean flip){ + SorterEntity entity = dest.entity(); + + int dir = source.relativeTo(dest.x, dest.y); + if(dir == -1) return null; + Tile to; + + if(item == entity.sortItem){ + to = dest.getNearby(dir); + }else{ + Tile a = dest.getNearby(Mathf.mod(dir - 1, 4)); + Tile b = dest.getNearby(Mathf.mod(dir + 1, 4)); + boolean ac = a != null && !(a.block().instantTransfer && source.block().instantTransfer) && + a.block().acceptItem(item, a, dest); + boolean bc = b != null && !(b.block().instantTransfer && source.block().instantTransfer) && + b.block().acceptItem(item, b, dest); + + if(ac && !bc){ + to = a; + }else if(bc && !ac){ + to = b; + }else if(!bc){ + return null; + }else{ + if(dest.getDump() == 0){ + to = a; + if(flip) + dest.setDump((byte) 1); + }else{ + to = b; + if(flip) + dest.setDump((byte) 0); + } + } + } + + return to; + } + + @Override + public void buildTable(Tile tile, Table table){ + SorterEntity entity = tile.entity(); + buildItemTable(table, () -> entity.sortItem, item -> CallBlocks.setSorterItem(null, tile, item)); + } + + @Override + public TileEntity getEntity(){ + return new SorterEntity(); + } + + public static class SorterEntity extends TileEntity{ + public Item sortItem = Items.tungsten; + + @Override + public void write(DataOutputStream stream) throws IOException{ + stream.writeByte(sortItem.id); + } + + @Override + public void read(DataInputStream stream) throws IOException{ + sortItem = Item.all().get(stream.readByte()); + } + } } diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/Splitter.java b/core/src/io/anuke/mindustry/world/blocks/distribution/Splitter.java index fd5c57bf19..1edf61002d 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/Splitter.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/Splitter.java @@ -35,9 +35,9 @@ public class Splitter extends Block{ Tile getTileTarget(Item item, Tile tile, Tile source, boolean flip){ Array proximity = tile.entity.proximity(); int counter = tile.getDump(); - for (int i = 0; i < proximity.size; i++) { + for(int i = 0; i < proximity.size; i++){ Tile other = proximity.get((i + counter) % proximity.size); - if(flip) tile.setDump((byte)((tile.getDump() + 1) % proximity.size)); + if(flip) tile.setDump((byte) ((tile.getDump() + 1) % proximity.size)); if(other != source && !(source.block().instantTransfer && other.block().instantTransfer) && !(other.block() instanceof Splitter) && other.block().acceptItem(item, other, Edges.getFacingEdge(tile, other))){ return other; diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/TunnelConduit.java b/core/src/io/anuke/mindustry/world/blocks/distribution/TunnelConduit.java index a342a41efc..8639a99da9 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/TunnelConduit.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/TunnelConduit.java @@ -7,11 +7,11 @@ import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.LiquidBlock; import io.anuke.ucore.graphics.Draw; -public class TunnelConduit extends LiquidBlock { +public class TunnelConduit extends LiquidBlock{ protected int maxdist = 3; protected float speed = 53; - protected TunnelConduit(String name) { + protected TunnelConduit(String name){ super(name); rotate = true; solid = true; @@ -21,7 +21,7 @@ public class TunnelConduit extends LiquidBlock { } @Override - public void setBars() { + public void setBars(){ super.setBars(); bars.remove(BarType.liquid); } @@ -37,39 +37,39 @@ public class TunnelConduit extends LiquidBlock { } @Override - public void handleLiquid(Tile tile, Tile source, Liquid liquid, float amount) { + public void handleLiquid(Tile tile, Tile source, Liquid liquid, float amount){ Tile tunnel = getDestTunnel(tile); - if (tunnel == null) return; + if(tunnel == null) return; Tile to = tunnel.getNearby(tunnel.getRotation()); - if (to == null || !(to.block().hasLiquids)) return; + if(to == null || !(to.block().hasLiquids)) return; - if (to.block().acceptLiquid(to, tunnel, liquid, amount)) + if(to.block().acceptLiquid(to, tunnel, liquid, amount)) to.block().handleLiquid(to, tunnel, liquid, amount); } @Override - public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount) { + public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){ int rot = source.relativeTo(tile.x, tile.y); - if (rot != (tile.getRotation() + 2) % 4) return false; + if(rot != (tile.getRotation() + 2) % 4) return false; Tile tunnel = getDestTunnel(tile); - if (tunnel != null) { + if(tunnel != null){ Tile to = tunnel.getNearby(tunnel.getRotation()); return to != null && (to.block().hasLiquids) && (to.block()).acceptLiquid(to, tunnel, liquid, amount); - } else { + }else{ return false; } } - Tile getDestTunnel(Tile tile) { + Tile getDestTunnel(Tile tile){ Tile dest = tile; int rel = (tile.getRotation() + 2) % 4; - for (int i = 0; i < maxdist; i++) { - if (dest == null) return null; + for(int i = 0; i < maxdist; i++){ + if(dest == null) return null; dest = dest.getNearby(rel); - if (dest != null && dest.block() instanceof TunnelConduit && dest.getRotation() == rel - && dest.getNearby(rel) != null) { + if(dest != null && dest.block() instanceof TunnelConduit && dest.getRotation() == rel + && dest.getNearby(rel) != null){ return dest; } } diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/WarpGate.java b/core/src/io/anuke/mindustry/world/blocks/distribution/WarpGate.java index 4a1b8e849e..0ed512555b 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/WarpGate.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/WarpGate.java @@ -36,133 +36,136 @@ import static io.anuke.mindustry.Vars.tilesize; //TODO implement public class WarpGate extends PowerBlock{ - public static final Color[] colorArray = {Color.ROYAL, Color.ORANGE, Color.SCARLET, Color.LIME, - Color.PURPLE, Color.GOLD, Color.PINK, Color.LIGHT_GRAY}; - public static final int colors = colorArray.length; + public static final Color[] colorArray = {Color.ROYAL, Color.ORANGE, Color.SCARLET, Color.LIME, + Color.PURPLE, Color.GOLD, Color.PINK, Color.LIGHT_GRAY}; + public static final int colors = colorArray.length; + private static ObjectSet[] teleporters = new ObjectSet[colors]; + private static Color color = new Color(); + private static byte lastColor = 0; - protected int timerTeleport = timers++; + static{ + for(int i = 0; i < colors; i++){ + teleporters[i] = new ObjectSet<>(); + } + } - private static ObjectSet[] teleporters = new ObjectSet[colors]; - private static Color color = new Color(); - private static byte lastColor = 0; + protected int timerTeleport = timers++; + protected float warmupTime = 60f; + //time between teleports + protected float teleportMax = 400f; + protected float teleportLiquidUse = 0.3f; + protected Liquid inputLiquid = Liquids.cryofluid; + protected Effect activateEffect = BlockFx.teleportActivate; + protected Effect teleportEffect = BlockFx.teleport; + protected Effect teleportOutEffect = BlockFx.teleportOut; + private Array removal = new Array<>(); + private Array returns = new Array<>(); - private Array removal = new Array<>(); - private Array returns = new Array<>(); + public WarpGate(String name){ + super(name); + update = true; + solid = true; + health = 80; + powerCapacity = 300f; + size = 3; + itemCapacity = 100; + hasLiquids = true; + hasItems = true; + liquidCapacity = 100f; + configurable = true; + } - protected float warmupTime = 60f; - //time between teleports - protected float teleportMax = 400f; - protected float teleportLiquidUse = 0.3f; - protected Liquid inputLiquid = Liquids.cryofluid; - protected Effect activateEffect = BlockFx.teleportActivate; - protected Effect teleportEffect = BlockFx.teleport; - protected Effect teleportOutEffect = BlockFx.teleportOut; + @Remote(targets = Loc.both, called = Loc.both, in = In.blocks, forward = true) + public static void setTeleporterColor(Player player, Tile tile, byte color){ + TeleporterEntity entity = tile.entity(); + entity.color = color; + } - static{ - for(int i = 0; i < colors; i ++){ - teleporters[i] = new ObjectSet<>(); - } - } - - public WarpGate(String name) { - super(name); - update = true; - solid = true; - health = 80; - powerCapacity = 300f; - size = 3; - itemCapacity = 100; - hasLiquids = true; - hasItems = true; - liquidCapacity = 100f; - configurable = true; - } + @Override + public void setStats(){ + super.setStats(); + } - @Override - public void setStats(){ - super.setStats(); - } + @Override + public void placed(Tile tile){ + CallBlocks.setTeleporterColor(null, tile, lastColor); + } - @Override - public void placed(Tile tile){ - CallBlocks.setTeleporterColor(null, tile, lastColor); - } - - @Override - public void draw(Tile tile){ - super.draw(tile); + @Override + public void draw(Tile tile){ + super.draw(tile); - TeleporterEntity entity = tile.entity(); - float time = entity.time; - float rad = entity.activeScl; + TeleporterEntity entity = tile.entity(); + float time = entity.time; + float rad = entity.activeScl; - if(entity.liquidLackScl > 0.01f){ - Graphics.setAdditiveBlending(); - Draw.color(1f, 0.3f, 0.3f, 0.4f * entity.liquidLackScl); - Fill.square(tile.drawx(), tile.drawy(), size * tilesize); - Graphics.setNormalBlending(); - } + if(entity.liquidLackScl > 0.01f){ + Graphics.setAdditiveBlending(); + Draw.color(1f, 0.3f, 0.3f, 0.4f * entity.liquidLackScl); + Fill.square(tile.drawx(), tile.drawy(), size * tilesize); + Graphics.setNormalBlending(); + } - Draw.color(getColor(tile, 0)); - Draw.rect(name+"-top", tile.drawx(), tile.drawy()); - Draw.reset(); + Draw.color(getColor(tile, 0)); + Draw.rect(name + "-top", tile.drawx(), tile.drawy()); + Draw.reset(); - if(rad <= 0.0001f) return; + if(rad <= 0.0001f) return; - Draw.color(getColor(tile, 0)); + Draw.color(getColor(tile, 0)); - Fill.circle(tile.drawx(), tile.drawy(), rad*(7f + Mathf.absin(time+55, 8f, 1f))); + Fill.circle(tile.drawx(), tile.drawy(), rad * (7f + Mathf.absin(time + 55, 8f, 1f))); - Draw.color(getColor(tile, -1)); + Draw.color(getColor(tile, -1)); - Fill.circle(tile.drawx(), tile.drawy(), rad*(2f + Mathf.absin(time, 7f, 3f))); + Fill.circle(tile.drawx(), tile.drawy(), rad * (2f + Mathf.absin(time, 7f, 3f))); - for(int i = 0; i < 11; i ++){ - Lines.swirl(tile.drawx(), tile.drawy(), - rad*(2f + i/3f + Mathf.sin(time - i *75, 20f + i, 3f)), - 0.3f + Mathf.sin(time + i *33, 10f + i, 0.1f), - time * (1f + Mathf.randomSeedRange(i + 1, 1f)) + Mathf.randomSeedRange(i, 360f)); - } + for(int i = 0; i < 11; i++){ + Lines.swirl(tile.drawx(), tile.drawy(), + rad * (2f + i / 3f + Mathf.sin(time - i * 75, 20f + i, 3f)), + 0.3f + Mathf.sin(time + i * 33, 10f + i, 0.1f), + time * (1f + Mathf.randomSeedRange(i + 1, 1f)) + Mathf.randomSeedRange(i, 360f)); + } - Draw.color(getColor(tile, 1)); + Draw.color(getColor(tile, 1)); - Lines.stroke(2f); - Lines.circle(tile.drawx(), tile.drawy(), rad*(7f + Mathf.absin(time+55, 8f, 1f))); - Lines.stroke(1f); + Lines.stroke(2f); + Lines.circle(tile.drawx(), tile.drawy(), rad * (7f + Mathf.absin(time + 55, 8f, 1f))); + Lines.stroke(1f); - for(int i = 0; i < 11; i ++){ - Lines.swirl(tile.drawx(), tile.drawy(), - rad*(3f + i/3f + Mathf.sin(time + i *93, 20f + i, 3f)), - 0.2f + Mathf.sin(time + i *33, 10f + i, 0.1f), - time * (1f + Mathf.randomSeedRange(i + 1, 1f)) + Mathf.randomSeedRange(i, 360f)); - } + for(int i = 0; i < 11; i++){ + Lines.swirl(tile.drawx(), tile.drawy(), + rad * (3f + i / 3f + Mathf.sin(time + i * 93, 20f + i, 3f)), + 0.2f + Mathf.sin(time + i * 33, 10f + i, 0.1f), + time * (1f + Mathf.randomSeedRange(i + 1, 1f)) + Mathf.randomSeedRange(i, 360f)); + } - Draw.reset(); - } - - @Override - public void update(Tile tile){ - TeleporterEntity entity = tile.entity(); + Draw.reset(); + } - teleporters[entity.color].add(tile); + @Override + public void update(Tile tile){ + TeleporterEntity entity = tile.entity(); - if(entity.items.total() > 0){ - tryDump(tile); - } + teleporters[entity.color].add(tile); - if(!entity.active){ - entity.activeScl = Mathf.lerpDelta(entity.activeScl, 0f, 0.01f); + if(entity.items.total() > 0){ + tryDump(tile); + } - if(entity.power.amount >= powerCapacity){ - Color resultColor = new Color(); - resultColor.set(getColor(tile, 0)); + if(!entity.active){ + entity.activeScl = Mathf.lerpDelta(entity.activeScl, 0f, 0.01f); - entity.active = true; - entity.power.amount = 0f; - Effects.effect(activateEffect, resultColor, tile.drawx(), tile.drawy()); - } - }else{ - entity.activeScl = Mathf.lerpDelta(entity.activeScl, 1f, 0.015f); + if(entity.power.amount >= powerCapacity){ + Color resultColor = new Color(); + resultColor.set(getColor(tile, 0)); + + entity.active = true; + entity.power.amount = 0f; + Effects.effect(activateEffect, resultColor, tile.drawx(), tile.drawy()); + } + }else{ + entity.activeScl = Mathf.lerpDelta(entity.activeScl, 1f, 0.015f); /* if (entity.power.amount >= powerUsed) { @@ -185,26 +188,26 @@ public class WarpGate extends PowerBlock{ entity.liquidLackScl = Mathf.lerpDelta(entity.liquidLackScl, 1f, 0.1f); }*/ - if(entity.liquidLackScl >= 0.999f){ - catastrophicFailure(tile); - } + if(entity.liquidLackScl >= 0.999f){ + catastrophicFailure(tile); + } - //TODO draw warning info! + //TODO draw warning info! - if (entity.teleporting) { - entity.speedScl = Mathf.lerpDelta(entity.speedScl, 2f, 0.01f); - //liquidUsed = Math.min(liquidCapacity, teleportLiquidUse * Timers.delta()); + if(entity.teleporting){ + entity.speedScl = Mathf.lerpDelta(entity.speedScl, 2f, 0.01f); + //liquidUsed = Math.min(liquidCapacity, teleportLiquidUse * Timers.delta()); - //if (entity.liquids.amount >= liquidUsed) { - // entity.liquids.amount -= liquidUsed; - //} else { - catastrophicFailure(tile); - //} - } else { - entity.speedScl = Mathf.lerpDelta(entity.speedScl, 1f, 0.04f); - } + //if (entity.liquids.amount >= liquidUsed) { + // entity.liquids.amount -= liquidUsed; + //} else { + catastrophicFailure(tile); + //} + }else{ + entity.speedScl = Mathf.lerpDelta(entity.speedScl, 1f, 0.04f); + } - entity.time += Timers.delta() * entity.speedScl; + entity.time += Timers.delta() * entity.speedScl; /* if (!entity.teleporting && entity.items.total() >= itemCapacity && entity.power.amount >= powerCapacity - 0.01f - powerUse && entity.timer.get(timerTeleport, teleportMax)) { @@ -235,138 +238,132 @@ public class WarpGate extends PowerBlock{ entity.teleporting = false; }); }*/ - } - } - - @Override - public void buildTable(Tile tile, Table table){ - TeleporterEntity entity = tile.entity(); + } + } - //TODO call event for change + @Override + public void buildTable(Tile tile, Table table){ + TeleporterEntity entity = tile.entity(); - ButtonGroup group = new ButtonGroup<>(); - Table cont = new Table(); + //TODO call event for change - for(int i = 0; i < colors; i ++){ - final int f = i; - ImageButton button = cont.addImageButton("white", "toggle", 24, () -> { - lastColor = (byte)f; - CallBlocks.setTeleporterColor(null, tile, (byte)f); - }).size(34, 38).padBottom(-5.1f).group(group).get(); - button.getStyle().imageUpColor = colorArray[f]; - button.setChecked(entity.color == f); + ButtonGroup group = new ButtonGroup<>(); + Table cont = new Table(); - if(i%4 == 3){ - cont.row(); - } - } + for(int i = 0; i < colors; i++){ + final int f = i; + ImageButton button = cont.addImageButton("white", "toggle", 24, () -> { + lastColor = (byte) f; + CallBlocks.setTeleporterColor(null, tile, (byte) f); + }).size(34, 38).padBottom(-5.1f).group(group).get(); + button.getStyle().imageUpColor = colorArray[f]; + button.setChecked(entity.color == f); - table.add(cont); - } - - @Override - public boolean acceptItem(Item item, Tile tile, Tile source){ - TeleporterEntity entity = tile.entity(); - return entity.items.total() < itemCapacity; - } - - @Override - public TileEntity getEntity(){ - return new TeleporterEntity(); - } + if(i % 4 == 3){ + cont.row(); + } + } - @Override - public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount) { - return super.acceptLiquid(tile, source, liquid, amount) && liquid == inputLiquid; - } + table.add(cont); + } - @Override - public void onDestroyed(Tile tile) { - super.onDestroyed(tile); + @Override + public boolean acceptItem(Item item, Tile tile, Tile source){ + TeleporterEntity entity = tile.entity(); + return entity.items.total() < itemCapacity; + } - TeleporterEntity entity = tile.entity(); + @Override + public TileEntity getEntity(){ + return new TeleporterEntity(); + } - if(entity.activeScl < 0.5f) return; + @Override + public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){ + return super.acceptLiquid(tile, source, liquid, amount) && liquid == inputLiquid; + } - //TODO catastrophic failure - } + @Override + public void onDestroyed(Tile tile){ + super.onDestroyed(tile); - private void catastrophicFailure(Tile tile){ - tile.entity.damage(tile.entity.health + 1); - //TODO fail gloriously - } + TeleporterEntity entity = tile.entity(); - private Color getColor(Tile tile, int shift){ - TeleporterEntity entity = tile.entity(); + if(entity.activeScl < 0.5f) return; - Color target = colorArray[entity.color]; - float ss = 0.5f; - float bs = 0.2f; + //TODO catastrophic failure + } - return Hue.shift(Hue.multiply(color.set(target), 1, ss), 2, shift * bs + (entity.speedScl - 1f)/3f); - } - - private Array findLinks(Tile tile){ - TeleporterEntity entity = tile.entity(); - - removal.clear(); - returns.clear(); - - for(Tile other : teleporters[entity.color]){ - if(other != tile){ - if(other.block() instanceof WarpGate){ - TeleporterEntity oe = other.entity(); - if(!oe.active) continue; - if(oe.color != entity.color){ - removal.add(other); - }else if(other.entity.items.total() == 0){ - returns.add(other); - } - }else{ - removal.add(other); - } - } - } + private void catastrophicFailure(Tile tile){ + tile.entity.damage(tile.entity.health + 1); + //TODO fail gloriously + } - for(Tile remove : removal) { - teleporters[entity.color].remove(remove); - } - - return returns; - } + private Color getColor(Tile tile, int shift){ + TeleporterEntity entity = tile.entity(); - @Remote(targets = Loc.both, called = Loc.both, in = In.blocks, forward = true) - public static void setTeleporterColor(Player player, Tile tile, byte color){ - TeleporterEntity entity = tile.entity(); - entity.color = color; - } + Color target = colorArray[entity.color]; + float ss = 0.5f; + float bs = 0.2f; - public static class TeleporterEntity extends TileEntity{ - public byte color = 0; - public boolean teleporting; - public boolean active; - public float activeScl = 0f; - public float speedScl = 1f; - public float powerLackScl, liquidLackScl; - public float time; - - @Override - public void write(DataOutputStream stream) throws IOException{ - stream.writeByte(color); - stream.writeBoolean(active); - stream.writeFloat(activeScl); - stream.writeFloat(speedScl); - stream.writeFloat(powerLackScl); - } - - @Override - public void read(DataInputStream stream) throws IOException{ - color = stream.readByte(); - active = stream.readBoolean(); - activeScl = stream.readFloat(); - speedScl = stream.readFloat(); - powerLackScl = stream.readFloat(); - } - } + return Hue.shift(Hue.multiply(color.set(target), 1, ss), 2, shift * bs + (entity.speedScl - 1f) / 3f); + } + + private Array findLinks(Tile tile){ + TeleporterEntity entity = tile.entity(); + + removal.clear(); + returns.clear(); + + for(Tile other : teleporters[entity.color]){ + if(other != tile){ + if(other.block() instanceof WarpGate){ + TeleporterEntity oe = other.entity(); + if(!oe.active) continue; + if(oe.color != entity.color){ + removal.add(other); + }else if(other.entity.items.total() == 0){ + returns.add(other); + } + }else{ + removal.add(other); + } + } + } + + for(Tile remove : removal){ + teleporters[entity.color].remove(remove); + } + + return returns; + } + + public static class TeleporterEntity extends TileEntity{ + public byte color = 0; + public boolean teleporting; + public boolean active; + public float activeScl = 0f; + public float speedScl = 1f; + public float powerLackScl, liquidLackScl; + public float time; + + @Override + public void write(DataOutputStream stream) throws IOException{ + stream.writeByte(color); + stream.writeBoolean(active); + stream.writeFloat(activeScl); + stream.writeFloat(speedScl); + stream.writeFloat(powerLackScl); + } + + @Override + public void read(DataInputStream stream) throws IOException{ + color = stream.readByte(); + active = stream.readBoolean(); + activeScl = stream.readFloat(); + speedScl = stream.readFloat(); + powerLackScl = stream.readFloat(); + } + } } diff --git a/core/src/io/anuke/mindustry/world/blocks/effect/EffectCore.java b/core/src/io/anuke/mindustry/world/blocks/effect/EffectCore.java index adf1a243df..9604d28d8e 100644 --- a/core/src/io/anuke/mindustry/world/blocks/effect/EffectCore.java +++ b/core/src/io/anuke/mindustry/world/blocks/effect/EffectCore.java @@ -11,14 +11,14 @@ import static io.anuke.mindustry.Vars.tilesize; public abstract class EffectCore extends Block{ protected int range = 7; - public EffectCore(String name) { + public EffectCore(String name){ super(name); update = true; solid = true; } @Override - public void drawSelect(Tile tile) { + public void drawSelect(Tile tile){ Draw.color(Palette.accent); Lines.dashCircle(tile.drawx(), tile.drawy(), range * tilesize); Draw.reset(); diff --git a/core/src/io/anuke/mindustry/world/blocks/effect/MendingCore.java b/core/src/io/anuke/mindustry/world/blocks/effect/MendingCore.java index 571cd4112d..897690610a 100644 --- a/core/src/io/anuke/mindustry/world/blocks/effect/MendingCore.java +++ b/core/src/io/anuke/mindustry/world/blocks/effect/MendingCore.java @@ -6,19 +6,21 @@ import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.world; -public class MendingCore extends EffectCore { - /**Mending speed as a percentage of block health, per frame.*/ +public class MendingCore extends EffectCore{ + /** + * Mending speed as a percentage of block health, per frame. + */ protected float mendSpeed = 0.8f; - public MendingCore(String name) { + public MendingCore(String name){ super(name); } @Override - public void update(Tile tile) { + public void update(Tile tile){ - for (int dx = Math.max(-range + tile.x, 0); dx <= Math.min(range + tile.y, world.width() - 1); dx++) { - for (int dy = Math.max(-range + tile.y, 0); dy <= Math.min(range + tile.y, world.height() - 1); dy++) { + for(int dx = Math.max(-range + tile.x, 0); dx <= Math.min(range + tile.y, world.width() - 1); dx++){ + for(int dy = Math.max(-range + tile.y, 0); dy <= Math.min(range + tile.y, world.height() - 1); dy++){ Tile other = world.tile(dx, dy); if(other.entity != null){ diff --git a/core/src/io/anuke/mindustry/world/blocks/logic/LogicBlock.java b/core/src/io/anuke/mindustry/world/blocks/logic/LogicBlock.java index 2e1a11c3b1..ccb78c365c 100644 --- a/core/src/io/anuke/mindustry/world/blocks/logic/LogicBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/logic/LogicBlock.java @@ -4,7 +4,7 @@ import io.anuke.mindustry.world.Block; public class LogicBlock extends Block{ - public LogicBlock(String name) { + public LogicBlock(String name){ super(name); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/power/BurnerGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/BurnerGenerator.java index cee1109845..91051e8a85 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/BurnerGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/BurnerGenerator.java @@ -3,19 +3,19 @@ package io.anuke.mindustry.world.blocks.power; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.Liquid; -public class BurnerGenerator extends ItemLiquidGenerator { +public class BurnerGenerator extends ItemLiquidGenerator{ - public BurnerGenerator(String name) { + public BurnerGenerator(String name){ super(name); } @Override - protected float getLiquidEfficiency(Liquid liquid) { + protected float getLiquidEfficiency(Liquid liquid){ return liquid.flammability; } @Override - protected float getItemEfficiency(Item item) { + protected float getItemEfficiency(Item item){ return item.flammability; } } diff --git a/core/src/io/anuke/mindustry/world/blocks/power/DecayGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/DecayGenerator.java index f1481bfe23..225efd98c5 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/DecayGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/DecayGenerator.java @@ -2,16 +2,16 @@ package io.anuke.mindustry.world.blocks.power; import io.anuke.mindustry.type.Item; -public class DecayGenerator extends ItemGenerator { +public class DecayGenerator extends ItemGenerator{ - public DecayGenerator(String name) { + public DecayGenerator(String name){ super(name); hasItems = true; hasLiquids = false; } @Override - protected float getItemEfficiency(Item item) { + protected float getItemEfficiency(Item item){ return item.radioactivity; } } diff --git a/core/src/io/anuke/mindustry/world/blocks/power/FusionReactor.java b/core/src/io/anuke/mindustry/world/blocks/power/FusionReactor.java index b4c36a3f5c..d31f5a5ed7 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/FusionReactor.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/FusionReactor.java @@ -12,7 +12,7 @@ import io.anuke.ucore.core.Timers; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.util.Mathf; -public class FusionReactor extends PowerGenerator { +public class FusionReactor extends PowerGenerator{ protected int plasmas = 4; protected float maxPowerProduced = 2f; protected float warmupSpeed = 0.001f; @@ -20,7 +20,7 @@ public class FusionReactor extends PowerGenerator { protected Color plasma1 = Color.valueOf("ffd06b"), plasma2 = Color.valueOf("ff361b"); protected Color ind1 = Color.valueOf("858585"), ind2 = Color.valueOf("fea080"); - public FusionReactor(String name) { + public FusionReactor(String name){ super(name); hasPower = true; hasLiquids = true; @@ -30,7 +30,7 @@ public class FusionReactor extends PowerGenerator { } @Override - public void setStats() { + public void setStats(){ super.setStats(); stats.add(BlockStat.maxPowerGeneration, maxPowerProduced * 60f, StatUnit.powerSecond); @@ -54,17 +54,17 @@ public class FusionReactor extends PowerGenerator { } @Override - public float handleDamage(Tile tile, float amount) { + public float handleDamage(Tile tile, float amount){ FusionReactorEntity entity = tile.entity(); if(entity.warmup < 0.4f) return amount; - float healthFract = tile.entity.health/health; + float healthFract = tile.entity.health / health; //5% chance to explode when hit at <50% HP with a normal bullet if(amount > 5f && healthFract <= 0.5f && Mathf.chance(0.05)){ return health; - //10% chance to explode when hit at <25% HP with a powerful bullet + //10% chance to explode when hit at <25% HP with a powerful bullet }else if(amount > 8f && healthFract <= 0.2f && Mathf.chance(0.1)){ return health; } @@ -73,19 +73,19 @@ public class FusionReactor extends PowerGenerator { } @Override - public void draw(Tile tile) { + public void draw(Tile tile){ FusionReactorEntity entity = tile.entity(); Draw.rect(name + "-bottom", tile.drawx(), tile.drawy()); Graphics.setAdditiveBlending(); - for(int i = 0; i < plasmas; i ++){ - float r = 29f + Mathf.absin(Timers.time(), 2f + i*1f, 5f - i*0.5f); + for(int i = 0; i < plasmas; i++){ + float r = 29f + Mathf.absin(Timers.time(), 2f + i * 1f, 5f - i * 0.5f); - Draw.color(plasma1, plasma2, (float)i/plasmas); - Draw.alpha((0.3f + Mathf.absin(Timers.time(), 2f+i*2f, 0.3f+i*0.05f)) * entity.warmup); - Draw.rect(name + "-plasma-" + i, tile.drawx(), tile.drawy(), r, r, Timers.time()*(12+i*6f) * entity.warmup); + Draw.color(plasma1, plasma2, (float) i / plasmas); + Draw.alpha((0.3f + Mathf.absin(Timers.time(), 2f + i * 2f, 0.3f + i * 0.05f)) * entity.warmup); + Draw.rect(name + "-plasma-" + i, tile.drawx(), tile.drawy(), r, r, Timers.time() * (12 + i * 6f) * entity.warmup); } Draw.color(); @@ -96,24 +96,24 @@ public class FusionReactor extends PowerGenerator { Draw.rect(name + "-top", tile.drawx(), tile.drawy()); - Draw.color(ind1, ind2, entity.warmup + Mathf.absin(entity.totalProgress, 3f, entity.warmup*0.5f)); + Draw.color(ind1, ind2, entity.warmup + Mathf.absin(entity.totalProgress, 3f, entity.warmup * 0.5f)); Draw.rect(name + "-light", tile.drawx(), tile.drawy()); Draw.color(); } @Override - public TextureRegion[] getIcon() { + public TextureRegion[] getIcon(){ return new TextureRegion[]{Draw.region(name + "-bottom"), Draw.region(name), Draw.region(name + "-top")}; } @Override - public TileEntity getEntity() { + public TileEntity getEntity(){ return new FusionReactorEntity(); } @Override - public void onDestroyed(Tile tile) { + public void onDestroyed(Tile tile){ super.onDestroyed(tile); FusionReactorEntity entity = tile.entity(); diff --git a/core/src/io/anuke/mindustry/world/blocks/power/ItemGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/ItemGenerator.java index 872f03156e..0e5ba6d68a 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/ItemGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/ItemGenerator.java @@ -23,113 +23,113 @@ import java.io.IOException; import static io.anuke.mindustry.Vars.tilesize; -public abstract class ItemGenerator extends PowerGenerator { - protected float minItemEfficiency = 0.2f; - protected float powerOutput; - protected float itemDuration = 70f; - protected Effect generateEffect = BlockFx.generatespark, explodeEffect = - BlockFx.generatespark; - protected Color heatColor = Color.valueOf("ff9b59"); - protected TextureRegion topRegion; +public abstract class ItemGenerator extends PowerGenerator{ + protected float minItemEfficiency = 0.2f; + protected float powerOutput; + protected float itemDuration = 70f; + protected Effect generateEffect = BlockFx.generatespark, explodeEffect = + BlockFx.generatespark; + protected Color heatColor = Color.valueOf("ff9b59"); + protected TextureRegion topRegion; - public ItemGenerator(String name) { - super(name); - itemCapacity = 20; - hasItems = true; + public ItemGenerator(String name){ + super(name); + itemCapacity = 20; + hasItems = true; - consumes.add(new ConsumeItemFilter(item -> getItemEfficiency(item) >= minItemEfficiency)).update(false).optional(true); - } + consumes.add(new ConsumeItemFilter(item -> getItemEfficiency(item) >= minItemEfficiency)).update(false).optional(true); + } - @Override - public void load() { - super.load(); - topRegion = Draw.region(name + "-top"); - } + @Override + public void load(){ + super.load(); + topRegion = Draw.region(name + "-top"); + } - @Override - public void setStats() { - super.setStats(); + @Override + public void setStats(){ + super.setStats(); - stats.add(BlockStat.maxPowerGeneration, powerOutput * 60f, StatUnit.powerSecond); - } + stats.add(BlockStat.maxPowerGeneration, powerOutput * 60f, StatUnit.powerSecond); + } - @Override - public void setBars(){ - super.setBars(); - bars.replace(new BlockBar(BarType.inventory, true, tile -> (float)tile.entity.items.total() / itemCapacity)); - } - - @Override - public void draw(Tile tile){ - super.draw(tile); + @Override + public void setBars(){ + super.setBars(); + bars.replace(new BlockBar(BarType.inventory, true, tile -> (float) tile.entity.items.total() / itemCapacity)); + } - GeneratorEntity entity = tile.entity(); - - if(entity.generateTime > 0){ - Draw.color(heatColor); - float alpha = (entity.items.total() > 0 ? 1f : Mathf.clamp(entity.generateTime)); - alpha = alpha * 0.7f + Mathf.absin(Timers.time(), 12f, 0.3f) * alpha; - Draw.alpha(alpha); - Draw.rect(topRegion, tile.drawx(), tile.drawy()); - Draw.reset(); - } - } - - @Override - public boolean acceptItem(Item item, Tile tile, Tile source){ - return getItemEfficiency(item) >= minItemEfficiency && tile.entity.items.total() < itemCapacity; - } - - @Override - public void update(Tile tile){ - ItemGeneratorEntity entity = tile.entity(); - - float maxPower = Math.min(powerCapacity - entity.power.amount, powerOutput * Timers.delta()) * entity.efficiency; - float mfract = maxPower/(powerOutput); - - if(entity.generateTime > 0f){ - entity.generateTime -= 1f/itemDuration*mfract; - entity.power.amount += maxPower; - entity.generateTime = Mathf.clamp(entity.generateTime); + @Override + public void draw(Tile tile){ + super.draw(tile); - if(Mathf.chance(Timers.delta() * 0.06 * Mathf.clamp(entity.explosiveness - 0.25f))){ - entity.damage(Mathf.random(8f)); - Effects.effect(explodeEffect, tile.worldx() + Mathf.range(size * tilesize/2f), tile.worldy() + Mathf.range(size * tilesize/2f)); - } - } + GeneratorEntity entity = tile.entity(); - if (entity.generateTime <= 0f && entity.items.total() > 0) { - Effects.effect(generateEffect, tile.worldx() + Mathf.range(3f), tile.worldy() + Mathf.range(3f)); - Item item = entity.items.take(); - entity.efficiency = getItemEfficiency(item); - entity.explosiveness = item.explosiveness; - entity.generateTime = 1f; - } - - distributePower(tile); - - } + if(entity.generateTime > 0){ + Draw.color(heatColor); + float alpha = (entity.items.total() > 0 ? 1f : Mathf.clamp(entity.generateTime)); + alpha = alpha * 0.7f + Mathf.absin(Timers.time(), 12f, 0.3f) * alpha; + Draw.alpha(alpha); + Draw.rect(topRegion, tile.drawx(), tile.drawy()); + Draw.reset(); + } + } - protected abstract float getItemEfficiency(Item item); + @Override + public boolean acceptItem(Item item, Tile tile, Tile source){ + return getItemEfficiency(item) >= minItemEfficiency && tile.entity.items.total() < itemCapacity; + } - @Override - public TileEntity getEntity() { - return new ItemGeneratorEntity(); - } + @Override + public void update(Tile tile){ + ItemGeneratorEntity entity = tile.entity(); - public static class ItemGeneratorEntity extends GeneratorEntity{ - public float efficiency; - public float explosiveness; + float maxPower = Math.min(powerCapacity - entity.power.amount, powerOutput * Timers.delta()) * entity.efficiency; + float mfract = maxPower / (powerOutput); - @Override - public void write(DataOutputStream stream) throws IOException { - stream.writeFloat(efficiency); - } + if(entity.generateTime > 0f){ + entity.generateTime -= 1f / itemDuration * mfract; + entity.power.amount += maxPower; + entity.generateTime = Mathf.clamp(entity.generateTime); - @Override - public void read(DataInputStream stream) throws IOException { - efficiency = stream.readFloat(); - } - } + if(Mathf.chance(Timers.delta() * 0.06 * Mathf.clamp(entity.explosiveness - 0.25f))){ + entity.damage(Mathf.random(8f)); + Effects.effect(explodeEffect, tile.worldx() + Mathf.range(size * tilesize / 2f), tile.worldy() + Mathf.range(size * tilesize / 2f)); + } + } + + if(entity.generateTime <= 0f && entity.items.total() > 0){ + Effects.effect(generateEffect, tile.worldx() + Mathf.range(3f), tile.worldy() + Mathf.range(3f)); + Item item = entity.items.take(); + entity.efficiency = getItemEfficiency(item); + entity.explosiveness = item.explosiveness; + entity.generateTime = 1f; + } + + distributePower(tile); + + } + + protected abstract float getItemEfficiency(Item item); + + @Override + public TileEntity getEntity(){ + return new ItemGeneratorEntity(); + } + + public static class ItemGeneratorEntity extends GeneratorEntity{ + public float efficiency; + public float explosiveness; + + @Override + public void write(DataOutputStream stream) throws IOException{ + stream.writeFloat(efficiency); + } + + @Override + public void read(DataInputStream stream) throws IOException{ + efficiency = stream.readFloat(); + } + } } diff --git a/core/src/io/anuke/mindustry/world/blocks/power/ItemLiquidGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/ItemLiquidGenerator.java index 9e1efada0d..60fc48d267 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/ItemLiquidGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/ItemLiquidGenerator.java @@ -12,13 +12,15 @@ import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.tilesize; -public abstract class ItemLiquidGenerator extends ItemGenerator { +public abstract class ItemLiquidGenerator extends ItemGenerator{ protected float minLiquidEfficiency = 0.2f; protected float powerPerLiquid = 0.13f; - /**Maximum liquid used per frame.*/ + /** + * Maximum liquid used per frame. + */ protected float maxLiquidGenerate = 0.4f; - public ItemLiquidGenerator(String name) { + public ItemLiquidGenerator(String name){ super(name); hasLiquids = true; liquidCapacity = 10f; @@ -31,7 +33,7 @@ public abstract class ItemLiquidGenerator extends ItemGenerator { ItemGeneratorEntity entity = tile.entity(); Liquid liquid = null; - for (Liquid other : Liquid.all()){ + for(Liquid other : Liquid.all()){ if(entity.liquids.get(other) >= 0.001f && getLiquidEfficiency(other) >= minLiquidEfficiency){ liquid = other; break; @@ -40,9 +42,9 @@ public abstract class ItemLiquidGenerator extends ItemGenerator { //liquid takes priority over solids if(liquid != null && entity.liquids.get(liquid) >= 0.001f && entity.cons.valid()){ - float powerPerLiquid = getLiquidEfficiency(liquid)*this.powerPerLiquid; + float powerPerLiquid = getLiquidEfficiency(liquid) * this.powerPerLiquid; float used = Math.min(entity.liquids.get(liquid), maxLiquidGenerate * Timers.delta()); - used = Math.min(used, (powerCapacity - entity.power.amount)/powerPerLiquid); + used = Math.min(used, (powerCapacity - entity.power.amount) / powerPerLiquid); entity.liquids.remove(liquid, used); entity.power.amount += used * powerPerLiquid; @@ -50,23 +52,23 @@ public abstract class ItemLiquidGenerator extends ItemGenerator { if(used > 0.001f && Mathf.chance(0.05 * Timers.delta())){ Effects.effect(generateEffect, tile.drawx() + Mathf.range(3f), tile.drawy() + Mathf.range(3f)); } - }else if (entity.cons.valid()){ + }else if(entity.cons.valid()){ float maxPower = Math.min(powerCapacity - entity.power.amount, powerOutput * Timers.delta()) * entity.efficiency; float mfract = maxPower / (powerOutput); - if (entity.generateTime > 0f) { + if(entity.generateTime > 0f){ entity.generateTime -= 1f / itemDuration * mfract; entity.power.amount += maxPower; entity.generateTime = Mathf.clamp(entity.generateTime); if(Mathf.chance(Timers.delta() * 0.06 * Mathf.clamp(entity.explosiveness - 0.25f))){ entity.damage(Mathf.random(8f)); - Effects.effect(explodeEffect, tile.worldx() + Mathf.range(size * tilesize/2f), tile.worldy() + Mathf.range(size * tilesize/2f)); + Effects.effect(explodeEffect, tile.worldx() + Mathf.range(size * tilesize / 2f), tile.worldy() + Mathf.range(size * tilesize / 2f)); } } - if (entity.generateTime <= 0f && entity.items.total() > 0) { + if(entity.generateTime <= 0f && entity.items.total() > 0){ Effects.effect(generateEffect, tile.worldx() + Mathf.range(3f), tile.worldy() + Mathf.range(3f)); Item item = entity.items.take(); entity.efficiency = getItemEfficiency(item); diff --git a/core/src/io/anuke/mindustry/world/blocks/power/LiquidGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/LiquidGenerator.java index ddb092e181..b33f2c82d3 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/LiquidGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/LiquidGenerator.java @@ -12,69 +12,73 @@ import io.anuke.ucore.core.Timers; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.util.Mathf; -public abstract class LiquidGenerator extends PowerGenerator { - protected float minEfficiency = 0.2f; - protected float powerPerLiquid = 0.13f; - /**Maximum liquid used per frame.*/ - protected float maxLiquidGenerate = 0.4f; - protected Effect generateEffect = BlockFx.generatespark; +public abstract class LiquidGenerator extends PowerGenerator{ + protected float minEfficiency = 0.2f; + protected float powerPerLiquid = 0.13f; + /** + * Maximum liquid used per frame. + */ + protected float maxLiquidGenerate = 0.4f; + protected Effect generateEffect = BlockFx.generatespark; - public LiquidGenerator(String name) { - super(name); - liquidCapacity = 30f; - hasLiquids = true; + public LiquidGenerator(String name){ + super(name); + liquidCapacity = 30f; + hasLiquids = true; - consumes.add(new ConsumeLiquidFilter(liquid -> getEfficiency(liquid) >= minEfficiency, 0.001f)).update(false); - } + consumes.add(new ConsumeLiquidFilter(liquid -> getEfficiency(liquid) >= minEfficiency, 0.001f)).update(false); + } - @Override - public void draw(Tile tile){ - super.draw(tile); + @Override + public void draw(Tile tile){ + super.draw(tile); - TileEntity entity = tile.entity(); - - Draw.color(entity.liquids.current().color); - Draw.alpha(entity.liquids.total() / liquidCapacity); - drawLiquidCenter(tile); - Draw.color(); - } - - public void drawLiquidCenter(Tile tile){ - Draw.rect("blank", tile.drawx(), tile.drawy(), 2, 2); - } - - @Override - public void update(Tile tile){ - TileEntity entity = tile.entity(); - - if(entity.liquids.get(entity.liquids.current()) >= 0.001f){ - float powerPerLiquid = getEfficiency(entity.liquids.current())*this.powerPerLiquid; - float used = Math.min(entity.liquids.currentAmount(), maxLiquidGenerate * Timers.delta()); - used = Math.min(used, (powerCapacity - entity.power.amount)/powerPerLiquid); + TileEntity entity = tile.entity(); - entity.liquids.remove(entity.liquids.current(), used); - entity.power.amount += used * powerPerLiquid; - - if(used > 0.001f && Mathf.chance(0.05 * Timers.delta())){ - Effects.effect(generateEffect, tile.drawx() + Mathf.range(3f), tile.drawy() + Mathf.range(3f)); - } - } - - distributePower(tile); - } - - @Override - public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){ - return getEfficiency(liquid) >= minEfficiency && super.acceptLiquid(tile, source, liquid, amount); - } + Draw.color(entity.liquids.current().color); + Draw.alpha(entity.liquids.total() / liquidCapacity); + drawLiquidCenter(tile); + Draw.color(); + } - @Override - public TileEntity getEntity() { - return new ItemGeneratorEntity(); - } + public void drawLiquidCenter(Tile tile){ + Draw.rect("blank", tile.drawx(), tile.drawy(), 2, 2); + } - /**Returns an efficiency value for the specified liquid. - * Greater efficiency means more power generation. - * If a liquid's efficiency is below {@link #minEfficiency}, it is not accepted.*/ - protected abstract float getEfficiency(Liquid liquid); + @Override + public void update(Tile tile){ + TileEntity entity = tile.entity(); + + if(entity.liquids.get(entity.liquids.current()) >= 0.001f){ + float powerPerLiquid = getEfficiency(entity.liquids.current()) * this.powerPerLiquid; + float used = Math.min(entity.liquids.currentAmount(), maxLiquidGenerate * Timers.delta()); + used = Math.min(used, (powerCapacity - entity.power.amount) / powerPerLiquid); + + entity.liquids.remove(entity.liquids.current(), used); + entity.power.amount += used * powerPerLiquid; + + if(used > 0.001f && Mathf.chance(0.05 * Timers.delta())){ + Effects.effect(generateEffect, tile.drawx() + Mathf.range(3f), tile.drawy() + Mathf.range(3f)); + } + } + + distributePower(tile); + } + + @Override + public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){ + return getEfficiency(liquid) >= minEfficiency && super.acceptLiquid(tile, source, liquid, amount); + } + + @Override + public TileEntity getEntity(){ + return new ItemGeneratorEntity(); + } + + /** + * Returns an efficiency value for the specified liquid. + * Greater efficiency means more power generation. + * If a liquid's efficiency is below {@link #minEfficiency}, it is not accepted. + */ + protected abstract float getEfficiency(Liquid liquid); } diff --git a/core/src/io/anuke/mindustry/world/blocks/power/LiquidHeatGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/LiquidHeatGenerator.java index d591bea4f9..3990a6c731 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/LiquidHeatGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/LiquidHeatGenerator.java @@ -2,14 +2,14 @@ package io.anuke.mindustry.world.blocks.power; import io.anuke.mindustry.type.Liquid; -public class LiquidHeatGenerator extends LiquidGenerator { +public class LiquidHeatGenerator extends LiquidGenerator{ - public LiquidHeatGenerator(String name) { + public LiquidHeatGenerator(String name){ super(name); } @Override protected float getEfficiency(Liquid liquid){ - return liquid.temperature-0.5f; + return liquid.temperature - 0.5f; } } diff --git a/core/src/io/anuke/mindustry/world/blocks/power/NuclearReactor.java b/core/src/io/anuke/mindustry/world/blocks/power/NuclearReactor.java index dae8e33dae..9759b2e63e 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/NuclearReactor.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/NuclearReactor.java @@ -27,192 +27,192 @@ import java.io.IOException; import static io.anuke.mindustry.Vars.tilesize; //TODO refactor to use consumers -public class NuclearReactor extends PowerGenerator { - protected final int timerFuel = timers++; +public class NuclearReactor extends PowerGenerator{ + protected final int timerFuel = timers++; - protected final Translator tr = new Translator(); + protected final Translator tr = new Translator(); - protected Color coolColor = new Color(1, 1, 1, 0f); - protected Color hotColor = Color.valueOf("ff9575a3"); - protected int fuelUseTime = 120; //time to consume 1 fuel - protected float powerMultiplier = 0.45f; //power per frame, depends on full capacity - protected float heating = 0.013f; //heating per frame - protected float coolantPower = 0.015f; //how much heat decreases per coolant unit - protected float smokeThreshold = 0.3f; //threshold at which block starts smoking - protected float maxLiquidUse = 2f; //max liquid use per frame - protected int explosionRadius = 19; - protected int explosionDamage = 135; - protected float flashThreshold = 0.46f; //heat threshold at which the lights start flashing + protected Color coolColor = new Color(1, 1, 1, 0f); + protected Color hotColor = Color.valueOf("ff9575a3"); + protected int fuelUseTime = 120; //time to consume 1 fuel + protected float powerMultiplier = 0.45f; //power per frame, depends on full capacity + protected float heating = 0.013f; //heating per frame + protected float coolantPower = 0.015f; //how much heat decreases per coolant unit + protected float smokeThreshold = 0.3f; //threshold at which block starts smoking + protected float maxLiquidUse = 2f; //max liquid use per frame + protected int explosionRadius = 19; + protected int explosionDamage = 135; + protected float flashThreshold = 0.46f; //heat threshold at which the lights start flashing - protected TextureRegion topRegion, lightsRegion; + protected TextureRegion topRegion, lightsRegion; - public NuclearReactor(String name) { - super(name); - itemCapacity = 30; - liquidCapacity = 50; - powerCapacity = 80f; - hasItems = true; - hasLiquids = true; + public NuclearReactor(String name){ + super(name); + itemCapacity = 30; + liquidCapacity = 50; + powerCapacity = 80f; + hasItems = true; + hasLiquids = true; - consumes.item(Items.thorium); - } + consumes.item(Items.thorium); + } - @Override - public void load() { - super.load(); + @Override + public void load(){ + super.load(); - topRegion = Draw.region(name + "-center"); - lightsRegion = Draw.region(name + "-lights"); - } + topRegion = Draw.region(name + "-center"); + lightsRegion = Draw.region(name + "-lights"); + } - @Override - public void setBars(){ - super.setBars(); - bars.replace(new BlockBar(BarType.inventory, true, tile -> (float)tile.entity.items.get(consumes.item()) / itemCapacity)); - bars.add(new BlockBar(BarType.heat, true, tile -> tile.entity().heat)); - } + @Override + public void setBars(){ + super.setBars(); + bars.replace(new BlockBar(BarType.inventory, true, tile -> (float) tile.entity.items.get(consumes.item()) / itemCapacity)); + bars.add(new BlockBar(BarType.heat, true, tile -> tile.entity().heat)); + } - @Override - public void setStats(){ - super.setStats(); - stats.add(BlockStat.inputLiquid, new LiquidFilterValue(liquid -> liquid.temperature <= 0.5f)); - stats.add(BlockStat.maxPowerGeneration, powerMultiplier*60f, StatUnit.powerSecond); - } - - @Override - public void update(Tile tile){ - NuclearReactorEntity entity = tile.entity(); - - int fuel = entity.items.get(consumes.item()); - float fullness = (float)fuel / itemCapacity; - - if(fuel > 0){ - entity.heat += fullness * heating * Math.min(Timers.delta(), 4f); - entity.power.amount += powerMultiplier * fullness * Timers.delta(); - entity.power.amount = Mathf.clamp(entity.power.amount, 0f, powerCapacity); - if(entity.timer.get(timerFuel, fuelUseTime)){ - entity.items.remove(consumes.item(), 1); - } - } - - if(entity.liquids.total() > 0){ - Liquid liquid = entity.liquids.current(); + @Override + public void setStats(){ + super.setStats(); + stats.add(BlockStat.inputLiquid, new LiquidFilterValue(liquid -> liquid.temperature <= 0.5f)); + stats.add(BlockStat.maxPowerGeneration, powerMultiplier * 60f, StatUnit.powerSecond); + } - if(liquid.temperature <= 0.5f){ //is coolant - float pow = coolantPower * (liquid.heatCapacity + 0.5f/liquid.temperature); //heat depleted per unit of liquid - float maxUsed = Math.min(Math.min(entity.liquids.get(liquid), entity.heat / pow), maxLiquidUse * Timers.delta()); //max that can be cooled in terms of liquid - entity.heat -= maxUsed * pow; - entity.liquids.remove(liquid, maxUsed); - }else{ //is heater - float heat = coolantPower * liquid.heatCapacity / 4f; //heat created per unit of liquid - float maxUsed = Math.min(Math.min(entity.liquids.get(liquid), (1f - entity.heat) / heat), maxLiquidUse * Timers.delta()); //max liquid used - entity.heat += maxUsed * heat; - entity.liquids.remove(liquid, maxUsed); - } - } - - if(entity.heat > smokeThreshold){ - float smoke = 1.0f + (entity.heat - smokeThreshold) / (1f - smokeThreshold); //ranges from 1.0 to 2.0 - if(Mathf.chance(smoke / 20.0 * Timers.delta())){ - Effects.effect(BlockFx.reactorsmoke, tile.worldx() + Mathf.range(size * tilesize / 2f), - tile.worldy() + Mathf.random(size * tilesize / 2f)); - } - } + @Override + public void update(Tile tile){ + NuclearReactorEntity entity = tile.entity(); - entity.heat = Mathf.clamp(entity.heat); - - if(entity.heat >= 1f){ - entity.damage((int)entity.health); - }else{ - distributePower(tile); - } - } - - @Override - public void onDestroyed(Tile tile){ - super.onDestroyed(tile); - - NuclearReactorEntity entity = tile.entity(); - - int fuel = entity.items.get(consumes.item()); - - if(fuel < 5 && entity.heat < 0.5f) return; - - Effects.shake(6f, 16f, tile.worldx(), tile.worldy()); - Effects.effect(ExplosionFx.nuclearShockwave, tile.worldx(), tile.worldy()); - for(int i = 0; i < 6; i ++){ - Timers.run(Mathf.random(40), () -> { - Effects.effect(BlockFx.nuclearcloud, tile.worldx(), tile.worldy()); - }); - } - - Damage.damage(tile.worldx(), tile.worldy(), explosionRadius * tilesize, explosionDamage * 4); - - - for(int i = 0; i < 20; i ++){ - Timers.run(Mathf.random(50), ()->{ - tr.rnd(Mathf.random(40f)); - Effects.effect(ExplosionFx.explosion, tr.x + tile.worldx(), tr.y + tile.worldy()); - }); - } - - for(int i = 0; i < 70; i ++){ - Timers.run(Mathf.random(80), ()->{ - tr.rnd(Mathf.random(120f)); - Effects.effect(BlockFx.nuclearsmoke, tr.x + tile.worldx(), tr.y + tile.worldy()); - }); - } - } + int fuel = entity.items.get(consumes.item()); + float fullness = (float) fuel / itemCapacity; - @Override - public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){ - return tile.entity.liquids.get(liquid) + amount < liquidCapacity && liquid.temperature <= 0.5f && - (tile.entity.liquids.current() == liquid || tile.entity.liquids.get(tile.entity.liquids.current()) < 0.01f); - } + if(fuel > 0){ + entity.heat += fullness * heating * Math.min(Timers.delta(), 4f); + entity.power.amount += powerMultiplier * fullness * Timers.delta(); + entity.power.amount = Mathf.clamp(entity.power.amount, 0f, powerCapacity); + if(entity.timer.get(timerFuel, fuelUseTime)){ + entity.items.remove(consumes.item(), 1); + } + } - @Override - public void draw(Tile tile){ - super.draw(tile); - - NuclearReactorEntity entity = tile.entity(); - - Draw.color(coolColor, hotColor, entity.heat); - Draw.rect("white", tile.drawx(), tile.drawy(), size * tilesize, size * tilesize); + if(entity.liquids.total() > 0){ + Liquid liquid = entity.liquids.current(); - Draw.color(entity.liquids.current().color); - Draw.alpha(entity.liquids.currentAmount() / liquidCapacity); - Draw.rect(topRegion, tile.drawx(), tile.drawy()); - - if(entity.heat > flashThreshold){ - float flash = 1f + ((entity.heat - flashThreshold) / (1f - flashThreshold)) * 5.4f; - entity.flash += flash * Timers.delta(); - Draw.color(Color.RED, Color.YELLOW, Mathf.absin(entity.flash, 9f, 1f)); - Draw.alpha(0.6f); - Draw.rect(lightsRegion, tile.drawx(), tile.drawy()); - } - - Draw.reset(); - } - - @Override - public TileEntity getEntity(){ - return new NuclearReactorEntity(); - } - - public static class NuclearReactorEntity extends GeneratorEntity { - public float heat; - public float flash; - - @Override - public void write(DataOutputStream stream) throws IOException{ - super.write(stream); - stream.writeFloat(heat); - } - - @Override - public void read(DataInputStream stream) throws IOException{ - super.read(stream); - heat = stream.readFloat(); - } - } + if(liquid.temperature <= 0.5f){ //is coolant + float pow = coolantPower * (liquid.heatCapacity + 0.5f / liquid.temperature); //heat depleted per unit of liquid + float maxUsed = Math.min(Math.min(entity.liquids.get(liquid), entity.heat / pow), maxLiquidUse * Timers.delta()); //max that can be cooled in terms of liquid + entity.heat -= maxUsed * pow; + entity.liquids.remove(liquid, maxUsed); + }else{ //is heater + float heat = coolantPower * liquid.heatCapacity / 4f; //heat created per unit of liquid + float maxUsed = Math.min(Math.min(entity.liquids.get(liquid), (1f - entity.heat) / heat), maxLiquidUse * Timers.delta()); //max liquid used + entity.heat += maxUsed * heat; + entity.liquids.remove(liquid, maxUsed); + } + } + + if(entity.heat > smokeThreshold){ + float smoke = 1.0f + (entity.heat - smokeThreshold) / (1f - smokeThreshold); //ranges from 1.0 to 2.0 + if(Mathf.chance(smoke / 20.0 * Timers.delta())){ + Effects.effect(BlockFx.reactorsmoke, tile.worldx() + Mathf.range(size * tilesize / 2f), + tile.worldy() + Mathf.random(size * tilesize / 2f)); + } + } + + entity.heat = Mathf.clamp(entity.heat); + + if(entity.heat >= 1f){ + entity.damage((int) entity.health); + }else{ + distributePower(tile); + } + } + + @Override + public void onDestroyed(Tile tile){ + super.onDestroyed(tile); + + NuclearReactorEntity entity = tile.entity(); + + int fuel = entity.items.get(consumes.item()); + + if(fuel < 5 && entity.heat < 0.5f) return; + + Effects.shake(6f, 16f, tile.worldx(), tile.worldy()); + Effects.effect(ExplosionFx.nuclearShockwave, tile.worldx(), tile.worldy()); + for(int i = 0; i < 6; i++){ + Timers.run(Mathf.random(40), () -> { + Effects.effect(BlockFx.nuclearcloud, tile.worldx(), tile.worldy()); + }); + } + + Damage.damage(tile.worldx(), tile.worldy(), explosionRadius * tilesize, explosionDamage * 4); + + + for(int i = 0; i < 20; i++){ + Timers.run(Mathf.random(50), () -> { + tr.rnd(Mathf.random(40f)); + Effects.effect(ExplosionFx.explosion, tr.x + tile.worldx(), tr.y + tile.worldy()); + }); + } + + for(int i = 0; i < 70; i++){ + Timers.run(Mathf.random(80), () -> { + tr.rnd(Mathf.random(120f)); + Effects.effect(BlockFx.nuclearsmoke, tr.x + tile.worldx(), tr.y + tile.worldy()); + }); + } + } + + @Override + public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){ + return tile.entity.liquids.get(liquid) + amount < liquidCapacity && liquid.temperature <= 0.5f && + (tile.entity.liquids.current() == liquid || tile.entity.liquids.get(tile.entity.liquids.current()) < 0.01f); + } + + @Override + public void draw(Tile tile){ + super.draw(tile); + + NuclearReactorEntity entity = tile.entity(); + + Draw.color(coolColor, hotColor, entity.heat); + Draw.rect("white", tile.drawx(), tile.drawy(), size * tilesize, size * tilesize); + + Draw.color(entity.liquids.current().color); + Draw.alpha(entity.liquids.currentAmount() / liquidCapacity); + Draw.rect(topRegion, tile.drawx(), tile.drawy()); + + if(entity.heat > flashThreshold){ + float flash = 1f + ((entity.heat - flashThreshold) / (1f - flashThreshold)) * 5.4f; + entity.flash += flash * Timers.delta(); + Draw.color(Color.RED, Color.YELLOW, Mathf.absin(entity.flash, 9f, 1f)); + Draw.alpha(0.6f); + Draw.rect(lightsRegion, tile.drawx(), tile.drawy()); + } + + Draw.reset(); + } + + @Override + public TileEntity getEntity(){ + return new NuclearReactorEntity(); + } + + public static class NuclearReactorEntity extends GeneratorEntity{ + public float heat; + public float flash; + + @Override + public void write(DataOutputStream stream) throws IOException{ + super.write(stream); + stream.writeFloat(heat); + } + + @Override + public void read(DataInputStream stream) throws IOException{ + super.read(stream); + heat = stream.readFloat(); + } + } } diff --git a/core/src/io/anuke/mindustry/world/blocks/power/PowerDistributor.java b/core/src/io/anuke/mindustry/world/blocks/power/PowerDistributor.java index bb2a5ac1f8..991bd165d2 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/PowerDistributor.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/PowerDistributor.java @@ -7,9 +7,9 @@ import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.PowerBlock; import io.anuke.ucore.core.Timers; -public class PowerDistributor extends PowerBlock { +public class PowerDistributor extends PowerBlock{ - public PowerDistributor(String name) { + public PowerDistributor(String name){ super(name); } @@ -26,7 +26,7 @@ public class PowerDistributor extends PowerBlock { for(GridPoint2 point : Edges.getEdges(size)){ Tile target = tile.getNearby(point); if(target != null && target.block().hasPower && - shouldDistribute(tile, target)) sources ++; + shouldDistribute(tile, target)) sources++; } if(sources == 0) return; @@ -39,7 +39,7 @@ public class PowerDistributor extends PowerBlock { target = target.target(); if(target.block().hasPower && shouldDistribute(tile, target)){ - float diff = (tile.entity.power.amount / powerCapacity - target.entity.power.amount / target.block().powerCapacity)/1.4f; + float diff = (tile.entity.power.amount / powerCapacity - target.entity.power.amount / target.block().powerCapacity) / 1.4f; float transmit = Math.min(result * Timers.delta(), diff * powerCapacity); if(target.block().acceptPower(target, tile, transmit)){ @@ -50,7 +50,7 @@ public class PowerDistributor extends PowerBlock { } } - protected boolean shouldDistribute(Tile tile, Tile other) { + protected boolean shouldDistribute(Tile tile, Tile other){ other = other.target(); //only generators can distribute to other generators return (!(other.block() instanceof PowerGenerator) || tile.block() instanceof PowerGenerator) @@ -60,7 +60,7 @@ public class PowerDistributor extends PowerBlock { } @Override - public void update(Tile tile) { + public void update(Tile tile){ distributePower(tile); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/power/PowerGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/PowerGenerator.java index 03a8cbf43a..5fac88bc26 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/PowerGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/PowerGenerator.java @@ -4,16 +4,16 @@ import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.world.meta.BlockFlag; import io.anuke.ucore.util.EnumSet; -public class PowerGenerator extends PowerDistributor { +public class PowerGenerator extends PowerDistributor{ - public PowerGenerator(String name) { + public PowerGenerator(String name){ super(name); baseExplosiveness = 5f; flags = EnumSet.of(BlockFlag.producer); } @Override - public TileEntity getEntity() { + public TileEntity getEntity(){ return new GeneratorEntity(); } diff --git a/core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java b/core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java index 84b3769fdd..b2a7646e40 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java @@ -31,290 +31,291 @@ import java.io.IOException; import static io.anuke.mindustry.Vars.*; public class PowerNode extends PowerBlock{ - public static final float thicknessScl = 0.7f; + public static final float thicknessScl = 0.7f; public static final float flashScl = 0.12f; - //last distribution block placed - private static int lastPlaced = -1; + //last distribution block placed + private static int lastPlaced = -1; - protected Translator t1 = new Translator(); - protected Translator t2 = new Translator(); + protected Translator t1 = new Translator(); + protected Translator t2 = new Translator(); - protected float laserRange = 6; - protected float powerSpeed = 0.5f; - protected int maxNodes = 3; + protected float laserRange = 6; + protected float powerSpeed = 0.5f; + protected int maxNodes = 3; - public PowerNode(String name){ - super(name); - expanded = true; - layer = Layer.power; - powerCapacity = 5f; - configurable = true; - } + public PowerNode(String name){ + super(name); + expanded = true; + layer = Layer.power; + powerCapacity = 5f; + configurable = true; + } - @Override - public void setBars(){} + @Remote(targets = Loc.both, called = Loc.server, in = In.blocks, forward = true) + public static void linkPowerDistributors(Player player, Tile tile, Tile other){ - @Override - public void placed(Tile tile) { - Tile before = world.tile(lastPlaced); - if(linkValid(tile, before) && before.block() instanceof PowerNode){ - CallBlocks.linkPowerDistributors(null, tile, before); - } + DistributorEntity entity = tile.entity(); - lastPlaced = tile.packedPosition(); - } + if(!entity.links.contains(other.packedPosition())){ + entity.links.add(other.packedPosition()); + } - @Override - public void setStats(){ - super.setStats(); + if(other.block() instanceof PowerNode){ + DistributorEntity oe = other.entity(); - stats.add(BlockStat.powerRange, laserRange, StatUnit.blocks); - stats.add(BlockStat.powerTransferSpeed, powerSpeed * 60 / 2f, StatUnit.powerSecond); //divided by 2 since passback exists - } + if(!oe.links.contains(tile.packedPosition())){ + oe.links.add(tile.packedPosition()); + } + } + } - @Override - public void update(Tile tile){ + @Remote(targets = Loc.both, called = Loc.server, in = In.blocks, forward = true) + public static void unlinkPowerDistributors(Player player, Tile tile, Tile other){ + DistributorEntity entity = tile.entity(); + + entity.links.removeValue(other.packedPosition()); + + if(other.block() instanceof PowerNode){ + DistributorEntity oe = other.entity(); + + oe.links.removeValue(tile.packedPosition()); + } + } + + @Override + public void setBars(){ + } + + @Override + public void placed(Tile tile){ + Tile before = world.tile(lastPlaced); + if(linkValid(tile, before) && before.block() instanceof PowerNode){ + CallBlocks.linkPowerDistributors(null, tile, before); + } + + lastPlaced = tile.packedPosition(); + } + + @Override + public void setStats(){ + super.setStats(); + + stats.add(BlockStat.powerRange, laserRange, StatUnit.blocks); + stats.add(BlockStat.powerTransferSpeed, powerSpeed * 60 / 2f, StatUnit.powerSecond); //divided by 2 since passback exists + } + + @Override + public void update(Tile tile){ distributeLaserPower(tile); } @Override public boolean onConfigureTileTapped(Tile tile, Tile other){ - DistributorEntity entity = tile.entity(); - other = other.target(); + DistributorEntity entity = tile.entity(); + other = other.target(); - Tile result = other; + Tile result = other; - if(linkValid(tile, other)){ - if(linked(tile, other)){ - threads.run(() -> CallBlocks.unlinkPowerDistributors(null, tile, result)); - }else if(entity.links.size < maxNodes){ - threads.run(() -> CallBlocks.linkPowerDistributors(null, tile, result)); - } - return false; - } - return true; - } + if(linkValid(tile, other)){ + if(linked(tile, other)){ + threads.run(() -> CallBlocks.unlinkPowerDistributors(null, tile, result)); + }else if(entity.links.size < maxNodes){ + threads.run(() -> CallBlocks.linkPowerDistributors(null, tile, result)); + } + return false; + } + return true; + } - @Override - public void drawSelect(Tile tile){ - super.drawSelect(tile); + @Override + public void drawSelect(Tile tile){ + super.drawSelect(tile); Draw.color(Palette.power); Lines.stroke(1f); - Lines.poly(Edges.getPixelPolygon(laserRange), tile.worldx() - tilesize/2, tile.worldy() - tilesize/2, tilesize); + Lines.poly(Edges.getPixelPolygon(laserRange), tile.worldx() - tilesize / 2, tile.worldy() - tilesize / 2, tilesize); Draw.reset(); - } + } - @Override - public void drawConfigure(Tile tile){ - DistributorEntity entity = tile.entity(); + @Override + public void drawConfigure(Tile tile){ + DistributorEntity entity = tile.entity(); - Draw.color(Palette.accent); + Draw.color(Palette.accent); - Lines.stroke(1f); - Lines.square(tile.drawx(), tile.drawy(), - tile.block().size * tilesize / 2f + 1f + Mathf.absin(Timers.time(), 4f, 1f)); + Lines.stroke(1f); + Lines.square(tile.drawx(), tile.drawy(), + tile.block().size * tilesize / 2f + 1f + Mathf.absin(Timers.time(), 4f, 1f)); - Lines.stroke(1f); + Lines.stroke(1f); - Lines.poly(Edges.getPixelPolygon(laserRange), tile.worldx() - tilesize/2, tile.worldy() - tilesize/2, tilesize); + Lines.poly(Edges.getPixelPolygon(laserRange), tile.worldx() - tilesize / 2, tile.worldy() - tilesize / 2, tilesize); - Draw.color(Palette.power); + Draw.color(Palette.power); - for(int x = (int)(tile.x - laserRange); x <= tile.x + laserRange; x ++){ - for(int y = (int)(tile.y - laserRange); y <= tile.y + laserRange; y ++){ - Tile link = world.tile(x, y); - if(link != null) link = link.target(); + for(int x = (int) (tile.x - laserRange); x <= tile.x + laserRange; x++){ + for(int y = (int) (tile.y - laserRange); y <= tile.y + laserRange; y++){ + Tile link = world.tile(x, y); + if(link != null) link = link.target(); - if(link != tile && linkValid(tile, link, false)){ - boolean linked = linked(tile, link); - Draw.color(linked ? Palette.place : Palette.breakInvalid); + if(link != tile && linkValid(tile, link, false)){ + boolean linked = linked(tile, link); + Draw.color(linked ? Palette.place : Palette.breakInvalid); - Lines.square(link.drawx(), link.drawy(), - link.block().size * tilesize / 2f + 1f + (linked ? 0f : Mathf.absin(Timers.time(), 4f, 1f))); + Lines.square(link.drawx(), link.drawy(), + link.block().size * tilesize / 2f + 1f + (linked ? 0f : Mathf.absin(Timers.time(), 4f, 1f))); - if((entity.links.size >= maxNodes || (link.block() instanceof PowerNode && ((DistributorEntity)link.entity).links.size >= ((PowerNode)link.block()).maxNodes)) && !linked){ - Draw.color(); - Draw.rect("cross-" + link.block().size, link.drawx(), link.drawy()); - } - } - } - } + if((entity.links.size >= maxNodes || (link.block() instanceof PowerNode && ((DistributorEntity) link.entity).links.size >= ((PowerNode) link.block()).maxNodes)) && !linked){ + Draw.color(); + Draw.rect("cross-" + link.block().size, link.drawx(), link.drawy()); + } + } + } + } - Draw.reset(); - } + Draw.reset(); + } - @Override - public void drawPlace(int x, int y, int rotation, boolean valid){ + @Override + public void drawPlace(int x, int y, int rotation, boolean valid){ Draw.color(Palette.placing); Lines.stroke(1f); - Lines.poly(Edges.getPixelPolygon(laserRange), x * tilesize - tilesize/2, y * tilesize - tilesize/2, tilesize); + Lines.poly(Edges.getPixelPolygon(laserRange), x * tilesize - tilesize / 2, y * tilesize - tilesize / 2, tilesize); Draw.reset(); - } + } - @Override - public void drawLayer(Tile tile){ - if(!Settings.getBool("lasers")) return; + @Override + public void drawLayer(Tile tile){ + if(!Settings.getBool("lasers")) return; - DistributorEntity entity = tile.entity(); + DistributorEntity entity = tile.entity(); - entity.laserColor = Mathf.lerpDelta(entity.laserColor, Mathf.clamp(entity.powerRecieved/(powerSpeed)), 0.08f); + entity.laserColor = Mathf.lerpDelta(entity.laserColor, Mathf.clamp(entity.powerRecieved / (powerSpeed)), 0.08f); - Draw.color(Palette.powerLaserFrom, Palette.powerLaserTo, entity.laserColor * (1f-flashScl) + Mathf.sin(Timers.time(), 1.7f, flashScl)); + Draw.color(Palette.powerLaserFrom, Palette.powerLaserTo, entity.laserColor * (1f - flashScl) + Mathf.sin(Timers.time(), 1.7f, flashScl)); - for(int i = 0; i < entity.links.size; i ++){ - Tile link = world.tile(entity.links.get(i)); - if(linkValid(tile, link)) drawLaser(tile, link); + for(int i = 0; i < entity.links.size; i++){ + Tile link = world.tile(entity.links.get(i)); + if(linkValid(tile, link)) drawLaser(tile, link); } - Draw.color(); - } + Draw.color(); + } - @Override - public float addPower(Tile tile, float amount){ - DistributorEntity entity = tile.entity(); + @Override + public float addPower(Tile tile, float amount){ + DistributorEntity entity = tile.entity(); - if(entity.lastRecieved != threads.getFrameID()){ - entity.lastRecieved = threads.getFrameID(); - entity.powerRecieved = 0f; - } + if(entity.lastRecieved != threads.getFrameID()){ + entity.lastRecieved = threads.getFrameID(); + entity.powerRecieved = 0f; + } - float canAccept = Math.min(powerCapacity * Timers.delta() - tile.entity.power.amount, amount); + float canAccept = Math.min(powerCapacity * Timers.delta() - tile.entity.power.amount, amount); - tile.entity.power.amount += canAccept; - entity.powerRecieved += canAccept; + tile.entity.power.amount += canAccept; + entity.powerRecieved += canAccept; - return canAccept; - } + return canAccept; + } - protected boolean shouldDistribute(Tile tile, Tile other) { - return other.entity.power.amount / other.block().powerCapacity <= tile.entity.power.amount / powerCapacity && - !(other.block() instanceof PowerGenerator); //do not distribute to power generators - } + protected boolean shouldDistribute(Tile tile, Tile other){ + return other.entity.power.amount / other.block().powerCapacity <= tile.entity.power.amount / powerCapacity && + !(other.block() instanceof PowerGenerator); //do not distribute to power generators + } - protected boolean shouldLeechPower(Tile tile, Tile other){ - return !(other.block() instanceof PowerNode) - && other.block() instanceof PowerDistributor //only suck power from batteries and power generators - && other.entity.power.amount / other.block().powerCapacity > tile.entity.power.amount / powerCapacity; - } + protected boolean shouldLeechPower(Tile tile, Tile other){ + return !(other.block() instanceof PowerNode) + && other.block() instanceof PowerDistributor //only suck power from batteries and power generators + && other.entity.power.amount / other.block().powerCapacity > tile.entity.power.amount / powerCapacity; + } - protected void distributeLaserPower(Tile tile){ - DistributorEntity entity = tile.entity(); + protected void distributeLaserPower(Tile tile){ + DistributorEntity entity = tile.entity(); - if(Float.isNaN(entity.power.amount)){ - entity.power.amount = 0f; - } + if(Float.isNaN(entity.power.amount)){ + entity.power.amount = 0f; + } - int targets = 0; + int targets = 0; - //validate everything first. - for(int i = 0; i < entity.links.size; i ++){ - Tile target = world.tile(entity.links.get(i)); - if(!linkValid(tile, target)) { - entity.links.removeIndex(i); - i --; - }else if(shouldDistribute(tile, target)) { - targets++; - } - } + //validate everything first. + for(int i = 0; i < entity.links.size; i++){ + Tile target = world.tile(entity.links.get(i)); + if(!linkValid(tile, target)){ + entity.links.removeIndex(i); + i--; + }else if(shouldDistribute(tile, target)){ + targets++; + } + } - float result = Math.min(entity.power.amount / targets, powerSpeed * Timers.delta()); + float result = Math.min(entity.power.amount / targets, powerSpeed * Timers.delta()); - for(int i = 0; i < entity.links.size; i ++){ - Tile target = world.tile(entity.links.get(i)); - if(shouldDistribute(tile, target)) { + for(int i = 0; i < entity.links.size; i++){ + Tile target = world.tile(entity.links.get(i)); + if(shouldDistribute(tile, target)){ - float transmit = Math.min(result, entity.power.amount); - if (target.block().acceptPower(target, tile, transmit)) { - entity.power.amount -= target.block().addPower(target, transmit); - } - }else if(shouldLeechPower(tile, target)){ - float diff = (target.entity.power.amount / target.block().powerCapacity - tile.entity.power.amount / powerCapacity)/1.4f; - float transmit = Math.min(Math.min(target.block().powerCapacity * diff, target.entity.power.amount), powerCapacity - tile.entity.power.amount); - entity.power.amount += transmit; - target.entity.power.amount -= transmit; - } - } - } + float transmit = Math.min(result, entity.power.amount); + if(target.block().acceptPower(target, tile, transmit)){ + entity.power.amount -= target.block().addPower(target, transmit); + } + }else if(shouldLeechPower(tile, target)){ + float diff = (target.entity.power.amount / target.block().powerCapacity - tile.entity.power.amount / powerCapacity) / 1.4f; + float transmit = Math.min(Math.min(target.block().powerCapacity * diff, target.entity.power.amount), powerCapacity - tile.entity.power.amount); + entity.power.amount += transmit; + target.entity.power.amount -= transmit; + } + } + } - protected boolean linked(Tile tile, Tile other){ - return tile.entity().links.contains(other.packedPosition()); - } + protected boolean linked(Tile tile, Tile other){ + return tile.entity().links.contains(other.packedPosition()); + } - protected boolean linkValid(Tile tile, Tile link){ - return linkValid(tile, link, true); - } + protected boolean linkValid(Tile tile, Tile link){ + return linkValid(tile, link, true); + } - protected boolean linkValid(Tile tile, Tile link, boolean checkMaxNodes){ - if(!(tile != link && link != null && link.block().hasPower)) return false; + protected boolean linkValid(Tile tile, Tile link, boolean checkMaxNodes){ + if(!(tile != link && link != null && link.block().hasPower)) return false; - if(link.block() instanceof PowerNode){ - DistributorEntity oe = link.entity(); + if(link.block() instanceof PowerNode){ + DistributorEntity oe = link.entity(); - return Vector2.dst(tile.drawx(), tile.drawy(), link.drawx(), link.drawy()) <= Math.max(laserRange * tilesize, - ((PowerNode)link.block()).laserRange * tilesize) - tilesize/2f - + (link.block().size-1)*tilesize/2f + (tile.block().size-1)*tilesize/2f && - (!checkMaxNodes || (oe.links.size < ((PowerNode)link.block()).maxNodes || oe.links.contains(tile.packedPosition()))); - }else{ - return Vector2.dst(tile.drawx(), tile.drawy(), link.drawx(), link.drawy()) - <= laserRange * tilesize - tilesize/2f + (link.block().size-1)*tilesize; - } - } + return Vector2.dst(tile.drawx(), tile.drawy(), link.drawx(), link.drawy()) <= Math.max(laserRange * tilesize, + ((PowerNode) link.block()).laserRange * tilesize) - tilesize / 2f + + (link.block().size - 1) * tilesize / 2f + (tile.block().size - 1) * tilesize / 2f && + (!checkMaxNodes || (oe.links.size < ((PowerNode) link.block()).maxNodes || oe.links.contains(tile.packedPosition()))); + }else{ + return Vector2.dst(tile.drawx(), tile.drawy(), link.drawx(), link.drawy()) + <= laserRange * tilesize - tilesize / 2f + (link.block().size - 1) * tilesize; + } + } - protected void drawLaser(Tile tile, Tile target){ + protected void drawLaser(Tile tile, Tile target){ float x1 = tile.drawx(), y1 = tile.drawy(), x2 = target.drawx(), y2 = target.drawy(); float angle1 = Angles.angle(x1, y1, x2, y2); float angle2 = angle1 + 180f; - t1.trns(angle1, tile.block().size * tilesize/2f + 1f); - t2.trns(angle2, target.block().size * tilesize/2f + 1f); + t1.trns(angle1, tile.block().size * tilesize / 2f + 1f); + t2.trns(angle2, target.block().size * tilesize / 2f + 1f); Shapes.laser("laser", "laser-end", x1 + t1.x, y1 + t1.y, x2 + t2.x, y2 + t2.y, thicknessScl); - } - - @Override - public TileEntity getEntity() { - return new DistributorEntity(); } - @Remote(targets = Loc.both, called = Loc.server, in = In.blocks, forward = true) - public static void linkPowerDistributors(Player player, Tile tile, Tile other){ - - DistributorEntity entity = tile.entity(); - - if(!entity.links.contains(other.packedPosition())){ - entity.links.add(other.packedPosition()); - } - - if(other.block() instanceof PowerNode){ - DistributorEntity oe = other.entity(); - - if(!oe.links.contains(tile.packedPosition()) ){ - oe.links.add(tile.packedPosition()); - } - } - } - - @Remote(targets = Loc.both, called = Loc.server, in = In.blocks, forward = true) - public static void unlinkPowerDistributors(Player player, Tile tile, Tile other){ - DistributorEntity entity = tile.entity(); - - entity.links.removeValue(other.packedPosition()); - - if(other.block() instanceof PowerNode){ - DistributorEntity oe = other.entity(); - - oe.links.removeValue(tile.packedPosition()); - } - } + @Override + public TileEntity getEntity(){ + return new DistributorEntity(); + } public static class DistributorEntity extends TileEntity{ public float laserColor = 0f; @@ -322,21 +323,21 @@ public class PowerNode extends PowerBlock{ public long lastRecieved = 0; public IntArray links = new IntArray(); - @Override - public void write(DataOutputStream stream) throws IOException { - stream.writeShort(links.size); - for(int i = 0; i < links.size; i ++){ - stream.writeInt(links.get(i)); - } - } + @Override + public void write(DataOutputStream stream) throws IOException{ + stream.writeShort(links.size); + for(int i = 0; i < links.size; i++){ + stream.writeInt(links.get(i)); + } + } - @Override - public void read(DataInputStream stream) throws IOException { - short amount = stream.readShort(); - for(int i = 0; i < amount; i ++){ - links.add(stream.readInt()); - } - } - } + @Override + public void read(DataInputStream stream) throws IOException{ + short amount = stream.readShort(); + for(int i = 0; i < amount; i++){ + links.add(stream.readInt()); + } + } + } } diff --git a/core/src/io/anuke/mindustry/world/blocks/power/SolarGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/SolarGenerator.java index 5dee77caf8..651ea6af5d 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/SolarGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/SolarGenerator.java @@ -5,8 +5,10 @@ import io.anuke.mindustry.world.meta.BlockStat; import io.anuke.mindustry.world.meta.StatUnit; import io.anuke.ucore.core.Timers; -public class SolarGenerator extends PowerGenerator { - /**power generated per frame*/ +public class SolarGenerator extends PowerGenerator{ + /** + * power generated per frame + */ protected float generation = 0.005f; public SolarGenerator(String name){ @@ -14,7 +16,7 @@ public class SolarGenerator extends PowerGenerator { } @Override - public void setStats() { + public void setStats(){ super.setStats(); stats.add(BlockStat.maxPowerGeneration, generation * 60f, StatUnit.powerSecond); diff --git a/core/src/io/anuke/mindustry/world/blocks/power/TurbineGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/TurbineGenerator.java index 99e679557a..7416986d6e 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/TurbineGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/TurbineGenerator.java @@ -5,9 +5,9 @@ import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.consumers.ConsumeLiquid; //TODO -public class TurbineGenerator extends BurnerGenerator { +public class TurbineGenerator extends BurnerGenerator{ - public TurbineGenerator(String name) { + public TurbineGenerator(String name){ super(name); singleLiquid = false; diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Compressor.java b/core/src/io/anuke/mindustry/world/blocks/production/Compressor.java index 4fde97444e..189dfd1456 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Compressor.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Compressor.java @@ -7,30 +7,30 @@ import io.anuke.mindustry.world.blocks.production.GenericCrafter.GenericCrafterE import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.util.Mathf; -public class Compressor extends PowerCrafter { +public class Compressor extends PowerCrafter{ protected TextureRegion liquidRegion, topRegion; protected TextureRegion[] frameRegions; - public Compressor(String name) { + public Compressor(String name){ super(name); hasLiquids = true; } @Override - public void load() { + public void load(){ super.load(); frameRegions = new TextureRegion[3]; - for (int i = 0; i < 3; i++) { + for(int i = 0; i < 3; i++){ frameRegions[i] = Draw.region(name + "-frame" + i); } - + liquidRegion = Draw.region(name + "-liquid"); topRegion = Draw.region(name + "-top"); } @Override - public void draw(Tile tile) { + public void draw(Tile tile){ GenericCrafterEntity entity = tile.entity(); Draw.rect(region, tile.drawx(), tile.drawy()); @@ -42,7 +42,7 @@ public class Compressor extends PowerCrafter { } @Override - public TextureRegion[] getIcon() { + public TextureRegion[] getIcon(){ return new TextureRegion[]{Draw.region(name), Draw.region(name + "-top")}; } } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Cultivator.java b/core/src/io/anuke/mindustry/world/blocks/production/Cultivator.java index c0f473e4cd..507e1256ea 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Cultivator.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Cultivator.java @@ -19,7 +19,7 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; -public class Cultivator extends Drill { +public class Cultivator extends Drill{ protected Color plantColor = Color.valueOf("648b55"); protected Color plantColorLight = Color.valueOf("73a75f"); protected Color bottomColor = Color.valueOf("474747"); @@ -30,23 +30,23 @@ public class Cultivator extends Drill { protected SeedRandom random = new SeedRandom(0); protected float recurrence = 6f; - public Cultivator(String name) { + public Cultivator(String name){ super(name); drillEffect = Fx.none; } @Override - public void setStats() { + public void setStats(){ super.setStats(); stats.remove(BlockStat.drillTier); stats.add(BlockStat.drillTier, table -> { - table.addImage("grass1").size(8*3).padBottom(3).padTop(3); + table.addImage("grass1").size(8 * 3).padBottom(3).padTop(3); }); } @Override - public void load() { + public void load(){ super.load(); middleRegion = Draw.region(name + "-middle"); @@ -54,7 +54,7 @@ public class Cultivator extends Drill { } @Override - public void update(Tile tile) { + public void update(Tile tile){ super.update(tile); CultivatorEntity entity = tile.entity(); @@ -62,7 +62,7 @@ public class Cultivator extends Drill { } @Override - public void draw(Tile tile) { + public void draw(Tile tile){ CultivatorEntity entity = tile.entity(); Draw.rect(region, tile.drawx(), tile.drawy()); @@ -74,14 +74,14 @@ public class Cultivator extends Drill { Draw.color(bottomColor, plantColorLight, entity.warmup); random.setSeed(tile.packedPosition()); - for(int i = 0; i < 12; i ++){ + for(int i = 0; i < 12; i++){ float offset = random.nextFloat() * 999999f; float x = random.range(4f), y = random.range(4f); float life = 1f - (((Timers.time() + offset) / 50f) % recurrence); if(life > 0){ - Lines.stroke(entity.warmup * (life*1f + 0.2f)); - Lines.poly(tile.drawx() + x, tile.drawy() + y, 8, (1f-life) * 3f); + Lines.stroke(entity.warmup * (life * 1f + 0.2f)); + Lines.poly(tile.drawx() + x, tile.drawy() + y, 8, (1f - life) * 3f); } } @@ -90,12 +90,12 @@ public class Cultivator extends Drill { } @Override - public TextureRegion[] getIcon() { - return new TextureRegion[]{Draw.region(name), Draw.region(name + "-top"), }; + public TextureRegion[] getIcon(){ + return new TextureRegion[]{Draw.region(name), Draw.region(name + "-top"),}; } @Override - public TileEntity getEntity() { + public TileEntity getEntity(){ return new CultivatorEntity(); } @@ -105,7 +105,7 @@ public class Cultivator extends Drill { } @Override - public Item getDrop(Tile tile) { + public Item getDrop(Tile tile){ return Items.biomatter; } @@ -113,12 +113,12 @@ public class Cultivator extends Drill { public float warmup; @Override - public void write(DataOutputStream stream) throws IOException { + public void write(DataOutputStream stream) throws IOException{ stream.writeFloat(warmup); } @Override - public void read(DataInputStream stream) throws IOException { + public void read(DataInputStream stream) throws IOException{ warmup = stream.readFloat(); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Drill.java b/core/src/io/anuke/mindustry/world/blocks/production/Drill.java index 999818157b..5d7951a5a4 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Drill.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Drill.java @@ -25,213 +25,231 @@ import static io.anuke.mindustry.Vars.control; import static io.anuke.mindustry.Vars.headless; public class Drill extends Block{ - protected final static float hardnessDrillMultiplier = 50f; - protected final int timerDump = timers++; + protected final static float hardnessDrillMultiplier = 50f; + protected final int timerDump = timers++; - protected final Array drawTiles = new Array<>(); - protected final Array toAdd = new Array<>(); + protected final Array drawTiles = new Array<>(); + protected final Array toAdd = new Array<>(); - /**Maximum tier of blocks this drill can mine.*/ - protected int tier; - /**Base time to drill one ore, in frames.*/ - protected float drillTime = 300; - /**Whether the liquid is required to drill. If false, then it will be used as a speed booster.*/ - protected boolean liquidRequired = false; - /**How many times faster the drill will progress when boosted by liquid.*/ - protected float liquidBoostIntensity = 1.6f; - /**Speed at which the drill speeds up.*/ - protected float warmupSpeed = 0.02f; + /** + * Maximum tier of blocks this drill can mine. + */ + protected int tier; + /** + * Base time to drill one ore, in frames. + */ + protected float drillTime = 300; + /** + * Whether the liquid is required to drill. If false, then it will be used as a speed booster. + */ + protected boolean liquidRequired = false; + /** + * How many times faster the drill will progress when boosted by liquid. + */ + protected float liquidBoostIntensity = 1.6f; + /** + * Speed at which the drill speeds up. + */ + protected float warmupSpeed = 0.02f; - /**Effect played when an item is produced. This is colored.*/ - protected Effect drillEffect = BlockFx.mine; - /**Speed the drill bit rotates at.*/ - protected float rotateSpeed = 2f; - /**Effect randomly played while drilling.*/ - protected Effect updateEffect = BlockFx.pulverizeSmall; - /**Chance the update effect will appear.*/ - protected float updateEffectChance = 0.02f; + /** + * Effect played when an item is produced. This is colored. + */ + protected Effect drillEffect = BlockFx.mine; + /** + * Speed the drill bit rotates at. + */ + protected float rotateSpeed = 2f; + /** + * Effect randomly played while drilling. + */ + protected Effect updateEffect = BlockFx.pulverizeSmall; + /** + * Chance the update effect will appear. + */ + protected float updateEffectChance = 0.02f; - protected boolean drawRim = false; + protected boolean drawRim = false; - protected Color heatColor = Color.valueOf("ff5512"); - protected TextureRegion rimRegion; - protected TextureRegion rotatorRegion; - protected TextureRegion topRegion; + protected Color heatColor = Color.valueOf("ff5512"); + protected TextureRegion rimRegion; + protected TextureRegion rotatorRegion; + protected TextureRegion topRegion; - public Drill(String name) { - super(name); - update = true; - solid = true; - layer = Layer.overlay; - itemCapacity = 5; - group = BlockGroup.drills; - hasLiquids = true; - liquidCapacity = 5f; - hasItems = true; + public Drill(String name){ + super(name); + update = true; + solid = true; + layer = Layer.overlay; + itemCapacity = 5; + group = BlockGroup.drills; + hasLiquids = true; + liquidCapacity = 5f; + hasItems = true; - consumes.add(new ConsumeLiquid(Liquids.water, 0.05f)).optional(true); - } + consumes.add(new ConsumeLiquid(Liquids.water, 0.05f)).optional(true); + } - @Override - public void load() { - super.load(); - rimRegion = Draw.region(name + "-rim"); - rotatorRegion = Draw.region(name + "-rotator"); - topRegion = Draw.region(name + "-top"); - } + @Override + public void load(){ + super.load(); + rimRegion = Draw.region(name + "-rim"); + rotatorRegion = Draw.region(name + "-rotator"); + topRegion = Draw.region(name + "-top"); + } - @Override - public void draw(Tile tile) { - float s = 0.3f; - float ts = 0.6f; + @Override + public void draw(Tile tile){ + float s = 0.3f; + float ts = 0.6f; - DrillEntity entity = tile.entity(); + DrillEntity entity = tile.entity(); - Draw.rect(region, tile.drawx(), tile.drawy()); + Draw.rect(region, tile.drawx(), tile.drawy()); - if(drawRim) { - Graphics.setAdditiveBlending(); - Draw.color(heatColor); - Draw.alpha(entity.warmup * ts * (1f-s + Mathf.absin(Timers.time(), 3f, s))); - Draw.rect(rimRegion, tile.drawx(), tile.drawy()); - Draw.color(); - Graphics.setNormalBlending(); - } + if(drawRim){ + Graphics.setAdditiveBlending(); + Draw.color(heatColor); + Draw.alpha(entity.warmup * ts * (1f - s + Mathf.absin(Timers.time(), 3f, s))); + Draw.rect(rimRegion, tile.drawx(), tile.drawy()); + Draw.color(); + Graphics.setNormalBlending(); + } - Draw.rect(rotatorRegion, tile.drawx(), tile.drawy(), entity.drillTime * rotateSpeed); + Draw.rect(rotatorRegion, tile.drawx(), tile.drawy(), entity.drillTime * rotateSpeed); - Draw.rect(topRegion, tile.drawx(), tile.drawy()); + Draw.rect(topRegion, tile.drawx(), tile.drawy()); - if(!isMultiblock() && isValid(tile)) { - Draw.color(tile.floor().drops.item.color); - Draw.rect("blank", tile.worldx(), tile.worldy(), 2f, 2f); - Draw.color(); - } - } + if(!isMultiblock() && isValid(tile)){ + Draw.color(tile.floor().drops.item.color); + Draw.rect("blank", tile.worldx(), tile.worldy(), 2f, 2f); + Draw.color(); + } + } - @Override - public TextureRegion[] getIcon() { - return new TextureRegion[]{Draw.region(name), Draw.region(name + "-rotator"), Draw.region(name + "-top")}; - } - - @Override - public void setStats(){ - super.setStats(); + @Override + public TextureRegion[] getIcon(){ + return new TextureRegion[]{Draw.region(name), Draw.region(name + "-rotator"), Draw.region(name + "-top")}; + } + + @Override + public void setStats(){ + super.setStats(); stats.add(BlockStat.drillTier, table -> { - Array list = new Array<>(); + Array list = new Array<>(); - for(Item item : Item.all()){ - if(tier >= item.hardness && Draw.hasRegion(item.name + "1")){ - list.add(item); - } - } + for(Item item : Item.all()){ + if(tier >= item.hardness && Draw.hasRegion(item.name + "1")){ + list.add(item); + } + } - for (int i = 0; i < list.size; i++) { - Item item = list.get(i); - table.addImage(item.name + "1").size(8*3).padRight(2).padLeft(2).padTop(3).padBottom(3); - if(i != list.size - 1){ - table.add("/"); - } - } - }); + for(int i = 0; i < list.size; i++){ + Item item = list.get(i); + table.addImage(item.name + "1").size(8 * 3).padRight(2).padLeft(2).padTop(3).padBottom(3); + if(i != list.size - 1){ + table.add("/"); + } + } + }); - stats.add(BlockStat.drillSpeed, 60f/drillTime, StatUnit.itemsSecond); - } - - @Override - public void update(Tile tile){ - toAdd.clear(); + stats.add(BlockStat.drillSpeed, 60f / drillTime, StatUnit.itemsSecond); + } - DrillEntity entity = tile.entity(); + @Override + public void update(Tile tile){ + toAdd.clear(); - float multiplier = 0f; - float totalHardness = 0f; + DrillEntity entity = tile.entity(); - for(Tile other : tile.getLinkedTiles(tempTiles)){ - if(isValid(other)){ - Item drop = getDrop(other); - toAdd.add(drop); - totalHardness += drop.hardness; - multiplier += 1f; - } - } + float multiplier = 0f; + float totalHardness = 0f; - if(entity.timer.get(timerDump, 15)){ - tryDump(tile); - } + for(Tile other : tile.getLinkedTiles(tempTiles)){ + if(isValid(other)){ + Item drop = getDrop(other); + toAdd.add(drop); + totalHardness += drop.hardness; + multiplier += 1f; + } + } - entity.drillTime += entity.warmup * Timers.delta(); + if(entity.timer.get(timerDump, 15)){ + tryDump(tile); + } - if(entity.items.total() < itemCapacity && toAdd.size > 0 && entity.cons.valid()){ + entity.drillTime += entity.warmup * Timers.delta(); - float speed = 1f; + if(entity.items.total() < itemCapacity && toAdd.size > 0 && entity.cons.valid()){ - if(entity.consumed(ConsumeLiquid.class) && !liquidRequired){ - speed = liquidBoostIntensity; - } + float speed = 1f; - entity.warmup = Mathf.lerpDelta(entity.warmup, speed, warmupSpeed); - entity.progress += Timers.delta() * multiplier * speed * entity.warmup; + if(entity.consumed(ConsumeLiquid.class) && !liquidRequired){ + speed = liquidBoostIntensity; + } - if(Mathf.chance(Timers.delta() * updateEffectChance * entity.warmup)) - Effects.effect(updateEffect, entity.x + Mathf.range(size*2f), entity.y + Mathf.range(size*2f)); - }else{ - entity.warmup = Mathf.lerpDelta(entity.warmup, 0f, warmupSpeed); - return; - } + entity.warmup = Mathf.lerpDelta(entity.warmup, speed, warmupSpeed); + entity.progress += Timers.delta() * multiplier * speed * entity.warmup; - if(toAdd.size > 0 && entity.progress >= drillTime + hardnessDrillMultiplier*Math.max(totalHardness, 1f)/multiplier - && tile.entity.items.total() < itemCapacity){ + if(Mathf.chance(Timers.delta() * updateEffectChance * entity.warmup)) + Effects.effect(updateEffect, entity.x + Mathf.range(size * 2f), entity.y + Mathf.range(size * 2f)); + }else{ + entity.warmup = Mathf.lerpDelta(entity.warmup, 0f, warmupSpeed); + return; + } - int index = entity.index % toAdd.size; - offloadNear(tile, toAdd.get(index)); + if(toAdd.size > 0 && entity.progress >= drillTime + hardnessDrillMultiplier * Math.max(totalHardness, 1f) / multiplier + && tile.entity.items.total() < itemCapacity){ - //unlock item content - if(!headless){ - control.database().unlockContent(toAdd.get(index)); - } + int index = entity.index % toAdd.size; + offloadNear(tile, toAdd.get(index)); - entity.index ++; - entity.progress = 0f; + //unlock item content + if(!headless){ + control.database().unlockContent(toAdd.get(index)); + } - Effects.effect(drillEffect, toAdd.get(index).color, - entity.x + Mathf.range(size), entity.y + Mathf.range(size)); - } - } + entity.index++; + entity.progress = 0f; - @Override - public boolean canPlaceOn(Tile tile) { - if(isMultiblock()){ - for(Tile other : tile.getLinkedTilesAs(this, drawTiles)){ - if(isValid(other)){ - return true; - } - } - return false; - }else{ - return isValid(tile); - } - } + Effects.effect(drillEffect, toAdd.get(index).color, + entity.x + Mathf.range(size), entity.y + Mathf.range(size)); + } + } - @Override - public TileEntity getEntity() { - return new DrillEntity(); - } + @Override + public boolean canPlaceOn(Tile tile){ + if(isMultiblock()){ + for(Tile other : tile.getLinkedTilesAs(this, drawTiles)){ + if(isValid(other)){ + return true; + } + } + return false; + }else{ + return isValid(tile); + } + } - public Item getDrop(Tile tile){ - return tile.floor().drops.item; - } + @Override + public TileEntity getEntity(){ + return new DrillEntity(); + } - protected boolean isValid(Tile tile){ - return tile.floor().drops != null && tile.floor().drops.item.hardness <= tier; - } + public Item getDrop(Tile tile){ + return tile.floor().drops.item; + } - public static class DrillEntity extends TileEntity{ - public float progress; - public int index; - public float warmup; - public float drillTime; - } + protected boolean isValid(Tile tile){ + return tile.floor().drops != null && tile.floor().drops.item.hardness <= tier; + } + + public static class DrillEntity extends TileEntity{ + public float progress; + public int index; + public float warmup; + public float drillTime; + } } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Fracker.java b/core/src/io/anuke/mindustry/world/blocks/production/Fracker.java index 25507dcb32..3f3e9675ae 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Fracker.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Fracker.java @@ -8,14 +8,14 @@ import io.anuke.mindustry.world.consumers.ConsumeItem; import io.anuke.ucore.core.Timers; import io.anuke.ucore.graphics.Draw; -public class Fracker extends SolidPump { +public class Fracker extends SolidPump{ protected float itemUseTime = 100f; protected TextureRegion liquidRegion; protected TextureRegion rotatorRegion; protected TextureRegion topRegion; - public Fracker(String name) { + public Fracker(String name){ super(name); hasItems = true; itemCapacity = 20; @@ -25,7 +25,7 @@ public class Fracker extends SolidPump { } @Override - public void load() { + public void load(){ super.load(); liquidRegion = Draw.region(name + "-liquid"); @@ -34,18 +34,18 @@ public class Fracker extends SolidPump { } @Override - public void setStats() { + public void setStats(){ super.setStats(); } @Override - public void draw(Tile tile) { + public void draw(Tile tile){ FrackerEntity entity = tile.entity(); Draw.rect(region, tile.drawx(), tile.drawy()); Draw.color(result.color); - Draw.alpha(tile.entity.liquids.get(result)/liquidCapacity); + Draw.alpha(tile.entity.liquids.get(result) / liquidCapacity); Draw.rect(liquidRegion, tile.drawx(), tile.drawy()); Draw.color(); @@ -54,12 +54,12 @@ public class Fracker extends SolidPump { } @Override - public TextureRegion[] getIcon() { + public TextureRegion[] getIcon(){ return new TextureRegion[]{Draw.region(name), Draw.region(name + "-rotator"), Draw.region(name + "-top")}; } @Override - public void update(Tile tile) { + public void update(Tile tile){ FrackerEntity entity = tile.entity(); Item item = consumes.item(); @@ -77,12 +77,12 @@ public class Fracker extends SolidPump { } @Override - public TileEntity getEntity() { + public TileEntity getEntity(){ return new FrackerEntity(); } @Override - public float typeLiquid(Tile tile) { + public float typeLiquid(Tile tile){ return tile.entity.liquids.get(result); } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/GenericCrafter.java b/core/src/io/anuke/mindustry/world/blocks/production/GenericCrafter.java index 8a6a67c2fd..9c0f60ba75 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/GenericCrafter.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/GenericCrafter.java @@ -26,108 +26,108 @@ import static io.anuke.mindustry.Vars.control; import static io.anuke.mindustry.Vars.headless; public class GenericCrafter extends Block{ - protected final int timerDump = timers++; + protected final int timerDump = timers++; - protected Item output; - protected float craftTime = 80; - protected Effect craftEffect = BlockFx.purify; - protected Effect updateEffect = Fx.none; - protected float updateEffectChance = 0.04f; + protected Item output; + protected float craftTime = 80; + protected Effect craftEffect = BlockFx.purify; + protected Effect updateEffect = Fx.none; + protected float updateEffectChance = 0.04f; - public GenericCrafter(String name) { - super(name); - update = true; - solid = true; - health = 60; - } + public GenericCrafter(String name){ + super(name); + update = true; + solid = true; + health = 60; + } - @Override - public void setBars(){ - super.setBars(); + @Override + public void setBars(){ + super.setBars(); - if(consumes.has(ConsumeItem.class)) bars.replace(new BlockBar(BarType.inventory, true, - tile -> (float)tile.entity.items.get(consumes.item()) / itemCapacity)); - } - - @Override - public void setStats(){ - super.setStats(); - stats.add(BlockStat.craftSpeed, 60f/craftTime, StatUnit.itemsSecond); - stats.add(BlockStat.outputItem, output); - } - - @Override - public void draw(Tile tile){ - Draw.rect(name(), tile.drawx(), tile.drawy()); - - if(!hasLiquids) return; - - Draw.color(tile.entity.liquids.current().color); - Draw.alpha(tile.entity.liquids.total() / liquidCapacity); - Draw.rect("blank", tile.drawx(), tile.drawy(), 2, 2); - Draw.color(); - } + if(consumes.has(ConsumeItem.class)) bars.replace(new BlockBar(BarType.inventory, true, + tile -> (float) tile.entity.items.get(consumes.item()) / itemCapacity)); + } - @Override - public TextureRegion[] getIcon(){ - return new TextureRegion[]{Draw.region(name)}; - } - - @Override - public void update(Tile tile){ - GenericCrafterEntity entity = tile.entity(); + @Override + public void setStats(){ + super.setStats(); + stats.add(BlockStat.craftSpeed, 60f / craftTime, StatUnit.itemsSecond); + stats.add(BlockStat.outputItem, output); + } - if(entity.cons.valid()){ + @Override + public void draw(Tile tile){ + Draw.rect(name(), tile.drawx(), tile.drawy()); - entity.progress += 1f / craftTime * Timers.delta(); - entity.totalProgress += Timers.delta(); - entity.warmup = Mathf.lerp(entity.warmup, 1f, 0.02f); + if(!hasLiquids) return; - if(Mathf.chance(Timers.delta() * updateEffectChance)) - Effects.effect(updateEffect, entity.x + Mathf.range(size*4f), entity.y + Mathf.range(size*4)); - }else{ - entity.warmup = Mathf.lerp(entity.warmup, 0f, 0.02f); - } + Draw.color(tile.entity.liquids.current().color); + Draw.alpha(tile.entity.liquids.total() / liquidCapacity); + Draw.rect("blank", tile.drawx(), tile.drawy(), 2, 2); + Draw.color(); + } - if(entity.progress >= 1f){ - - if(consumes.has(ConsumeItem.class)) tile.entity.items.remove(consumes.item(), consumes.itemAmount()); + @Override + public TextureRegion[] getIcon(){ + return new TextureRegion[]{Draw.region(name)}; + } - //unlock output item - if(!headless){ - control.database().unlockContent(output); - } + @Override + public void update(Tile tile){ + GenericCrafterEntity entity = tile.entity(); - offloadNear(tile, output); - Effects.effect(craftEffect, tile.drawx(), tile.drawy()); - entity.progress = 0f; - } - - if(tile.entity.timer.get(timerDump, 5)){ - tryDump(tile, output); - } - } + if(entity.cons.valid()){ - @Override - public TileEntity getEntity() { - return new GenericCrafterEntity(); - } + entity.progress += 1f / craftTime * Timers.delta(); + entity.totalProgress += Timers.delta(); + entity.warmup = Mathf.lerp(entity.warmup, 1f, 0.02f); - public static class GenericCrafterEntity extends TileEntity{ - public float progress; - public float totalProgress; - public float warmup; + if(Mathf.chance(Timers.delta() * updateEffectChance)) + Effects.effect(updateEffect, entity.x + Mathf.range(size * 4f), entity.y + Mathf.range(size * 4)); + }else{ + entity.warmup = Mathf.lerp(entity.warmup, 0f, 0.02f); + } - @Override - public void write(DataOutputStream stream) throws IOException { - stream.writeFloat(progress); - stream.writeFloat(warmup); - } + if(entity.progress >= 1f){ - @Override - public void read(DataInputStream stream) throws IOException { - progress = stream.readFloat(); - warmup = stream.readFloat(); - } - } + if(consumes.has(ConsumeItem.class)) tile.entity.items.remove(consumes.item(), consumes.itemAmount()); + + //unlock output item + if(!headless){ + control.database().unlockContent(output); + } + + offloadNear(tile, output); + Effects.effect(craftEffect, tile.drawx(), tile.drawy()); + entity.progress = 0f; + } + + if(tile.entity.timer.get(timerDump, 5)){ + tryDump(tile, output); + } + } + + @Override + public TileEntity getEntity(){ + return new GenericCrafterEntity(); + } + + public static class GenericCrafterEntity extends TileEntity{ + public float progress; + public float totalProgress; + public float warmup; + + @Override + public void write(DataOutputStream stream) throws IOException{ + stream.writeFloat(progress); + stream.writeFloat(warmup); + } + + @Override + public void read(DataInputStream stream) throws IOException{ + progress = stream.readFloat(); + warmup = stream.readFloat(); + } + } } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Incinerator.java b/core/src/io/anuke/mindustry/world/blocks/production/Incinerator.java index 00b8997d07..ed8697ad2a 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Incinerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Incinerator.java @@ -15,11 +15,11 @@ import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.Fill; import io.anuke.ucore.util.Mathf; -public class Incinerator extends Block { +public class Incinerator extends Block{ protected Effect effect = BlockFx.fuelburn; protected Color flameColor = Color.valueOf("ffad9d"); - public Incinerator(String name) { + public Incinerator(String name){ super(name); hasPower = true; hasLiquids = true; @@ -30,13 +30,13 @@ public class Incinerator extends Block { } @Override - public void setBars() { + public void setBars(){ super.setBars(); bars.remove(BarType.liquid); } @Override - public void update(Tile tile) { + public void update(Tile tile){ IncineratorEntity entity = tile.entity(); if(entity.cons.valid()){ @@ -47,7 +47,7 @@ public class Incinerator extends Block { } @Override - public void draw(Tile tile) { + public void draw(Tile tile){ super.draw(tile); IncineratorEntity entity = tile.entity(); @@ -56,7 +56,7 @@ public class Incinerator extends Block { float g = 0.3f; float r = 0.06f; - Draw.alpha(((1f-g) + Mathf.absin(Timers.time(), 8f, g) + Mathf.random(r) - r) * entity.heat); + Draw.alpha(((1f - g) + Mathf.absin(Timers.time(), 8f, g) + Mathf.random(r) - r) * entity.heat); Draw.tint(flameColor); Fill.circle(tile.drawx(), tile.drawy(), 2f); @@ -68,33 +68,33 @@ public class Incinerator extends Block { } @Override - public void handleItem(Item item, Tile tile, Tile source) { + public void handleItem(Item item, Tile tile, Tile source){ if(Mathf.chance(0.3)){ Effects.effect(effect, tile.drawx(), tile.drawy()); } } @Override - public boolean acceptItem(Item item, Tile tile, Tile source) { + public boolean acceptItem(Item item, Tile tile, Tile source){ IncineratorEntity entity = tile.entity(); return entity.heat > 0.5f; } @Override - public void handleLiquid(Tile tile, Tile source, Liquid liquid, float amount) { + public void handleLiquid(Tile tile, Tile source, Liquid liquid, float amount){ if(Mathf.chance(0.02)){ Effects.effect(effect, tile.drawx(), tile.drawy()); } } @Override - public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount) { + public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){ IncineratorEntity entity = tile.entity(); return entity.heat > 0.5f; } @Override - public TileEntity getEntity() { + public TileEntity getEntity(){ return new IncineratorEntity(); } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/LiquidMixer.java b/core/src/io/anuke/mindustry/world/blocks/production/LiquidMixer.java index e99fc47c36..11733cf392 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/LiquidMixer.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/LiquidMixer.java @@ -16,7 +16,7 @@ public class LiquidMixer extends LiquidBlock{ protected Liquid outputLiquid; protected float liquidPerItem = 50f; - public LiquidMixer(String name) { + public LiquidMixer(String name){ super(name); hasItems = true; rotate = false; @@ -25,14 +25,14 @@ public class LiquidMixer extends LiquidBlock{ } @Override - public void setStats() { + public void setStats(){ super.setStats(); stats.add(BlockStat.liquidOutput, outputLiquid); } @Override - public void setBars() { + public void setBars(){ super.setBars(); bars.remove(BarType.liquid); @@ -53,7 +53,7 @@ public class LiquidMixer extends LiquidBlock{ float use = Math.min(consumes.get(ConsumeLiquid.class).used() * Timers.delta(), liquidCapacity - entity.liquids.get(outputLiquid)); entity.accumulator += use; entity.liquids.add(outputLiquid, use); - for (int i = 0; i < (int)(entity.accumulator / liquidPerItem); i++) { + for(int i = 0; i < (int) (entity.accumulator / liquidPerItem); i++){ if(!entity.items.has(consumes.item())) break; entity.items.remove(consumes.item(), 1); entity.accumulator -= liquidPerItem; @@ -82,11 +82,11 @@ public class LiquidMixer extends LiquidBlock{ } @Override - public TileEntity getEntity() { + public TileEntity getEntity(){ return new LiquidMixerEntity(); } - static class LiquidMixerEntity extends TileEntity { + static class LiquidMixerEntity extends TileEntity{ float accumulator; } } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/PhaseWeaver.java b/core/src/io/anuke/mindustry/world/blocks/production/PhaseWeaver.java index d58545f44f..5a7369d1aa 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/PhaseWeaver.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/PhaseWeaver.java @@ -14,12 +14,12 @@ public class PhaseWeaver extends PowerSmelter{ protected TextureRegion bottomRegion; protected TextureRegion weaveRegion; - public PhaseWeaver(String name) { + public PhaseWeaver(String name){ super(name); } @Override - public void load() { + public void load(){ super.load(); bottomRegion = Draw.region(name + "-bottom"); @@ -27,7 +27,7 @@ public class PhaseWeaver extends PowerSmelter{ } @Override - public TextureRegion[] getIcon() { + public TextureRegion[] getIcon(){ if(icon == null){ icon = new TextureRegion[]{Draw.region(name + "-bottom"), Draw.region(name)}; } @@ -35,7 +35,7 @@ public class PhaseWeaver extends PowerSmelter{ } @Override - public void draw(Tile tile) { + public void draw(Tile tile){ PowerSmelterEntity entity = tile.entity(); Draw.rect(bottomRegion, tile.drawx(), tile.drawy()); @@ -59,7 +59,7 @@ public class PhaseWeaver extends PowerSmelter{ tile.drawx() + Mathf.sin(entity.time, 6f, Vars.tilesize / 3f * size), tile.drawy(), 90, - size * Vars.tilesize /2f); + size * Vars.tilesize / 2f); Draw.reset(); } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/PlastaniumCompressor.java b/core/src/io/anuke/mindustry/world/blocks/production/PlastaniumCompressor.java index faf664d788..0a8c5fda3f 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/PlastaniumCompressor.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/PlastaniumCompressor.java @@ -4,14 +4,14 @@ import io.anuke.mindustry.world.Tile; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.util.Mathf; -public class PlastaniumCompressor extends GenericCrafter { +public class PlastaniumCompressor extends GenericCrafter{ - public PlastaniumCompressor(String name) { + public PlastaniumCompressor(String name){ super(name); } @Override - public void draw(Tile tile) { + public void draw(Tile tile){ super.draw(tile); GenericCrafterEntity entity = tile.entity(); diff --git a/core/src/io/anuke/mindustry/world/blocks/production/PowerCrafter.java b/core/src/io/anuke/mindustry/world/blocks/production/PowerCrafter.java index 18639a72e1..c43860227f 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/PowerCrafter.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/PowerCrafter.java @@ -12,14 +12,18 @@ import io.anuke.ucore.core.Timers; public class PowerCrafter extends Block{ protected final int timerDump = timers++; - /**Optional.*/ + /** + * Optional. + */ protected Item outputItem; - /**Optional. Set hasLiquids to true when using.*/ + /** + * Optional. Set hasLiquids to true when using. + */ protected Liquid outputLiquid; protected float outputLiquidAmount; protected float craftTime; - public PowerCrafter(String name) { + public PowerCrafter(String name){ super(name); solid = true; update = true; @@ -28,7 +32,7 @@ public class PowerCrafter extends Block{ } @Override - public void init() { + public void init(){ super.init(); if(outputLiquid != null){ @@ -37,7 +41,7 @@ public class PowerCrafter extends Block{ } @Override - public void setStats() { + public void setStats(){ super.setStats(); if(outputItem != null){ @@ -50,11 +54,11 @@ public class PowerCrafter extends Block{ } @Override - public void update(Tile tile) { + public void update(Tile tile){ GenericCrafterEntity entity = tile.entity(); if(entity.cons.valid()){ - entity.progress += 1f/craftTime; + entity.progress += 1f / craftTime; entity.totalProgress += Timers.delta(); } @@ -75,7 +79,7 @@ public class PowerCrafter extends Block{ } @Override - public TileEntity getEntity() { + public TileEntity getEntity(){ return new GenericCrafterEntity(); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/PowerSmelter.java b/core/src/io/anuke/mindustry/world/blocks/production/PowerSmelter.java index 67b18228b8..ebb561aa12 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/PowerSmelter.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/PowerSmelter.java @@ -23,7 +23,7 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; -public class PowerSmelter extends PowerBlock { +public class PowerSmelter extends PowerBlock{ protected final int timerDump = timers++; protected final int timerCraft = timers++; @@ -45,7 +45,7 @@ public class PowerSmelter extends PowerBlock { protected TextureRegion topRegion; - public PowerSmelter(String name) { + public PowerSmelter(String name){ super(name); hasItems = true; update = true; @@ -54,7 +54,7 @@ public class PowerSmelter extends PowerBlock { } @Override - public void load() { + public void load(){ super.load(); topRegion = Draw.region(name + "-top"); } @@ -74,7 +74,7 @@ public class PowerSmelter extends PowerBlock { super.setStats(); stats.add(BlockStat.outputItem, result); - stats.add(BlockStat.craftSpeed, 60f/craftTime, StatUnit.itemsSecond); + stats.add(BlockStat.craftSpeed, 60f / craftTime, StatUnit.itemsSecond); stats.add(BlockStat.inputItemCapacity, itemCapacity, StatUnit.items); stats.add(BlockStat.outputItemCapacity, itemCapacity, StatUnit.items); } @@ -92,7 +92,7 @@ public class PowerSmelter extends PowerBlock { if(entity.cons.valid()){ entity.heat += 1f / heatUpTime * Timers.delta(); if(Mathf.chance(Timers.delta() * burnEffectChance)) - Effects.effect(burnEffect, entity.x + Mathf.range(size*4f), entity.y + Mathf.range(size*4)); + Effects.effect(burnEffect, entity.x + Mathf.range(size * 4f), entity.y + Mathf.range(size * 4)); }else{ entity.heat -= 1f / heatUpTime * Timers.delta(); } @@ -125,8 +125,8 @@ public class PowerSmelter extends PowerBlock { } } - if(consumeInputs) { - for (ItemStack item : consumes.items()) { + if(consumeInputs){ + for(ItemStack item : consumes.items()){ entity.items.remove(item.item, item.amount); } } @@ -152,7 +152,7 @@ public class PowerSmelter extends PowerBlock { } @Override - public int getMaximumAccepted(Tile tile, Item item) { + public int getMaximumAccepted(Tile tile, Item item){ return itemCapacity - tile.entity.items.get(item); } @@ -168,7 +168,7 @@ public class PowerSmelter extends PowerBlock { float r = 0.06f; float cr = Mathf.random(0.1f); - Draw.alpha(((1f-g) + Mathf.absin(Timers.time(), 8f, g) + Mathf.random(r) - r) * entity.heat); + Draw.alpha(((1f - g) + Mathf.absin(Timers.time(), 8f, g) + Mathf.random(r) - r) * entity.heat); Draw.tint(flameColor); Fill.circle(tile.drawx(), tile.drawy(), 3f + Mathf.absin(Timers.time(), 5f, 2f) + cr); @@ -181,7 +181,7 @@ public class PowerSmelter extends PowerBlock { } @Override - public TileEntity getEntity() { + public TileEntity getEntity(){ return new PowerSmelterEntity(); } @@ -190,12 +190,12 @@ public class PowerSmelter extends PowerBlock { public float time; @Override - public void write(DataOutputStream stream) throws IOException { + public void write(DataOutputStream stream) throws IOException{ stream.writeFloat(heat); } @Override - public void read(DataInputStream stream) throws IOException { + public void read(DataInputStream stream) throws IOException{ heat = stream.readFloat(); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Pulverizer.java b/core/src/io/anuke/mindustry/world/blocks/production/Pulverizer.java index c96c0ec054..72f80e138b 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Pulverizer.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Pulverizer.java @@ -4,23 +4,23 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion; import io.anuke.mindustry.world.Tile; import io.anuke.ucore.graphics.Draw; -public class Pulverizer extends GenericCrafter { +public class Pulverizer extends GenericCrafter{ protected TextureRegion rotatorRegion; - public Pulverizer(String name) { + public Pulverizer(String name){ super(name); hasItems = true; } @Override - public void load() { + public void load(){ super.load(); rotatorRegion = Draw.region(name + "-rotator"); } @Override - public void draw(Tile tile) { + public void draw(Tile tile){ GenericCrafterEntity entity = tile.entity(); Draw.rect(region, tile.drawx(), tile.drawy()); @@ -28,7 +28,7 @@ public class Pulverizer extends GenericCrafter { } @Override - public TextureRegion[] getIcon() { + public TextureRegion[] getIcon(){ return new TextureRegion[]{Draw.region(name), Draw.region(name + "-rotator")}; } } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Pump.java b/core/src/io/anuke/mindustry/world/blocks/production/Pump.java index 97c6129e32..448f840801 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Pump.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Pump.java @@ -13,97 +13,101 @@ import io.anuke.ucore.core.Timers; import io.anuke.ucore.graphics.Draw; public class Pump extends LiquidBlock{ - protected final Array drawTiles = new Array<>(); - protected final Array updateTiles = new Array<>(); + protected final Array drawTiles = new Array<>(); + protected final Array updateTiles = new Array<>(); - /**Pump amount per tile this block is on.*/ - protected float pumpAmount = 1f; - /**Maximum liquid tier this pump can use.*/ - protected int tier = 0; + /** + * Pump amount per tile this block is on. + */ + protected float pumpAmount = 1f; + /** + * Maximum liquid tier this pump can use. + */ + protected int tier = 0; - public Pump(String name) { - super(name); - layer = Layer.overlay; - liquidFlowFactor = 3f; - group = BlockGroup.liquids; - floating = true; - } + public Pump(String name){ + super(name); + layer = Layer.overlay; + liquidFlowFactor = 3f; + group = BlockGroup.liquids; + floating = true; + } - @Override - public void load() { - super.load(); + @Override + public void load(){ + super.load(); - liquidRegion = Draw.region("pump-liquid"); - } + liquidRegion = Draw.region("pump-liquid"); + } - @Override - public void setStats(){ - super.setStats(); - stats.add(BlockStat.liquidOutput, 60f*pumpAmount, StatUnit.liquidSecond); - } - - @Override - public void draw(Tile tile){ - Draw.rect(name(), tile.drawx(), tile.drawy()); - - Draw.color(tile.entity.liquids.current().color); - Draw.alpha(tile.entity.liquids.total() / liquidCapacity); - Draw.rect(liquidRegion, tile.drawx(), tile.drawy()); - Draw.color(); - } + @Override + public void setStats(){ + super.setStats(); + stats.add(BlockStat.liquidOutput, 60f * pumpAmount, StatUnit.liquidSecond); + } - @Override - public TextureRegion[] getIcon(){ - return new TextureRegion[]{Draw.region(name)}; - } + @Override + public void draw(Tile tile){ + Draw.rect(name(), tile.drawx(), tile.drawy()); - @Override - public boolean canPlaceOn(Tile tile) { - if(isMultiblock()){ - Liquid last = null; - for(Tile other : tile.getLinkedTilesAs(this, drawTiles)){ - //can't place pump on block with multiple liquids - if(last != null && other.floor().liquidDrop != last){ - return false; - } + Draw.color(tile.entity.liquids.current().color); + Draw.alpha(tile.entity.liquids.total() / liquidCapacity); + Draw.rect(liquidRegion, tile.drawx(), tile.drawy()); + Draw.color(); + } - if(isValid(other)){ - last = other.floor().liquidDrop; - } - } - return last != null; - }else{ - return isValid(tile); - } - } - - @Override - public void update(Tile tile){ - float tiles = 0f; - Liquid liquidDrop = null; + @Override + public TextureRegion[] getIcon(){ + return new TextureRegion[]{Draw.region(name)}; + } - if(isMultiblock()){ - for(Tile other : tile.getLinkedTiles(updateTiles)){ - if(isValid(other)){ - liquidDrop = other.floor().liquidDrop; - tiles ++; - } - } - }else{ - tiles = 1f; - liquidDrop = tile.floor().liquidDrop; - } + @Override + public boolean canPlaceOn(Tile tile){ + if(isMultiblock()){ + Liquid last = null; + for(Tile other : tile.getLinkedTilesAs(this, drawTiles)){ + //can't place pump on block with multiple liquids + if(last != null && other.floor().liquidDrop != last){ + return false; + } - if(tile.entity.cons.valid() && liquidDrop != null){ - float maxPump = Math.min(liquidCapacity - tile.entity.liquids.total(), tiles * pumpAmount * Timers.delta()); - tile.entity.liquids.add(liquidDrop, maxPump); - } + if(isValid(other)){ + last = other.floor().liquidDrop; + } + } + return last != null; + }else{ + return isValid(tile); + } + } - tryDumpLiquid(tile, tile.entity.liquids.current()); - } + @Override + public void update(Tile tile){ + float tiles = 0f; + Liquid liquidDrop = null; - protected boolean isValid(Tile tile){ - return tile.floor().liquidDrop != null && tier >= tile.floor().liquidDrop.tier; - } + if(isMultiblock()){ + for(Tile other : tile.getLinkedTiles(updateTiles)){ + if(isValid(other)){ + liquidDrop = other.floor().liquidDrop; + tiles++; + } + } + }else{ + tiles = 1f; + liquidDrop = tile.floor().liquidDrop; + } + + if(tile.entity.cons.valid() && liquidDrop != null){ + float maxPump = Math.min(liquidCapacity - tile.entity.liquids.total(), tiles * pumpAmount * Timers.delta()); + tile.entity.liquids.add(liquidDrop, maxPump); + } + + tryDumpLiquid(tile, tile.entity.liquids.current()); + } + + protected boolean isValid(Tile tile){ + return tile.floor().liquidDrop != null && tier >= tile.floor().liquidDrop.tier; + } } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Separator.java b/core/src/io/anuke/mindustry/world/blocks/production/Separator.java index 9ba2cb2d7c..583885d450 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Separator.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Separator.java @@ -16,9 +16,11 @@ import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.Lines; import io.anuke.ucore.util.Mathf; -/**Extracts a random list of items from an input item and an input liquid.*/ -public class Separator extends Block { - protected final int timerDump = timers ++; +/** + * Extracts a random list of items from an input item and an input liquid. + */ +public class Separator extends Block{ + protected final int timerDump = timers++; protected Item[] results; protected float filterTime; @@ -32,7 +34,7 @@ public class Separator extends Block { protected boolean offloading = false; - public Separator(String name) { + public Separator(String name){ super(name); update = true; solid = true; @@ -44,14 +46,14 @@ public class Separator extends Block { } @Override - public void load() { + public void load(){ super.load(); liquidRegion = Draw.region(name + "-liquid"); } @Override - public void setStats() { + public void setStats(){ super.setStats(); stats.add(BlockStat.outputItem, new ItemFilterValue(item -> { @@ -63,7 +65,7 @@ public class Separator extends Block { } @Override - public void draw(Tile tile) { + public void draw(Tile tile){ super.draw(tile); GenericCrafterEntity entity = tile.entity(); @@ -74,18 +76,18 @@ public class Separator extends Block { Draw.color(color); Lines.stroke(spinnerThickness); - Lines.spikes(tile.drawx(), tile.drawy(), spinnerRadius, spinnerLength, 3, entity.totalProgress*spinnerSpeed); + Lines.spikes(tile.drawx(), tile.drawy(), spinnerRadius, spinnerLength, 3, entity.totalProgress * spinnerSpeed); Draw.reset(); } @Override - public void update(Tile tile) { + public void update(Tile tile){ GenericCrafterEntity entity = tile.entity(); - entity.totalProgress += entity.warmup*Timers.delta(); + entity.totalProgress += entity.warmup * Timers.delta(); if(entity.cons.valid()){ - entity.progress += 1f/filterTime; + entity.progress += 1f / filterTime; entity.warmup = Mathf.lerpDelta(entity.warmup, 1f, 0.02f); }else{ entity.warmup = Mathf.lerpDelta(entity.warmup, 0f, 0.02f); @@ -108,12 +110,12 @@ public class Separator extends Block { } @Override - public boolean canDump(Tile tile, Tile to, Item item) { + public boolean canDump(Tile tile, Tile to, Item item){ return offloading || item != consumes.item(); } @Override - public TileEntity getEntity() { + public TileEntity getEntity(){ return new GenericCrafterEntity(); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Smelter.java b/core/src/io/anuke/mindustry/world/blocks/production/Smelter.java index b28847fb7e..1f347070d9 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Smelter.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Smelter.java @@ -21,169 +21,169 @@ import io.anuke.ucore.graphics.Fill; import io.anuke.ucore.util.Mathf; public class Smelter extends Block{ - protected final int timerDump = timers++; - protected final int timerCraft = timers++; + protected final int timerDump = timers++; + protected final int timerCraft = timers++; - protected Item result; + protected Item result; - protected float minFlux = 0.2f; - protected float baseFluxChance = 0.15f; - protected boolean useFlux = false; + protected float minFlux = 0.2f; + protected float baseFluxChance = 0.15f; + protected boolean useFlux = false; - protected float craftTime = 20f; - protected float burnDuration = 50f; - protected Effect craftEffect = BlockFx.smelt, burnEffect = BlockFx.fuelburn; - protected Color flameColor = Color.valueOf("ffb879"); + protected float craftTime = 20f; + protected float burnDuration = 50f; + protected Effect craftEffect = BlockFx.smelt, burnEffect = BlockFx.fuelburn; + protected Color flameColor = Color.valueOf("ffb879"); - public Smelter(String name) { - super(name); - update = true; - hasItems = true; - solid = true; - itemCapacity = 20; + public Smelter(String name){ + super(name); + update = true; + hasItems = true; + solid = true; + itemCapacity = 20; - consumes.require(ConsumeItems.class); - consumes.require(ConsumeItem.class); - } + consumes.require(ConsumeItems.class); + consumes.require(ConsumeItem.class); + } - @Override - public void setBars(){ - for(ItemStack item : consumes.items()){ - bars.add(new BlockBar(BarType.inventory, true, tile -> (float)tile.entity.items.get(item.item)/itemCapacity)); - } - } - - @Override - public void setStats(){ - super.setStats(); + @Override + public void setBars(){ + for(ItemStack item : consumes.items()){ + bars.add(new BlockBar(BarType.inventory, true, tile -> (float) tile.entity.items.get(item.item) / itemCapacity)); + } + } - //TODO - //stats.add(BlockStat.inputFuel, fuel); - stats.add(BlockStat.fuelBurnTime, burnDuration/60f, StatUnit.seconds); - stats.add(BlockStat.outputItem, result); - stats.add(BlockStat.craftSpeed, 60f/craftTime, StatUnit.itemsSecond); - stats.add(BlockStat.inputItemCapacity, itemCapacity, StatUnit.items); - stats.add(BlockStat.outputItemCapacity, itemCapacity, StatUnit.items); - } + @Override + public void setStats(){ + super.setStats(); - @Override - public void init() { - super.init(); + //TODO + //stats.add(BlockStat.inputFuel, fuel); + stats.add(BlockStat.fuelBurnTime, burnDuration / 60f, StatUnit.seconds); + stats.add(BlockStat.outputItem, result); + stats.add(BlockStat.craftSpeed, 60f / craftTime, StatUnit.itemsSecond); + stats.add(BlockStat.inputItemCapacity, itemCapacity, StatUnit.items); + stats.add(BlockStat.outputItemCapacity, itemCapacity, StatUnit.items); + } - for(ItemStack item : consumes.items()){ - if(item.item.fluxiness >= minFlux && useFlux){ - throw new IllegalArgumentException("'" + name + "' has input item '" + item.item.name + "', which is a flux, when useFlux is enabled. To prevent ambiguous item use, either remove this flux item from the inputs, or set useFlux to false."); - } - } - } + @Override + public void init(){ + super.init(); - @Override - public void update(Tile tile){ - SmelterEntity entity = tile.entity(); - - if(entity.timer.get(timerDump, 5) && entity.items.has(result)){ - tryDump(tile, result); - } + for(ItemStack item : consumes.items()){ + if(item.item.fluxiness >= minFlux && useFlux){ + throw new IllegalArgumentException("'" + name + "' has input item '" + item.item.name + "', which is a flux, when useFlux is enabled. To prevent ambiguous item use, either remove this flux item from the inputs, or set useFlux to false."); + } + } + } - //add fuel - if(entity.consumed(ConsumeItem.class) && entity.burnTime <= 0f){ - entity.items.remove(consumes.item(), 1); - entity.burnTime += burnDuration; - Effects.effect(burnEffect, entity.x + Mathf.range(2f), entity.y + Mathf.range(2f)); - } + @Override + public void update(Tile tile){ + SmelterEntity entity = tile.entity(); - //decrement burntime - if(entity.burnTime > 0){ - entity.burnTime -= Timers.delta(); - entity.heat = Mathf.lerp(entity.heat, 1f, 0.02f); - }else{ - entity.heat = Mathf.lerp(entity.heat, 0f, 0.02f); - } + if(entity.timer.get(timerDump, 5) && entity.items.has(result)){ + tryDump(tile, result); + } - //make sure it has all the items - if(!entity.cons.valid()){ - return; - } + //add fuel + if(entity.consumed(ConsumeItem.class) && entity.burnTime <= 0f){ + entity.items.remove(consumes.item(), 1); + entity.burnTime += burnDuration; + Effects.effect(burnEffect, entity.x + Mathf.range(2f), entity.y + Mathf.range(2f)); + } - if(entity.items.get(result) >= itemCapacity //output full - || entity.burnTime <= 0 //not burning - || !entity.timer.get(timerCraft, craftTime)){ //not yet time - return; - } + //decrement burntime + if(entity.burnTime > 0){ + entity.burnTime -= Timers.delta(); + entity.heat = Mathf.lerp(entity.heat, 1f, 0.02f); + }else{ + entity.heat = Mathf.lerp(entity.heat, 0f, 0.02f); + } - boolean consumeInputs = true; + //make sure it has all the items + if(!entity.cons.valid()){ + return; + } - if(useFlux){ - //remove flux materials if present - for(Item item : Item.all()){ - if(item.fluxiness >= minFlux && tile.entity.items.get(item) > 0){ - tile.entity.items.remove(item, 1); + if(entity.items.get(result) >= itemCapacity //output full + || entity.burnTime <= 0 //not burning + || !entity.timer.get(timerCraft, craftTime)){ //not yet time + return; + } - //chance of not consuming inputs if flux material present - consumeInputs = !Mathf.chance(item.fluxiness * baseFluxChance); - break; - } - } - } + boolean consumeInputs = true; - if(consumeInputs) { - for (ItemStack item : consumes.items()) { - entity.items.remove(item.item, item.amount); - } - } - - offloadNear(tile, result); - Effects.effect(craftEffect, flameColor, tile.drawx(), tile.drawy()); - } + if(useFlux){ + //remove flux materials if present + for(Item item : Item.all()){ + if(item.fluxiness >= minFlux && tile.entity.items.get(item) > 0){ + tile.entity.items.remove(item, 1); - @Override - public int getMaximumAccepted(Tile tile, Item item) { - return itemCapacity - tile.entity.items.get(item); - } + //chance of not consuming inputs if flux material present + consumeInputs = !Mathf.chance(item.fluxiness * baseFluxChance); + break; + } + } + } - @Override - public boolean acceptItem(Item item, Tile tile, Tile source){ - boolean isInput = false; + if(consumeInputs){ + for(ItemStack item : consumes.items()){ + entity.items.remove(item.item, item.amount); + } + } - for(ItemStack req : consumes.items()){ - if(req.item == item){ - isInput = true; - break; - } - } + offloadNear(tile, result); + Effects.effect(craftEffect, flameColor, tile.drawx(), tile.drawy()); + } - return (isInput && tile.entity.items.get(item) < itemCapacity) || (item == consumes.item() && tile.entity.items.get(consumes.item()) < itemCapacity) || - (useFlux && item.fluxiness >= minFlux && tile.entity.items.get(item) < itemCapacity); - } + @Override + public int getMaximumAccepted(Tile tile, Item item){ + return itemCapacity - tile.entity.items.get(item); + } - @Override - public void draw(Tile tile){ - super.draw(tile); + @Override + public boolean acceptItem(Item item, Tile tile, Tile source){ + boolean isInput = false; + + for(ItemStack req : consumes.items()){ + if(req.item == item){ + isInput = true; + break; + } + } + + return (isInput && tile.entity.items.get(item) < itemCapacity) || (item == consumes.item() && tile.entity.items.get(consumes.item()) < itemCapacity) || + (useFlux && item.fluxiness >= minFlux && tile.entity.items.get(item) < itemCapacity); + } + + @Override + public void draw(Tile tile){ + super.draw(tile); SmelterEntity entity = tile.entity(); //draw glowing center - if(entity.heat > 0f){ - float g = 0.1f; + if(entity.heat > 0f){ + float g = 0.1f; - Draw.alpha(((1f-g) + Mathf.absin(Timers.time(), 8f, g)) * entity.heat); + Draw.alpha(((1f - g) + Mathf.absin(Timers.time(), 8f, g)) * entity.heat); - Draw.tint(flameColor); - Fill.circle(tile.drawx(), tile.drawy(), 2f + Mathf.absin(Timers.time(), 5f, 0.8f)); - Draw.color(1f, 1f, 1f, entity.heat); - Fill.circle(tile.drawx(), tile.drawy(), 1f + Mathf.absin(Timers.time(), 5f, 0.7f)); + Draw.tint(flameColor); + Fill.circle(tile.drawx(), tile.drawy(), 2f + Mathf.absin(Timers.time(), 5f, 0.8f)); + Draw.color(1f, 1f, 1f, entity.heat); + Fill.circle(tile.drawx(), tile.drawy(), 1f + Mathf.absin(Timers.time(), 5f, 0.7f)); - Draw.color(); - } + Draw.color(); + } } - @Override - public TileEntity getEntity() { - return new SmelterEntity(); - } + @Override + public TileEntity getEntity(){ + return new SmelterEntity(); + } - public class SmelterEntity extends TileEntity{ - public float burnTime; - public float heat; - } + public class SmelterEntity extends TileEntity{ + public float burnTime; + public float heat; + } } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/SolidPump.java b/core/src/io/anuke/mindustry/world/blocks/production/SolidPump.java index 76993b79ad..49523b350b 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/SolidPump.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/SolidPump.java @@ -13,8 +13,10 @@ import io.anuke.ucore.core.Timers; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.util.Mathf; -/**Pump that makes liquid from solids and takes in power. Only works on solid floor blocks.*/ -public class SolidPump extends Pump { +/** + * Pump that makes liquid from solids and takes in power. Only works on solid floor blocks. + */ +public class SolidPump extends Pump{ protected Liquid result = Liquids.water; protected Effect updateEffect = Fx.none; protected float updateEffectChance = 0.02f; @@ -26,14 +28,14 @@ public class SolidPump extends Pump { } @Override - public void load() { + public void load(){ super.load(); liquidRegion = Draw.region(name + "-liquid"); } @Override - public void setStats() { + public void setStats(){ super.setStats(); stats.remove(BlockStat.liquidOutput); @@ -41,7 +43,7 @@ public class SolidPump extends Pump { } @Override - public void draw(Tile tile) { + public void draw(Tile tile){ SolidPumpEntity entity = tile.entity(); Draw.rect(region, tile.drawx(), tile.drawy()); @@ -54,7 +56,7 @@ public class SolidPump extends Pump { } @Override - public TextureRegion[] getIcon() { + public TextureRegion[] getIcon(){ return new TextureRegion[]{Draw.region(name), Draw.region(name + "-rotator"), Draw.region(name + "-top")}; } @@ -67,7 +69,7 @@ public class SolidPump extends Pump { if(isMultiblock()){ for(Tile other : tile.getLinkedTiles(tempTiles)){ if(isValid(other)){ - fraction += 1f/ size; + fraction += 1f / size; } } }else{ @@ -79,7 +81,7 @@ public class SolidPump extends Pump { tile.entity.liquids.add(result, maxPump); entity.warmup = Mathf.lerpDelta(entity.warmup, 1f, 0.02f); if(Mathf.chance(Timers.delta() * updateEffectChance)) - Effects.effect(updateEffect, entity.x + Mathf.range(size*2f), entity.y + Mathf.range(size*2f)); + Effects.effect(updateEffect, entity.x + Mathf.range(size * 2f), entity.y + Mathf.range(size * 2f)); }else{ entity.warmup = Mathf.lerpDelta(entity.warmup, 0f, 0.02f); } @@ -90,7 +92,7 @@ public class SolidPump extends Pump { } @Override - public boolean canPlaceOn(Tile tile) { + public boolean canPlaceOn(Tile tile){ if(isMultiblock()){ for(Tile other : tile.getLinkedTilesAs(this, drawTiles)){ if(isValid(other)){ @@ -109,7 +111,7 @@ public class SolidPump extends Pump { } @Override - public TileEntity getEntity() { + public TileEntity getEntity(){ return new SolidPumpEntity(); } diff --git a/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java b/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java index de992e1dcc..9d921ccc5a 100644 --- a/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java @@ -39,20 +39,20 @@ import java.io.IOException; import static io.anuke.mindustry.Vars.*; -public class CoreBlock extends StorageBlock { +public class CoreBlock extends StorageBlock{ private static Rectangle rect = new Rectangle(); - protected int timerSupply = timers ++; + protected int timerSupply = timers++; protected float supplyRadius = 50f; protected float supplyInterval = 5f; - protected float droneRespawnDuration = 60*6; + protected float droneRespawnDuration = 60 * 6; protected UnitType droneType = UnitTypes.drone; protected TextureRegion openRegion; protected TextureRegion topRegion; - public CoreBlock(String name) { + public CoreBlock(String name){ super(name); solid = false; @@ -66,15 +66,37 @@ public class CoreBlock extends StorageBlock { flags = EnumSet.of(BlockFlag.resupplyPoint, BlockFlag.target); } + @Remote(called = Loc.server, in = In.blocks) + public static void onUnitRespawn(Tile tile, Unit player){ + if(player == null) return; + + CoreEntity entity = tile.entity(); + Effects.effect(Fx.spawn, entity); + entity.solid = false; + entity.progress = 0; + entity.currentUnit = player; + entity.currentUnit.heal(); + entity.currentUnit.rotation = 90f; + entity.currentUnit.setNet(tile.drawx(), tile.drawy()); + entity.currentUnit.add(); + entity.currentUnit = null; + } + + @Remote(called = Loc.server, in = In.blocks) + public static void setCoreSolid(Tile tile, boolean solid){ + CoreEntity entity = tile.entity(); + entity.solid = solid; + } + @Override - public void setBars() { + public void setBars(){ super.setBars(); bars.remove(BarType.inventory); } @Override - public void load() { + public void load(){ super.load(); openRegion = Draw.region(name + "-open"); @@ -82,12 +104,12 @@ public class CoreBlock extends StorageBlock { } @Override - public float handleDamage(Tile tile, float amount) { + public float handleDamage(Tile tile, float amount){ return debug ? 0 : amount; } @Override - public void draw(Tile tile) { + public void draw(Tile tile){ CoreEntity entity = tile.entity(); Draw.rect(entity.solid ? Draw.region(name) : openRegion, tile.drawx(), tile.drawy()); @@ -96,7 +118,7 @@ public class CoreBlock extends StorageBlock { Draw.rect(topRegion, tile.drawx(), tile.drawy()); Draw.color(); - if(entity.currentUnit != null) { + if(entity.currentUnit != null){ Unit player = entity.currentUnit; TextureRegion region = player.getIconRegion(); @@ -117,14 +139,14 @@ public class CoreBlock extends StorageBlock { tile.drawx() + Mathf.sin(entity.time, 6f, Vars.tilesize / 3f * size), tile.drawy(), 90, - size * Vars.tilesize /2f); + size * Vars.tilesize / 2f); Draw.reset(); } } @Override - public boolean isSolidFor(Tile tile) { + public boolean isSolidFor(Tile tile){ CoreEntity entity = tile.entity(); return entity.solid; @@ -140,7 +162,7 @@ public class CoreBlock extends StorageBlock { } @Override - public boolean acceptItem(Item item, Tile tile, Tile source) { + public boolean acceptItem(Item item, Tile tile, Tile source){ return tile.entity.items.get(item) < itemCapacity && item.type == ItemType.material; } @@ -167,7 +189,7 @@ public class CoreBlock extends StorageBlock { } @Override - public void update(Tile tile) { + public void update(Tile tile){ CoreEntity entity = tile.entity(); if(!entity.solid && !Units.anyEntities(tile)){ @@ -215,12 +237,13 @@ public class CoreBlock extends StorageBlock { } if(entity.solid && tile.entity.timer.get(timerSupply, supplyInterval)){ - rect.setSize(supplyRadius*2).setCenter(tile.drawx(), tile.drawy()); + rect.setSize(supplyRadius * 2).setCenter(tile.drawx(), tile.drawy()); Units.getNearby(tile.getTeam(), rect, unit -> { - if(unit.isDead() || unit.distanceTo(tile.drawx(), tile.drawy()) > supplyRadius || unit.getGroup() == null) return; + if(unit.isDead() || unit.distanceTo(tile.drawx(), tile.drawy()) > supplyRadius || unit.getGroup() == null) + return; - for(int i = 0; i < Item.all().size; i ++){ + for(int i = 0; i < Item.all().size; i++){ Item item = Item.getByID(i); if(tile.entity.items.get(item) > 0 && unit.acceptsAmmo(item)){ tile.entity.items.remove(item, 1); @@ -234,44 +257,23 @@ public class CoreBlock extends StorageBlock { } @Override - public TileEntity getEntity() { + public TileEntity getEntity(){ return new CoreEntity(); } - @Remote(called = Loc.server, in = In.blocks) - public static void onUnitRespawn(Tile tile, Unit player){ - if(player == null) return; + /* + @Remote(called = Loc.server, in = In.blocks) + public static void onCoreUnitSet(Tile tile, Unit player){ + CoreEntity entity = tile.entity(); + entity.currentUnit = player; + entity.progress = 0f; + player.set(tile.drawx(), tile.drawy()); - CoreEntity entity = tile.entity(); - Effects.effect(Fx.spawn, entity); - entity.solid = false; - entity.progress = 0; - entity.currentUnit = player; - entity.currentUnit.heal(); - entity.currentUnit.rotation = 90f; - entity.currentUnit.setNet(tile.drawx(), tile.drawy()); - entity.currentUnit.add(); - entity.currentUnit = null; - } - - @Remote(called = Loc.server, in = In.blocks) - public static void setCoreSolid(Tile tile, boolean solid){ - CoreEntity entity = tile.entity(); - entity.solid = solid; - } -/* - @Remote(called = Loc.server, in = In.blocks) - public static void onCoreUnitSet(Tile tile, Unit player){ - CoreEntity entity = tile.entity(); - entity.currentUnit = player; - entity.progress = 0f; - player.set(tile.drawx(), tile.drawy()); - - if(player instanceof Player){ - ((Player) player).setRespawning(true); + if(player instanceof Player){ + ((Player) player).setRespawning(true); + } } - } -*/ + */ public class CoreEntity extends TileEntity implements SpawnerTrait{ public Unit currentUnit; int droneID = -1; @@ -282,7 +284,7 @@ public class CoreBlock extends StorageBlock { float heat; @Override - public void updateSpawning(Unit unit) { + public void updateSpawning(Unit unit){ if(currentUnit == null){ currentUnit = unit; progress = 0f; @@ -291,18 +293,18 @@ public class CoreBlock extends StorageBlock { } @Override - public float getSpawnProgress() { + public float getSpawnProgress(){ return progress; } @Override - public void write(DataOutputStream stream) throws IOException { + public void write(DataOutputStream stream) throws IOException{ stream.writeBoolean(solid); stream.writeInt(droneID); } @Override - public void read(DataInputStream stream) throws IOException { + public void read(DataInputStream stream) throws IOException{ solid = stream.readBoolean(); droneID = stream.readInt(); } diff --git a/core/src/io/anuke/mindustry/world/blocks/storage/SortedUnloader.java b/core/src/io/anuke/mindustry/world/blocks/storage/SortedUnloader.java index de4c79d10c..00cf65918c 100644 --- a/core/src/io/anuke/mindustry/world/blocks/storage/SortedUnloader.java +++ b/core/src/io/anuke/mindustry/world/blocks/storage/SortedUnloader.java @@ -26,6 +26,12 @@ public class SortedUnloader extends Unloader implements SelectionTrait{ //TODO call event + @Remote(targets = Loc.both, called = Loc.both, in = In.blocks, forward = true) + public static void setSortedUnloaderItem(Player player, Tile tile, Item item){ + SortedUnloaderEntity entity = tile.entity(); + entity.sortItem = item; + } + @Override public void update(Tile tile){ SortedUnloaderEntity entity = tile.entity(); @@ -33,8 +39,8 @@ public class SortedUnloader extends Unloader implements SelectionTrait{ if(entity.items.total() == 0 && entity.timer.get(timerUnload, speed)){ tile.allNearby(other -> { if(other.block() instanceof StorageBlock && entity.items.total() == 0 && - ((StorageBlock)other.block()).hasItem(other, entity.sortItem)){ - offloadNear(tile, ((StorageBlock)other.block()).removeItem(other, entity.sortItem)); + ((StorageBlock) other.block()).hasItem(other, entity.sortItem)){ + offloadNear(tile, ((StorageBlock) other.block()).removeItem(other, entity.sortItem)); } }); } @@ -66,17 +72,11 @@ public class SortedUnloader extends Unloader implements SelectionTrait{ return new SortedUnloaderEntity(); } - @Remote(targets = Loc.both, called = Loc.both, in = In.blocks, forward = true) - public static void setSortedUnloaderItem(Player player, Tile tile, Item item){ - SortedUnloaderEntity entity = tile.entity(); - entity.sortItem = item; - } - public static class SortedUnloaderEntity extends TileEntity{ public Item sortItem = Items.tungsten; @Override - public void write(DataOutputStream stream) throws IOException { + public void write(DataOutputStream stream) throws IOException{ stream.writeByte(sortItem.id); } diff --git a/core/src/io/anuke/mindustry/world/blocks/storage/StorageBlock.java b/core/src/io/anuke/mindustry/world/blocks/storage/StorageBlock.java index 31d24e1190..b5e4c83a8c 100644 --- a/core/src/io/anuke/mindustry/world/blocks/storage/StorageBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/storage/StorageBlock.java @@ -5,15 +5,17 @@ import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; -public abstract class StorageBlock extends Block { +public abstract class StorageBlock extends Block{ public StorageBlock(String name){ super(name); hasItems = true; } - /**Removes an item and returns it. If item is not null, it should return the item. - * Returns null if no items are there.*/ + /** + * Removes an item and returns it. If item is not null, it should return the item. + * Returns null if no items are there. + */ public Item removeItem(Tile tile, Item item){ TileEntity entity = tile.entity; @@ -29,8 +31,10 @@ public abstract class StorageBlock extends Block { } } - /**Returns whether this storage block has the specified item. - * If the item is null, it should return whether it has ANY items.*/ + /** + * Returns whether this storage block has the specified item. + * If the item is null, it should return whether it has ANY items. + */ public boolean hasItem(Tile tile, Item item){ TileEntity entity = tile.entity; if(item == null){ diff --git a/core/src/io/anuke/mindustry/world/blocks/storage/Unloader.java b/core/src/io/anuke/mindustry/world/blocks/storage/Unloader.java index aa59e769c7..6e7d32403c 100644 --- a/core/src/io/anuke/mindustry/world/blocks/storage/Unloader.java +++ b/core/src/io/anuke/mindustry/world/blocks/storage/Unloader.java @@ -2,10 +2,10 @@ package io.anuke.mindustry.world.blocks.storage; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.Block; -import io.anuke.mindustry.world.meta.BlockGroup; import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.meta.BlockGroup; -public class Unloader extends Block { +public class Unloader extends Block{ protected final int timerUnload = timers++; protected int speed = 5; @@ -23,8 +23,8 @@ public class Unloader extends Block { if(tile.entity.items.total() == 0 && tile.entity.timer.get(timerUnload, speed)){ tile.allNearby(other -> { if(other.block() instanceof StorageBlock && tile.entity.items.total() == 0 && - ((StorageBlock)other.block()).hasItem(other, null)){ - offloadNear(tile, ((StorageBlock)other.block()).removeItem(other, null)); + ((StorageBlock) other.block()).hasItem(other, null)){ + offloadNear(tile, ((StorageBlock) other.block()).removeItem(other, null)); } }); } @@ -35,11 +35,12 @@ public class Unloader extends Block { } @Override - public boolean canDump(Tile tile, Tile to, Item item) { + public boolean canDump(Tile tile, Tile to, Item item){ Block block = to.target().block(); return !(block instanceof StorageBlock); } @Override - public void setBars(){} + public void setBars(){ + } } diff --git a/core/src/io/anuke/mindustry/world/blocks/storage/Vault.java b/core/src/io/anuke/mindustry/world/blocks/storage/Vault.java index 54a9bffd28..16e23306ea 100644 --- a/core/src/io/anuke/mindustry/world/blocks/storage/Vault.java +++ b/core/src/io/anuke/mindustry/world/blocks/storage/Vault.java @@ -4,7 +4,7 @@ import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.Tile; import io.anuke.ucore.core.Timers; -public class Vault extends StorageBlock { +public class Vault extends StorageBlock{ public Vault(String name){ super(name); @@ -17,8 +17,8 @@ public class Vault extends StorageBlock { public void update(Tile tile){ int iterations = Math.max(1, (int) (Timers.delta() + 0.4f)); - for(int i = 0; i < iterations; i ++) { - if (tile.entity.items.total() > 0) { + for(int i = 0; i < iterations; i++){ + if(tile.entity.items.total() > 0){ tryDump(tile); } } @@ -30,14 +30,14 @@ public class Vault extends StorageBlock { } @Override - public boolean acceptItem(Item item, Tile tile, Tile source) { + public boolean acceptItem(Item item, Tile tile, Tile source){ return tile.entity.items.total() < itemCapacity; } @Override - public boolean canDump(Tile tile, Tile to, Item item) { + public boolean canDump(Tile tile, Tile to, Item item){ to = to.target(); - if (!(to.block() instanceof StorageBlock)) return false; + if(!(to.block() instanceof StorageBlock)) return false; return !(to.block() instanceof Vault) || (float) to.entity.items.total() / to.block().itemCapacity < (float) tile.entity.items.total() / itemCapacity; diff --git a/core/src/io/anuke/mindustry/world/blocks/units/CommandCenter.java b/core/src/io/anuke/mindustry/world/blocks/units/CommandCenter.java index 830b215b2d..c4a5ca3859 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/CommandCenter.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/CommandCenter.java @@ -2,8 +2,8 @@ package io.anuke.mindustry.world.blocks.units; import io.anuke.mindustry.world.Block; -public class CommandCenter extends Block { - public CommandCenter(String name) { +public class CommandCenter extends Block{ + public CommandCenter(String name){ super(name); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/units/DropPoint.java b/core/src/io/anuke/mindustry/world/blocks/units/DropPoint.java index b6a294465e..8acdf20be9 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/DropPoint.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/DropPoint.java @@ -4,9 +4,9 @@ import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; -public class DropPoint extends Block { +public class DropPoint extends Block{ - public DropPoint(String name) { + public DropPoint(String name){ super(name); hasItems = true; @@ -15,13 +15,13 @@ public class DropPoint extends Block { } @Override - public boolean acceptItem(Item item, Tile tile, Tile source) { + public boolean acceptItem(Item item, Tile tile, Tile source){ return false; } @Override - public void update(Tile tile) { - if (tile.entity.items.total() > 0) { + public void update(Tile tile){ + if(tile.entity.items.total() > 0){ tryDump(tile); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/units/MechFactory.java b/core/src/io/anuke/mindustry/world/blocks/units/MechFactory.java index deff90de86..df2c2db165 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/MechFactory.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/MechFactory.java @@ -33,7 +33,7 @@ import static io.anuke.mindustry.Vars.tilesize; public class MechFactory extends Block{ protected Mech mech; - protected float buildTime = 60*5; + protected float buildTime = 60 * 5; protected TextureRegion openRegion; @@ -44,14 +44,52 @@ public class MechFactory extends Block{ solidifes = true; } + @Remote(targets = Loc.both, called = Loc.server, in = In.blocks) + public static void onMechFactoryTap(Player player, Tile tile){ + if(!checkValidTap(tile, player)) return; + + MechFactoryEntity entity = tile.entity(); + player.beginRespawning(entity); + } + + @Remote(called = Loc.server, in = In.blocks) + public static void onMechFactoryDone(Tile tile){ + MechFactoryEntity entity = tile.entity(); + + Effects.effect(Fx.spawn, entity); + + if(entity.player == null) return; + + Mech result = ((MechFactory) tile.block()).mech; + + if(entity.player.mech == result){ + entity.player.mech = (entity.player.isMobile ? Mechs.starterMobile : Mechs.starterDesktop); + }else{ + entity.player.mech = result; + } + + entity.progress = 0; + entity.player.heal(); + entity.open = true; + entity.player.setDead(false); + entity.player.inventory.clear(); + entity.player = null; + } + + protected static boolean checkValidTap(Tile tile, Player player){ + MechFactoryEntity entity = tile.entity(); + return Math.abs(player.x - tile.drawx()) <= tile.block().size * tilesize / 2f && + Math.abs(player.y - tile.drawy()) <= tile.block().size * tilesize / 2f && entity.player == null; + } + @Override - public boolean isSolidFor(Tile tile) { + public boolean isSolidFor(Tile tile){ MechFactoryEntity entity = tile.entity(); return !entity.open; } @Override - public void tapped(Tile tile, Player player) { + public void tapped(Tile tile, Player player){ if(mobile && !mech.flying) return; if(checkValidTap(tile, player)){ @@ -62,18 +100,18 @@ public class MechFactory extends Block{ } @Override - public void load() { + public void load(){ super.load(); openRegion = Draw.region(name + "-open"); } @Override - public void draw(Tile tile) { + public void draw(Tile tile){ MechFactoryEntity entity = tile.entity(); Draw.rect(entity.open ? openRegion : Draw.region(name), tile.drawx(), tile.drawy()); - if(entity.player != null) { + if(entity.player != null){ TextureRegion region = mech.iconRegion; if(entity.player.mech == mech){ @@ -103,7 +141,7 @@ public class MechFactory extends Block{ } @Override - public void update(Tile tile) { + public void update(Tile tile){ MechFactoryEntity entity = tile.entity(); if(entity.open){ @@ -133,48 +171,10 @@ public class MechFactory extends Block{ } @Override - public TileEntity getEntity() { + public TileEntity getEntity(){ return new MechFactoryEntity(); } - @Remote(targets = Loc.both, called = Loc.server, in = In.blocks) - public static void onMechFactoryTap(Player player, Tile tile){ - if(!checkValidTap(tile, player)) return; - - MechFactoryEntity entity = tile.entity(); - player.beginRespawning(entity); - } - - @Remote(called = Loc.server, in = In.blocks) - public static void onMechFactoryDone(Tile tile){ - MechFactoryEntity entity = tile.entity(); - - Effects.effect(Fx.spawn, entity); - - if(entity.player == null) return; - - Mech result = ((MechFactory)tile.block()).mech; - - if(entity.player.mech == result){ - entity.player.mech = (entity.player.isMobile ? Mechs.starterMobile : Mechs.starterDesktop); - }else{ - entity.player.mech = result; - } - - entity.progress = 0; - entity.player.heal(); - entity.open = true; - entity.player.setDead(false); - entity.player.inventory.clear(); - entity.player = null; - } - - protected static boolean checkValidTap(Tile tile, Player player){ - MechFactoryEntity entity = tile.entity(); - return Math.abs(player.x - tile.drawx()) <= tile.block().size * tilesize / 2f && - Math.abs(player.y - tile.drawy()) <= tile.block().size * tilesize / 2f && entity.player == null; - } - public class MechFactoryEntity extends TileEntity implements SpawnerTrait{ Player player; float progress; @@ -183,12 +183,13 @@ public class MechFactory extends Block{ boolean open; @Override - public void updateSpawning(Unit unit) { - if(!(unit instanceof Player)) throw new IllegalArgumentException("Mech factories only accept player respawners."); + public void updateSpawning(Unit unit){ + if(!(unit instanceof Player)) + throw new IllegalArgumentException("Mech factories only accept player respawners."); if(player == null){ progress = 0f; - player = (Player)unit; + player = (Player) unit; player.rotation = 90f; player.baseRotation = 90f; @@ -198,19 +199,19 @@ public class MechFactory extends Block{ } @Override - public float getSpawnProgress() { + public float getSpawnProgress(){ return progress; } @Override - public void write(DataOutputStream stream) throws IOException { + public void write(DataOutputStream stream) throws IOException{ stream.writeFloat(progress); stream.writeFloat(time); stream.writeFloat(heat); } @Override - public void read(DataInputStream stream) throws IOException { + public void read(DataInputStream stream) throws IOException{ progress = stream.readFloat(); time = stream.readFloat(); heat = stream.readFloat(); diff --git a/core/src/io/anuke/mindustry/world/blocks/units/OverdriveProjector.java b/core/src/io/anuke/mindustry/world/blocks/units/OverdriveProjector.java index 7acecd1414..740f631053 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/OverdriveProjector.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/OverdriveProjector.java @@ -2,9 +2,9 @@ package io.anuke.mindustry.world.blocks.units; import io.anuke.mindustry.content.StatusEffects; -public class OverdriveProjector extends Projector { +public class OverdriveProjector extends Projector{ - public OverdriveProjector(String name) { + public OverdriveProjector(String name){ super(name); status = StatusEffects.overdrive; diff --git a/core/src/io/anuke/mindustry/world/blocks/units/Projector.java b/core/src/io/anuke/mindustry/world/blocks/units/Projector.java index 55ddcd1e78..0b05f77f7e 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/Projector.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/Projector.java @@ -11,7 +11,7 @@ import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.Lines; import io.anuke.ucore.util.Mathf; -public abstract class Projector extends Block { +public abstract class Projector extends Block{ protected final int timerApply = timers++; protected final float applyTime = 4f; @@ -20,7 +20,7 @@ public abstract class Projector extends Block { protected StatusEffect status; protected float intensity = 1f; - public Projector(String name) { + public Projector(String name){ super(name); hasPower = true; update = true; @@ -35,7 +35,7 @@ public abstract class Projector extends Block { } @Override - public void update(Tile tile) { + public void update(Tile tile){ ProjectorEntity entity = tile.entity(); if(entity.cons.valid()){ @@ -44,7 +44,7 @@ public abstract class Projector extends Block { entity.heat = Mathf.lerpDelta(entity.heat, 0f, 0.01f); } - if(entity.heat > 0.6f && Timers.get(timerApply, applyTime)) { + if(entity.heat > 0.6f && Timers.get(timerApply, applyTime)){ Units.getNearby(tile.getTeam(), tile.drawx(), tile.drawy(), range, unit -> { unit.applyEffect(status, intensity); }); @@ -52,7 +52,7 @@ public abstract class Projector extends Block { } @Override - public TileEntity getEntity() { + public TileEntity getEntity(){ return new ProjectorEntity(); } diff --git a/core/src/io/anuke/mindustry/world/blocks/units/Reconstructor.java b/core/src/io/anuke/mindustry/world/blocks/units/Reconstructor.java index d893038086..02e74a5f1e 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/Reconstructor.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/Reconstructor.java @@ -38,7 +38,7 @@ public class Reconstructor extends Block{ protected Effect arriveEffect = Fx.spawn; protected TextureRegion openRegion; - public Reconstructor(String name) { + public Reconstructor(String name){ super(name); update = true; solidifes = true; @@ -46,191 +46,11 @@ public class Reconstructor extends Block{ configurable = true; } - @Override - public void load() { - super.load(); - openRegion = Draw.region(name + "-open"); - } - - @Override - public boolean isSolidFor(Tile tile) { - ReconstructorEntity entity = tile.entity(); - - return entity.solid; - } - - @Override - public void drawConfigure(Tile tile) { - super.drawConfigure(tile); - - ReconstructorEntity entity = tile.entity(); - - if(validLink(tile, entity.link)){ - Tile target = world.tile(entity.link); - - Draw.color(Palette.place); - Lines.square(target.drawx(), target.drawy(), - target.block().size * tilesize / 2f + 1f); - Draw.reset(); - } - - Draw.color(Palette.accent); - Draw.color(); - } - - @Override - public boolean onConfigureTileTapped(Tile tile, Tile other){ - if(tile == other) return false; - - ReconstructorEntity entity = tile.entity(); - - if(entity.link == other.packedPosition()) { - CallBlocks.unlinkReconstructor(null, tile, other); - return false; - }else if(other.block() instanceof Reconstructor){ - CallBlocks.linkReconstructor(null, tile, other); - return false; - } - - return true; - } - - @Override - public boolean shouldShowConfigure(Tile tile, Player player) { - ReconstructorEntity entity = tile.entity(); - return !checkValidTap(tile, entity, player); - } - - @Override - public boolean shouldHideConfigure(Tile tile, Player player){ - ReconstructorEntity entity = tile.entity(); - return checkValidTap(tile, entity, player); - } - - @Override - public void draw(Tile tile) { - ReconstructorEntity entity = tile.entity(); - - if(entity.solid){ - Draw.rect(region, tile.drawx(), tile.drawy()); - }else{ - Draw.rect(openRegion, tile.drawx(), tile.drawy()); - } - - if(entity.current != null){ - float progress = entity.departing ? entity.updateTime : (1f - entity.updateTime); - - //Player player = entity.current; - - TextureRegion region = entity.current.getIconRegion(); - - Shaders.build.region = region; - Shaders.build.progress = progress; - Shaders.build.color.set(Palette.accent); - Shaders.build.time = -entity.time / 10f; - - Graphics.shader(Shaders.build, false); - Shaders.build.apply(); - Draw.rect(region, tile.drawx(), tile.drawy()); - Graphics.shader(); - - Draw.color(Palette.accent); - - Lines.lineAngleCenter( - tile.drawx() + Mathf.sin(entity.time, 6f, Vars.tilesize / 3f * size), - tile.drawy(), - 90, - size * Vars.tilesize /2f); - - Draw.reset(); - } - } - - @Override - public void update(Tile tile) { - ReconstructorEntity entity = tile.entity(); - - boolean stayOpen = false; - - if(entity.current != null){ - entity.time += Timers.delta(); - - entity.solid = true; - - if(entity.departing){ - //force respawn if there's suddenly nothing to link to - if(!validLink(tile, entity.link)){ - //entity.current.setRespawning(false); - return; - } - - ReconstructorEntity other = world.tile(entity.link).entity(); - - entity.updateTime -= Timers.delta()/departTime; - if(entity.updateTime <= 0f){ - //no power? death. - if(other.power.amount < powerPerTeleport){ - entity.current.setDead(true); - //entity.current.setRespawning(false); - entity.current = null; - return; - } - other.power.amount -= powerPerTeleport; - other.current = entity.current; - other.departing = false; - other.current.set(other.x, other.y); - other.updateTime = 1f; - entity.current = null; - } - }else{ //else, arriving - entity.updateTime -= Timers.delta()/arriveTime; - - if(entity.updateTime <= 0f){ - entity.solid = false; - entity.current.setDead(false); - - Effects.effect(arriveEffect, entity.current); - - entity.current = null; - } - } - - }else{ - - if (validLink(tile, entity.link)) { - Tile other = world.tile(entity.link); - if (other.entity.power.amount >= powerPerTeleport && Units.anyEntities(tile, 4f, unit -> unit.getTeam() == entity.getTeam() && unit instanceof Player) && - entity.power.amount >= powerPerTeleport) { - entity.solid = false; - stayOpen = true; - } - } - - if (!stayOpen && !entity.solid && !Units.anyEntities(tile)) { - entity.solid = true; - } - } - } - - @Override - public void tapped(Tile tile, Player player) { - ReconstructorEntity entity = tile.entity(); - - if(!checkValidTap(tile, entity, player)) return; - - CallBlocks.reconstructPlayer(player, tile); - } - - @Override - public TileEntity getEntity() { - return new ReconstructorEntity(); - } - protected static boolean checkValidTap(Tile tile, ReconstructorEntity entity, Player player){ return validLink(tile, entity.link) && Math.abs(player.x - tile.drawx()) <= tile.block().size * tilesize / 2f && Math.abs(player.y - tile.drawy()) <= tile.block().size * tilesize / 2f && - entity.current == null && entity.power.amount >= ((Reconstructor)tile.block()).powerPerTeleport; + entity.current == null && entity.power.amount >= ((Reconstructor) tile.block()).powerPerTeleport; } protected static boolean validLink(Tile tile, int position){ @@ -255,18 +75,19 @@ public class Reconstructor extends Block{ public static void reconstructPlayer(Player player, Tile tile){ ReconstructorEntity entity = tile.entity(); - if(!checkValidTap(tile, entity, player) || entity.power.amount < ((Reconstructor)tile.block()).powerPerTeleport) return; + if(!checkValidTap(tile, entity, player) || entity.power.amount < ((Reconstructor) tile.block()).powerPerTeleport) + return; entity.departing = true; entity.current = player; entity.solid = false; - entity.power.amount -= ((Reconstructor)tile.block()).powerPerTeleport; + entity.power.amount -= ((Reconstructor) tile.block()).powerPerTeleport; entity.updateTime = 1f; entity.set(tile.drawx(), tile.drawy()); player.rotation = 90f; player.baseRotation = 90f; player.setDead(true); - // player.setRespawning(true); + // player.setRespawning(true); //player.setRespawning(); } @@ -303,6 +124,186 @@ public class Reconstructor extends Block{ }); } + @Override + public void load(){ + super.load(); + openRegion = Draw.region(name + "-open"); + } + + @Override + public boolean isSolidFor(Tile tile){ + ReconstructorEntity entity = tile.entity(); + + return entity.solid; + } + + @Override + public void drawConfigure(Tile tile){ + super.drawConfigure(tile); + + ReconstructorEntity entity = tile.entity(); + + if(validLink(tile, entity.link)){ + Tile target = world.tile(entity.link); + + Draw.color(Palette.place); + Lines.square(target.drawx(), target.drawy(), + target.block().size * tilesize / 2f + 1f); + Draw.reset(); + } + + Draw.color(Palette.accent); + Draw.color(); + } + + @Override + public boolean onConfigureTileTapped(Tile tile, Tile other){ + if(tile == other) return false; + + ReconstructorEntity entity = tile.entity(); + + if(entity.link == other.packedPosition()){ + CallBlocks.unlinkReconstructor(null, tile, other); + return false; + }else if(other.block() instanceof Reconstructor){ + CallBlocks.linkReconstructor(null, tile, other); + return false; + } + + return true; + } + + @Override + public boolean shouldShowConfigure(Tile tile, Player player){ + ReconstructorEntity entity = tile.entity(); + return !checkValidTap(tile, entity, player); + } + + @Override + public boolean shouldHideConfigure(Tile tile, Player player){ + ReconstructorEntity entity = tile.entity(); + return checkValidTap(tile, entity, player); + } + + @Override + public void draw(Tile tile){ + ReconstructorEntity entity = tile.entity(); + + if(entity.solid){ + Draw.rect(region, tile.drawx(), tile.drawy()); + }else{ + Draw.rect(openRegion, tile.drawx(), tile.drawy()); + } + + if(entity.current != null){ + float progress = entity.departing ? entity.updateTime : (1f - entity.updateTime); + + //Player player = entity.current; + + TextureRegion region = entity.current.getIconRegion(); + + Shaders.build.region = region; + Shaders.build.progress = progress; + Shaders.build.color.set(Palette.accent); + Shaders.build.time = -entity.time / 10f; + + Graphics.shader(Shaders.build, false); + Shaders.build.apply(); + Draw.rect(region, tile.drawx(), tile.drawy()); + Graphics.shader(); + + Draw.color(Palette.accent); + + Lines.lineAngleCenter( + tile.drawx() + Mathf.sin(entity.time, 6f, Vars.tilesize / 3f * size), + tile.drawy(), + 90, + size * Vars.tilesize / 2f); + + Draw.reset(); + } + } + + @Override + public void update(Tile tile){ + ReconstructorEntity entity = tile.entity(); + + boolean stayOpen = false; + + if(entity.current != null){ + entity.time += Timers.delta(); + + entity.solid = true; + + if(entity.departing){ + //force respawn if there's suddenly nothing to link to + if(!validLink(tile, entity.link)){ + //entity.current.setRespawning(false); + return; + } + + ReconstructorEntity other = world.tile(entity.link).entity(); + + entity.updateTime -= Timers.delta() / departTime; + if(entity.updateTime <= 0f){ + //no power? death. + if(other.power.amount < powerPerTeleport){ + entity.current.setDead(true); + //entity.current.setRespawning(false); + entity.current = null; + return; + } + other.power.amount -= powerPerTeleport; + other.current = entity.current; + other.departing = false; + other.current.set(other.x, other.y); + other.updateTime = 1f; + entity.current = null; + } + }else{ //else, arriving + entity.updateTime -= Timers.delta() / arriveTime; + + if(entity.updateTime <= 0f){ + entity.solid = false; + entity.current.setDead(false); + + Effects.effect(arriveEffect, entity.current); + + entity.current = null; + } + } + + }else{ + + if(validLink(tile, entity.link)){ + Tile other = world.tile(entity.link); + if(other.entity.power.amount >= powerPerTeleport && Units.anyEntities(tile, 4f, unit -> unit.getTeam() == entity.getTeam() && unit instanceof Player) && + entity.power.amount >= powerPerTeleport){ + entity.solid = false; + stayOpen = true; + } + } + + if(!stayOpen && !entity.solid && !Units.anyEntities(tile)){ + entity.solid = true; + } + } + } + + @Override + public void tapped(Tile tile, Player player){ + ReconstructorEntity entity = tile.entity(); + + if(!checkValidTap(tile, entity, player)) return; + + CallBlocks.reconstructPlayer(player, tile); + } + + @Override + public TileEntity getEntity(){ + return new ReconstructorEntity(); + } + public class ReconstructorEntity extends TileEntity implements SpawnerTrait{ Unit current; float updateTime; @@ -311,22 +312,22 @@ public class Reconstructor extends Block{ boolean solid = true, departing; @Override - public void updateSpawning(Unit unit) { + public void updateSpawning(Unit unit){ } @Override - public float getSpawnProgress() { + public float getSpawnProgress(){ return 0; } @Override - public void write(DataOutputStream stream) throws IOException { + public void write(DataOutputStream stream) throws IOException{ stream.writeInt(link); } @Override - public void read(DataInputStream stream) throws IOException { + public void read(DataInputStream stream) throws IOException{ link = stream.readInt(); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/units/RepairPoint.java b/core/src/io/anuke/mindustry/world/blocks/units/RepairPoint.java index d592f7817e..e2e152509e 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/RepairPoint.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/RepairPoint.java @@ -9,8 +9,8 @@ import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.graphics.Layer; import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.world.Block; -import io.anuke.mindustry.world.meta.BlockFlag; import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.meta.BlockFlag; import io.anuke.ucore.core.Timers; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.Lines; @@ -22,14 +22,14 @@ import io.anuke.ucore.util.Mathf; public class RepairPoint extends Block{ private static Rectangle rect = new Rectangle(); - protected int timerTarget = timers ++; + protected int timerTarget = timers++; protected float repairRadius = 50f; protected float repairSpeed = 0.3f; protected TextureRegion topRegion; - public RepairPoint(String name) { + public RepairPoint(String name){ super(name); update = true; solid = true; @@ -42,7 +42,7 @@ public class RepairPoint extends Block{ } @Override - public void load() { + public void load(){ super.load(); topRegion = Draw.region(name + "-turret"); @@ -56,14 +56,14 @@ public class RepairPoint extends Block{ } @Override - public void drawLayer(Tile tile) { + public void drawLayer(Tile tile){ RepairPointEntity entity = tile.entity(); Draw.rect(topRegion, tile.drawx(), tile.drawy(), entity.rotation - 90); } @Override - public void drawLayer2(Tile tile) { + public void drawLayer2(Tile tile){ RepairPointEntity entity = tile.entity(); if(entity.target != null && @@ -80,11 +80,11 @@ public class RepairPoint extends Block{ } @Override - public void update(Tile tile) { + public void update(Tile tile){ RepairPointEntity entity = tile.entity(); if(entity.target != null && (entity.target.isDead() || entity.target.distanceTo(tile) > repairRadius || - entity.target.health >= entity.target.maxHealth())){ + entity.target.health >= entity.target.maxHealth())){ entity.target = null; }else if(entity.target != null){ entity.target.health += repairSpeed * Timers.delta() * entity.strength; @@ -98,7 +98,7 @@ public class RepairPoint extends Block{ entity.strength = Mathf.lerpDelta(entity.strength, 0f, 0.07f * Timers.delta()); } - if(entity.timer.get(timerTarget, 20)) { + if(entity.timer.get(timerTarget, 20)){ rect.setSize(repairRadius * 2).setCenter(tile.drawx(), tile.drawy()); entity.target = Units.getClosest(tile.getTeam(), tile.drawx(), tile.drawy(), repairRadius, unit -> unit.health < unit.maxHealth()); @@ -106,14 +106,14 @@ public class RepairPoint extends Block{ } @Override - public boolean shouldConsume(Tile tile) { + public boolean shouldConsume(Tile tile){ RepairPointEntity entity = tile.entity(); return entity.target != null; } @Override - public TileEntity getEntity() { + public TileEntity getEntity(){ return new RepairPointEntity(); } diff --git a/core/src/io/anuke/mindustry/world/blocks/units/ResupplyPoint.java b/core/src/io/anuke/mindustry/world/blocks/units/ResupplyPoint.java index adaaeddb34..12aa4b3ce6 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/ResupplyPoint.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/ResupplyPoint.java @@ -9,8 +9,8 @@ import io.anuke.mindustry.graphics.Layer; import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.Block; -import io.anuke.mindustry.world.meta.BlockFlag; import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.meta.BlockFlag; import io.anuke.ucore.core.Timers; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.Lines; @@ -22,13 +22,13 @@ import io.anuke.ucore.util.Mathf; public class ResupplyPoint extends Block{ private static Rectangle rect = new Rectangle(); - protected int timerSupply = timers ++; - protected int timerTarget = timers ++; + protected int timerSupply = timers++; + protected int timerTarget = timers++; protected float supplyRadius = 50f; protected float supplyInterval = 10f; - public ResupplyPoint(String name) { + public ResupplyPoint(String name){ super(name); update = true; solid = true; @@ -49,7 +49,7 @@ public class ResupplyPoint extends Block{ } @Override - public void drawLayer(Tile tile) { + public void drawLayer(Tile tile){ ResupplyPointEntity entity = tile.entity(); if(entity.strength > 0f){ @@ -65,11 +65,11 @@ public class ResupplyPoint extends Block{ x1, y1, entity.lastx, entity.lasty, entity.strength); Draw.color(Palette.accent); - for(int i = 0; i < dstTo/space-1; i ++){ - float fract = (i * space) / dstTo + ((Timers.time()/90f) % (space/dstTo)); - Draw.alpha(Mathf.clamp(fract*1.5f)); - Draw.rect("transfer-arrow", x1 + fract*xf, y1 + fract*yf, - 8, 8*entity.strength, ang); + for(int i = 0; i < dstTo / space - 1; i++){ + float fract = (i * space) / dstTo + ((Timers.time() / 90f) % (space / dstTo)); + Draw.alpha(Mathf.clamp(fract * 1.5f)); + Draw.rect("transfer-arrow", x1 + fract * xf, y1 + fract * yf, + 8, 8 * entity.strength, ang); } Draw.color(); @@ -78,17 +78,17 @@ public class ResupplyPoint extends Block{ } @Override - public void update(Tile tile) { + public void update(Tile tile){ ResupplyPointEntity entity = tile.entity(); if(!validTarget(entity, entity.target) || entity.target.distanceTo(tile) > supplyRadius){ entity.target = null; }else if(entity.target != null && entity.strength > 0.5f){ - if(entity.timer.get(timerSupply, supplyInterval)) { - for (int i = 0; i < Item.all().size; i++) { + if(entity.timer.get(timerSupply, supplyInterval)){ + for(int i = 0; i < Item.all().size; i++){ Item item = Item.getByID(i); - if (tile.entity.items.has(item) && entity.target.acceptsAmmo(item)) { + if(tile.entity.items.has(item) && entity.target.acceptsAmmo(item)){ tile.entity.items.remove(item, 1); entity.target.addAmmo(item); break; @@ -107,7 +107,7 @@ public class ResupplyPoint extends Block{ entity.strength = Mathf.lerpDelta(entity.strength, 0f, 0.08f * Timers.delta()); } - if(entity.timer.get(timerTarget, 20)) { + if(entity.timer.get(timerTarget, 20)){ rect.setSize(supplyRadius * 2).setCenter(tile.drawx(), tile.drawy()); entity.target = Units.getClosest(tile.getTeam(), tile.drawx(), tile.drawy(), supplyRadius, unit -> validTarget(entity, unit)); @@ -115,12 +115,12 @@ public class ResupplyPoint extends Block{ } @Override - public boolean acceptItem(Item item, Tile tile, Tile source) { + public boolean acceptItem(Item item, Tile tile, Tile source){ return tile.entity.items.total() < itemCapacity; } @Override - public TileEntity getEntity() { + public TileEntity getEntity(){ return new ResupplyPointEntity(); } @@ -128,9 +128,9 @@ public class ResupplyPoint extends Block{ if(unit == null || unit.inventory.totalAmmo() >= unit.inventory.ammoCapacity() || unit.isDead()) return false; - for (int i = 0; i < Item.all().size; i++) { + for(int i = 0; i < Item.all().size; i++){ Item item = Item.getByID(i); - if (entity.items.has(item) && unit.acceptsAmmo(item)) { + if(entity.items.has(item) && unit.acceptsAmmo(item)){ return true; } } diff --git a/core/src/io/anuke/mindustry/world/blocks/units/ShieldProjector.java b/core/src/io/anuke/mindustry/world/blocks/units/ShieldProjector.java index 7f171fe193..aab518b7b1 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/ShieldProjector.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/ShieldProjector.java @@ -2,9 +2,9 @@ package io.anuke.mindustry.world.blocks.units; import io.anuke.mindustry.content.StatusEffects; -public class ShieldProjector extends Projector { +public class ShieldProjector extends Projector{ - public ShieldProjector(String name) { + public ShieldProjector(String name){ super(name); status = StatusEffects.shielded; diff --git a/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java b/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java index a68d7562b5..98142a6972 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java @@ -35,14 +35,14 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; -public class UnitFactory extends Block { +public class UnitFactory extends Block{ protected UnitType type; protected float produceTime = 1000f; protected float openDuration = 50f; protected float launchVelocity = 0f; protected String unitRegion; - public UnitFactory(String name) { + public UnitFactory(String name){ super(name); update = true; hasPower = true; @@ -52,21 +52,41 @@ public class UnitFactory extends Block { consumes.require(ConsumeItems.class); } - @Override - public void setStats() { - super.setStats(); + @Remote(called = Loc.server, in = In.blocks) + public static void onUnitFactorySpawn(Tile tile){ + UnitFactoryEntity entity = tile.entity(); + UnitFactory factory = (UnitFactory) tile.block(); - stats.add(BlockStat.craftSpeed, produceTime/60f, StatUnit.seconds); + entity.buildTime = 0f; + entity.hasSpawned = true; + + Effects.shake(2f, 3f, entity); + Effects.effect(BlockFx.producesmoke, tile.drawx(), tile.drawy()); + + if(!Net.client()){ + BaseUnit unit = factory.type.create(tile.getTeam()); + unit.setSpawner(tile); + unit.set(tile.drawx(), tile.drawy()); + unit.add(); + unit.getVelocity().y = factory.launchVelocity; + } } @Override - public boolean isSolidFor(Tile tile) { + public void setStats(){ + super.setStats(); + + stats.add(BlockStat.craftSpeed, produceTime / 60f, StatUnit.seconds); + } + + @Override + public boolean isSolidFor(Tile tile){ UnitFactoryEntity entity = tile.entity(); return type.isFlying || !entity.open; } @Override - public void setBars() { + public void setBars(){ super.setBars(); bars.add(new BlockBar(BarType.production, true, tile -> tile.entity().buildTime / produceTime)); @@ -74,22 +94,22 @@ public class UnitFactory extends Block { } @Override - public TextureRegion[] getIcon() { + public TextureRegion[] getIcon(){ return new TextureRegion[]{ - Draw.region(name), - Draw.region(name + "-top") + Draw.region(name), + Draw.region(name + "-top") }; } @Override - public void draw(Tile tile) { + public void draw(Tile tile){ UnitFactoryEntity entity = tile.entity(); TextureRegion region = Draw.region(unitRegion == null ? type.name : unitRegion); Draw.rect(name(), tile.drawx(), tile.drawy()); Shaders.build.region = region; - Shaders.build.progress = entity.buildTime/produceTime; + Shaders.build.progress = entity.buildTime / produceTime; Shaders.build.color.set(Palette.accent); Shaders.build.color.a = entity.speedScl; Shaders.build.time = -entity.time / 10f; @@ -103,7 +123,7 @@ public class UnitFactory extends Block { Draw.alpha(entity.speedScl); Lines.lineAngleCenter( - tile.drawx() + Mathf.sin(entity.time, 6f, Vars.tilesize/2f*size - 2f), + tile.drawx() + Mathf.sin(entity.time, 6f, Vars.tilesize / 2f * size - 2f), tile.drawy(), 90, size * Vars.tilesize - 4f); @@ -114,7 +134,7 @@ public class UnitFactory extends Block { } @Override - public void update(Tile tile) { + public void update(Tile tile){ UnitFactoryEntity entity = tile.entity(); entity.time += Timers.delta() * entity.speedScl; @@ -123,7 +143,7 @@ public class UnitFactory extends Block { if(entity.openCountdown > Timers.delta()){ entity.openCountdown -= Timers.delta(); }else{ - if(type.isFlying || !Units.anyEntities(tile)) { + if(type.isFlying || !Units.anyEntities(tile)){ entity.open = false; entity.openCountdown = -1; }else{ @@ -143,7 +163,7 @@ public class UnitFactory extends Block { } }*/ - if(!entity.hasSpawned && hasRequirements(entity.items, entity.buildTime/produceTime) && + if(!entity.hasSpawned && hasRequirements(entity.items, entity.buildTime / produceTime) && entity.cons.valid() && !entity.open){ entity.buildTime += Timers.delta(); @@ -166,9 +186,9 @@ public class UnitFactory extends Block { } @Override - public boolean acceptItem(Item item, Tile tile, Tile source) { + public boolean acceptItem(Item item, Tile tile, Tile source){ for(ItemStack stack : consumes.items()){ - if(item == stack.item && tile.entity.items.get(item) <= stack.amount*2){ + if(item == stack.item && tile.entity.items.get(item) <= stack.amount * 2){ return true; } } @@ -176,39 +196,19 @@ public class UnitFactory extends Block { } @Override - public TileEntity getEntity() { + public TileEntity getEntity(){ return new UnitFactoryEntity(); } protected boolean hasRequirements(InventoryModule inv, float fraction){ for(ItemStack stack : consumes.items()){ - if(!inv.has(stack.item, (int)(fraction * stack.amount))){ + if(!inv.has(stack.item, (int) (fraction * stack.amount))){ return false; } } return true; } - @Remote(called = Loc.server, in = In.blocks) - public static void onUnitFactorySpawn(Tile tile){ - UnitFactoryEntity entity = tile.entity(); - UnitFactory factory = (UnitFactory)tile.block(); - - entity.buildTime = 0f; - entity.hasSpawned = true; - - Effects.shake(2f, 3f, entity); - Effects.effect(BlockFx.producesmoke, tile.drawx(), tile.drawy()); - - if(!Net.client()) { - BaseUnit unit = factory.type.create(tile.getTeam()); - unit.setSpawner(tile); - unit.set(tile.drawx(), tile.drawy()); - unit.add(); - unit.getVelocity().y = factory.launchVelocity; - } - } - public static class UnitFactoryEntity extends TileEntity{ public float buildTime; public boolean open; @@ -218,13 +218,13 @@ public class UnitFactory extends Block { public boolean hasSpawned; @Override - public void write(DataOutputStream stream) throws IOException { + public void write(DataOutputStream stream) throws IOException{ stream.writeFloat(buildTime); stream.writeBoolean(hasSpawned); } @Override - public void read(DataInputStream stream) throws IOException { + public void read(DataInputStream stream) throws IOException{ buildTime = stream.readFloat(); hasSpawned = stream.readBoolean(); } diff --git a/core/src/io/anuke/mindustry/world/blocks/units/UnloadPoint.java b/core/src/io/anuke/mindustry/world/blocks/units/UnloadPoint.java index 6d2ef8d2d6..b7dfd4ae7e 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/UnloadPoint.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/UnloadPoint.java @@ -1,4 +1,4 @@ package io.anuke.mindustry.world.blocks.units; -public class UnloadPoint { +public class UnloadPoint{ } diff --git a/core/src/io/anuke/mindustry/world/consumers/Consume.java b/core/src/io/anuke/mindustry/world/consumers/Consume.java index c26cd66e27..8408389933 100644 --- a/core/src/io/anuke/mindustry/world/consumers/Consume.java +++ b/core/src/io/anuke/mindustry/world/consumers/Consume.java @@ -10,11 +10,11 @@ import io.anuke.ucore.scene.ui.layout.Table; import static io.anuke.mindustry.Vars.mobile; -public abstract class Consume { +public abstract class Consume{ private boolean optional; private boolean update = true; - public Consume optional(boolean optional) { + public Consume optional(boolean optional){ this.optional = optional; return this; } @@ -24,11 +24,11 @@ public abstract class Consume { return this; } - public boolean isOptional() { + public boolean isOptional(){ return optional; } - public boolean isUpdate() { + public boolean isUpdate(){ return update; } @@ -40,16 +40,19 @@ public abstract class Consume { int scale = mobile ? 4 : 3; table.table(out -> { - out.addImage(getIcon()).size(10*scale).color(Color.DARK_GRAY).padRight(-10*scale).padBottom(-scale*2); - out.addImage(getIcon()).size(10*scale).color(Palette.accent); - out.addImage("icon-missing").size(10*scale).color(Palette.remove).padLeft(-10*scale); - }).size(10*scale).get().addListener(new Tooltip<>(t)); + out.addImage(getIcon()).size(10 * scale).color(Color.DARK_GRAY).padRight(-10 * scale).padBottom(-scale * 2); + out.addImage(getIcon()).size(10 * scale).color(Palette.accent); + out.addImage("icon-missing").size(10 * scale).color(Palette.remove).padLeft(-10 * scale); + }).size(10 * scale).get().addListener(new Tooltip<>(t)); } public abstract void buildTooltip(Table table); public abstract String getIcon(); + public abstract void update(Block block, TileEntity entity); + public abstract boolean valid(Block block, TileEntity entity); + public abstract void display(BlockStats stats); } diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumeItem.java b/core/src/io/anuke/mindustry/world/consumers/ConsumeItem.java index 91041bec16..61be341aa9 100644 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumeItem.java +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumeItem.java @@ -9,50 +9,50 @@ import io.anuke.mindustry.world.meta.BlockStat; import io.anuke.mindustry.world.meta.BlockStats; import io.anuke.ucore.scene.ui.layout.Table; -public class ConsumeItem extends Consume { +public class ConsumeItem extends Consume{ private final Item item; private final int amount; - public ConsumeItem(Item item) { + public ConsumeItem(Item item){ this.item = item; this.amount = 1; } - public ConsumeItem(Item item, int amount) { + public ConsumeItem(Item item, int amount){ this.item = item; this.amount = amount; } - public int getAmount() { + public int getAmount(){ return amount; } - public Item get() { + public Item get(){ return item; } @Override - public void buildTooltip(Table table) { - table.add(new ItemImage(new ItemStack(item, amount))).size(8*4); + public void buildTooltip(Table table){ + table.add(new ItemImage(new ItemStack(item, amount))).size(8 * 4); } @Override - public String getIcon() { + public String getIcon(){ return "icon-item"; } @Override - public void update(Block block, TileEntity entity) { + public void update(Block block, TileEntity entity){ //doesn't update because consuming items is very specific } @Override - public boolean valid(Block block, TileEntity entity) { + public boolean valid(Block block, TileEntity entity){ return entity.items.has(item, amount); } @Override - public void display(BlockStats stats) { + public void display(BlockStats stats){ stats.add(BlockStat.inputItem, item); } } diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumeItemFilter.java b/core/src/io/anuke/mindustry/world/consumers/ConsumeItemFilter.java index e226ad49b9..6860fee801 100644 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumeItemFilter.java +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumeItemFilter.java @@ -13,21 +13,21 @@ import io.anuke.ucore.scene.ui.layout.Table; public class ConsumeItemFilter extends Consume{ private final Predicate filter; - public ConsumeItemFilter(Predicate item) { + public ConsumeItemFilter(Predicate item){ this.filter = item; } @Override - public void buildTooltip(Table table) { + public void buildTooltip(Table table){ Array list = new Array<>(); for(Item item : Item.all()){ if(filter.test(item)) list.add(item); } - for (int i = 0; i < list.size; i++) { + for(int i = 0; i < list.size; i++){ Item item = list.get(i); - table.addImage(item.region).size(8*4).padRight(2).padLeft(2); + table.addImage(item.region).size(8 * 4).padRight(2).padLeft(2); if(i != list.size - 1){ table.add("/"); } @@ -35,18 +35,18 @@ public class ConsumeItemFilter extends Consume{ } @Override - public String getIcon() { + public String getIcon(){ return "icon-item"; } @Override - public void update(Block block, TileEntity entity) { + public void update(Block block, TileEntity entity){ } @Override - public boolean valid(Block block, TileEntity entity) { - for(int i = 0; i < Item.all().size; i ++){ + public boolean valid(Block block, TileEntity entity){ + for(int i = 0; i < Item.all().size; i++){ Item item = Item.getByID(i); if(entity.items.has(item) && this.filter.test(item)){ return true; @@ -56,7 +56,7 @@ public class ConsumeItemFilter extends Consume{ } @Override - public void display(BlockStats stats) { + public void display(BlockStats stats){ stats.add(BlockStat.inputItems, new ItemFilterValue(filter)); } } diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumeItems.java b/core/src/io/anuke/mindustry/world/consumers/ConsumeItems.java index c6336105f3..4215ac2fc2 100644 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumeItems.java +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumeItems.java @@ -9,41 +9,41 @@ import io.anuke.mindustry.world.meta.BlockStats; import io.anuke.mindustry.world.meta.values.ItemListValue; import io.anuke.ucore.scene.ui.layout.Table; -public class ConsumeItems extends Consume { +public class ConsumeItems extends Consume{ private ItemStack[] items; - public ConsumeItems(ItemStack[] items) { + public ConsumeItems(ItemStack[] items){ this.items = items; } - public ItemStack[] getItems() { + public ItemStack[] getItems(){ return items; } @Override - public void buildTooltip(Table table) { + public void buildTooltip(Table table){ for(ItemStack stack : items){ - table.add(new ItemImage(stack)).size(8*4).padRight(5); + table.add(new ItemImage(stack)).size(8 * 4).padRight(5); } } @Override - public String getIcon() { + public String getIcon(){ return "icon-item"; } @Override - public void update(Block block, TileEntity entity) { + public void update(Block block, TileEntity entity){ } @Override - public boolean valid(Block block, TileEntity entity) { + public boolean valid(Block block, TileEntity entity){ return entity.items.has(items); } @Override - public void display(BlockStats stats) { + public void display(BlockStats stats){ stats.add(BlockStat.inputItems, new ItemListValue(items)); } } diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquid.java b/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquid.java index 084e7cbe60..f8962ae760 100644 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquid.java +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquid.java @@ -9,50 +9,50 @@ import io.anuke.mindustry.world.meta.StatUnit; import io.anuke.ucore.core.Timers; import io.anuke.ucore.scene.ui.layout.Table; -public class ConsumeLiquid extends Consume { +public class ConsumeLiquid extends Consume{ protected final float use; protected final Liquid liquid; - public ConsumeLiquid(Liquid liquid, float use) { + public ConsumeLiquid(Liquid liquid, float use){ this.liquid = liquid; this.use = use; } - public float used() { + public float used(){ return use; } - public Liquid get() { + public Liquid get(){ return liquid; } @Override - public void buildTooltip(Table table) { - table.addImage(liquid.getContentIcon()).size(8*3); + public void buildTooltip(Table table){ + table.addImage(liquid.getContentIcon()).size(8 * 3); } @Override - public String getIcon() { + public String getIcon(){ return "icon-liquid"; } @Override - public void update(Block block, TileEntity entity) { + public void update(Block block, TileEntity entity){ entity.liquids.remove(liquid, Math.min(use(block), entity.liquids.get(liquid))); } @Override - public boolean valid(Block block, TileEntity entity) { + public boolean valid(Block block, TileEntity entity){ return entity.liquids.get(liquid) >= use(block); } @Override - public void display(BlockStats stats) { + public void display(BlockStats stats){ stats.add(BlockStat.liquidUse, use * 60f, StatUnit.liquidSecond); stats.add(BlockStat.inputLiquid, liquid); } - float use(Block block) { + float use(Block block){ return Math.min(use * Timers.delta(), block.liquidCapacity); } } diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquidFilter.java b/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquidFilter.java index c6e818dbdc..abbd36df25 100644 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquidFilter.java +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquidFilter.java @@ -17,7 +17,7 @@ public class ConsumeLiquidFilter extends Consume{ private final float use; private final boolean isFuel; - public ConsumeLiquidFilter(Predicate liquid, float amount, boolean isFuel) { + public ConsumeLiquidFilter(Predicate liquid, float amount, boolean isFuel){ this.filter = liquid; this.use = amount; this.isFuel = isFuel; @@ -28,16 +28,16 @@ public class ConsumeLiquidFilter extends Consume{ } @Override - public void buildTooltip(Table table) { + public void buildTooltip(Table table){ Array list = new Array<>(); for(Liquid item : Liquid.all()){ if(!item.isHidden() && filter.test(item)) list.add(item); } - for (int i = 0; i < list.size; i++) { + for(int i = 0; i < list.size; i++){ Liquid item = list.get(i); - table.addImage(item.getContentIcon()).size(8*3).padRight(2).padLeft(2).padTop(2).padBottom(2); + table.addImage(item.getContentIcon()).size(8 * 3).padRight(2).padLeft(2).padTop(2).padBottom(2); if(i != list.size - 1){ table.add("/"); } @@ -45,32 +45,32 @@ public class ConsumeLiquidFilter extends Consume{ } @Override - public String getIcon() { + public String getIcon(){ return "icon-liquid"; } @Override - public void update(Block block, TileEntity entity) { + public void update(Block block, TileEntity entity){ entity.liquids.remove(entity.liquids.current(), use(block)); } @Override - public boolean valid(Block block, TileEntity entity) { + public boolean valid(Block block, TileEntity entity){ return filter.test(entity.liquids.current()) && entity.liquids.currentAmount() >= use(block); } @Override - public void display(BlockStats stats) { + public void display(BlockStats stats){ if(isFuel){ stats.add(BlockStat.inputLiquidFuel, new LiquidFilterValue(filter)); stats.add(BlockStat.liquidFuelUse, 60f * use, StatUnit.liquidSecond); - }else { + }else{ stats.add(BlockStat.inputLiquid, new LiquidFilterValue(filter)); stats.add(BlockStat.liquidUse, 60f * use, StatUnit.liquidSecond); } } - float use(Block block) { + float use(Block block){ return Math.min(use * Timers.delta(), block.liquidCapacity); } } diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumePower.java b/core/src/io/anuke/mindustry/world/consumers/ConsumePower.java index 482c53916f..82bd1e56e0 100644 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumePower.java +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumePower.java @@ -8,35 +8,35 @@ import io.anuke.mindustry.world.meta.StatUnit; import io.anuke.ucore.core.Timers; import io.anuke.ucore.scene.ui.layout.Table; -public class ConsumePower extends Consume { +public class ConsumePower extends Consume{ private final float use; - public ConsumePower(float use) { + public ConsumePower(float use){ this.use = use; } @Override - public void buildTooltip(Table table) { + public void buildTooltip(Table table){ } @Override - public String getIcon() { + public String getIcon(){ return "icon-power"; } @Override - public void update(Block block, TileEntity entity) { + public void update(Block block, TileEntity entity){ entity.power.amount -= Math.min(use(block), entity.power.amount); } @Override - public boolean valid(Block block, TileEntity entity) { + public boolean valid(Block block, TileEntity entity){ return entity.power.amount >= use(block); } @Override - public void display(BlockStats stats) { + public void display(BlockStats stats){ stats.add(BlockStat.powerUse, use * 60f, StatUnit.powerSecond); } diff --git a/core/src/io/anuke/mindustry/world/consumers/Consumers.java b/core/src/io/anuke/mindustry/world/consumers/Consumers.java index 8bb729054f..a0ea86d201 100644 --- a/core/src/io/anuke/mindustry/world/consumers/Consumers.java +++ b/core/src/io/anuke/mindustry/world/consumers/Consumers.java @@ -10,7 +10,7 @@ import io.anuke.mindustry.world.Block; import io.anuke.ucore.function.Consumer; import io.anuke.ucore.util.ThreadArray; -public class Consumers { +public class Consumers{ private ObjectMap, Consume> map = new ObjectMap<>(); private ObjectSet> required = new ObjectSet<>(); private ThreadArray results = new ThreadArray<>(); @@ -20,7 +20,7 @@ public class Consumers { } public void checkRequired(Block block){ - for (Class c : required){ + for(Class c : required){ if(!map.containsKey(c)){ throw new RuntimeException("Missing required consumer of type \"" + ClassReflection.getSimpleName(c) + "\" in block \"" + block.name + "\"!"); } @@ -92,14 +92,14 @@ public class Consumers { if(!map.containsKey(type)){ throw new IllegalArgumentException("Block does not contain consumer of type '" + type + "'!"); } - return (T)map.get(type); + return (T) map.get(type); } - public Iterable all() { + public Iterable all(){ return map.values(); } - public ThreadArray array() { + public ThreadArray array(){ return results; } diff --git a/core/src/io/anuke/mindustry/world/mapgen/GenProperties.java b/core/src/io/anuke/mindustry/world/mapgen/GenProperties.java index 88a00e6709..b11aca6b8c 100644 --- a/core/src/io/anuke/mindustry/world/mapgen/GenProperties.java +++ b/core/src/io/anuke/mindustry/world/mapgen/GenProperties.java @@ -1,6 +1,6 @@ package io.anuke.mindustry.world.mapgen; -public class GenProperties { +public class GenProperties{ public long seed; public MapStyle maps; public OreStyle ores; @@ -11,24 +11,40 @@ public class GenProperties { public EnvironmentStyle environment; enum MapStyle{ - /**256x512*/ + /** + * 256x512 + */ longY, - /**128x256*/ + /** + * 128x256 + */ smallY, - /**128x128*/ + /** + * 128x128 + */ small, - /**256x256*/ + /** + * 256x256 + */ normal } enum OreStyle{ - /**'vanilla' noise-distributed ores*/ + /** + * 'vanilla' noise-distributed ores + */ normal, - /**ores hug the walls*/ + /** + * ores hug the walls + */ nearWalls, - /**ores hug all liquid rivers*/ + /** + * ores hug all liquid rivers + */ nearRivers, - /**large veins*/ + /** + * large veins + */ largeVeins } @@ -40,22 +56,36 @@ public class GenProperties { } enum RiverStyle{ - /**long thin river spanning entire map*/ + /** + * long thin river spanning entire map + */ longThin, - /**long river branching into many others*/ + /** + * long river branching into many others + */ longBranch, - /**one long, thick river*/ + /** + * one long, thick river + */ longThick, - /**short, thick river that ends in a lake*/ + /** + * short, thick river that ends in a lake + */ shortLake } enum TerrainStyle{ - /**bordered around by the normal material*/ + /** + * bordered around by the normal material + */ normal, - /**everything is islands*/ + /** + * everything is islands + */ waterIslands, - /**everything is islands: lava edition*/ + /** + * everything is islands: lava edition + */ lavaIslands } diff --git a/core/src/io/anuke/mindustry/world/mapgen/WorldGenerator.java b/core/src/io/anuke/mindustry/world/mapgen/WorldGenerator.java index 8d53a33c0d..6db249a9f1 100644 --- a/core/src/io/anuke/mindustry/world/mapgen/WorldGenerator.java +++ b/core/src/io/anuke/mindustry/world/mapgen/WorldGenerator.java @@ -27,234 +27,236 @@ import static io.anuke.mindustry.Vars.state; import static io.anuke.mindustry.Vars.world; -public class WorldGenerator { - static int oreIndex = 0; - - /**Should fill spawns with the correct spawnpoints.*/ - public static void loadTileData(Tile[][] tiles, MapTileData data, boolean genOres, int seed){ - data.position(0, 0); - TileDataMarker marker = data.newDataMarker(); +public class WorldGenerator{ + static int oreIndex = 0; - for(int y = 0; y < data.height(); y ++){ - for(int x = 0; x < data.width(); x ++){ - data.read(marker); - - tiles[x][y] = new Tile(x, y, marker.floor, marker.wall == Blocks.blockpart.id ? 0 : marker.wall, marker.rotation, marker.team, marker.elevation); - } - } + /** + * Should fill spawns with the correct spawnpoints. + */ + public static void loadTileData(Tile[][] tiles, MapTileData data, boolean genOres, int seed){ + data.position(0, 0); + TileDataMarker marker = data.newDataMarker(); - prepareTiles(tiles, seed, genOres); - } + for(int y = 0; y < data.height(); y++){ + for(int x = 0; x < data.width(); x++){ + data.read(marker); - public static void prepareTiles(Tile[][] tiles, int seed, boolean genOres){ - - //find multiblocks - IntArray multiblocks = new IntArray(); + tiles[x][y] = new Tile(x, y, marker.floor, marker.wall == Blocks.blockpart.id ? 0 : marker.wall, marker.rotation, marker.team, marker.elevation); + } + } - for(int x = 0; x < tiles.length; x ++) { - for (int y = 0; y < tiles[0].length; y++) { - Tile tile = tiles[x][y]; - - Team team = tile.getTeam(); + prepareTiles(tiles, seed, genOres); + } - if(tile.block() == StorageBlocks.core && - state.teams.has(team)){ - state.teams.get(team).cores.add(tile); - } - - if(tiles[x][y].block().isMultiblock()){ - multiblocks.add(tiles[x][y].packedPosition()); - } - } - } + public static void prepareTiles(Tile[][] tiles, int seed, boolean genOres){ - //place multiblocks now - for(int i = 0; i < multiblocks.size; i ++){ - int pos = multiblocks.get(i); + //find multiblocks + IntArray multiblocks = new IntArray(); - int x = pos % tiles.length; - int y = pos / tiles[0].length; + for(int x = 0; x < tiles.length; x++){ + for(int y = 0; y < tiles[0].length; y++){ + Tile tile = tiles[x][y]; - Block result = tiles[x][y].block(); - Team team = tiles[x][y].getTeam(); + Team team = tile.getTeam(); - int offsetx = -(result.size-1)/2; - int offsety = -(result.size-1)/2; + if(tile.block() == StorageBlocks.core && + state.teams.has(team)){ + state.teams.get(team).cores.add(tile); + } - for(int dx = 0; dx < result.size; dx ++){ - for(int dy = 0; dy < result.size; dy ++){ - int worldx = dx + offsetx + x; - int worldy = dy + offsety + y; - if(!(worldx == x && worldy == y)){ - Tile toplace = world.tile(worldx, worldy); - if(toplace != null) { - toplace.setLinked((byte) (dx + offsetx), (byte) (dy + offsety)); - toplace.setTeam(team); - } - } - } - } - } + if(tiles[x][y].block().isMultiblock()){ + multiblocks.add(tiles[x][y].packedPosition()); + } + } + } - //update cliffs, occlusion data - for(int x = 0; x < tiles.length; x ++){ - for(int y = 0; y < tiles[0].length; y ++) { - Tile tile = tiles[x][y]; + //place multiblocks now + for(int i = 0; i < multiblocks.size; i++){ + int pos = multiblocks.get(i); - tile.updateOcclusion(); + int x = pos % tiles.length; + int y = pos / tiles[0].length; - //fix things on cliffs that shouldn't be - if(tile.block() != Blocks.air && tile.cliffs != 0){ - tile.setBlock(Blocks.air); - } - } - } + Block result = tiles[x][y].block(); + Team team = tiles[x][y].getTeam(); - oreIndex = 0; + int offsetx = -(result.size - 1) / 2; + int offsety = -(result.size - 1) / 2; - if(genOres) { - Array ores = Array.with( - new OreEntry(Items.tungsten, 0.3f, seed), - new OreEntry(Items.coal, 0.284f, seed), - new OreEntry(Items.lead, 0.28f, seed), - new OreEntry(Items.titanium, 0.27f, seed), - new OreEntry(Items.thorium, 0.26f, seed) - ); + for(int dx = 0; dx < result.size; dx++){ + for(int dy = 0; dy < result.size; dy++){ + int worldx = dx + offsetx + x; + int worldy = dy + offsety + y; + if(!(worldx == x && worldy == y)){ + Tile toplace = world.tile(worldx, worldy); + if(toplace != null){ + toplace.setLinked((byte) (dx + offsetx), (byte) (dy + offsety)); + toplace.setTeam(team); + } + } + } + } + } - for (int x = 0; x < tiles.length; x++) { - for (int y = 0; y < tiles[0].length; y++) { + //update cliffs, occlusion data + for(int x = 0; x < tiles.length; x++){ + for(int y = 0; y < tiles[0].length; y++){ + Tile tile = tiles[x][y]; - Tile tile = tiles[x][y]; + tile.updateOcclusion(); - if(!tile.floor().hasOres || tile.cliffs != 0 || tile.block() != Blocks.air){ - continue; - } + //fix things on cliffs that shouldn't be + if(tile.block() != Blocks.air && tile.cliffs != 0){ + tile.setBlock(Blocks.air); + } + } + } - for(int i = ores.size-1; i >= 0; i --){ - OreEntry entry = ores.get(i); - if(entry.noise.octaveNoise2D(1, 0.7, 1f / (4 + i*2), x, y)/4f + - Math.abs(0.5f-entry.noise.octaveNoise2D(2, 0.7, 1f / (50 + i*2), x, y)) > 0.48f && - Math.abs(0.5f-entry.noise.octaveNoise2D(1, 1, 1f / (55 + i*4), x, y)) > 0.22f){ - tile.setFloor((Floor) OreBlocks.get(tile.floor(), entry.item)); - break; - } - } - } - } - } - } + oreIndex = 0; - public static void generateMap(Tile[][] tiles, int seed){ - MathUtils.random.setSeed((long)(Math.random() * 99999999)); - Simplex sim = new Simplex(Mathf.random(99999)); - Simplex sim2 = new Simplex(Mathf.random(99999)); - Simplex sim3 = new Simplex(Mathf.random(99999)); + if(genOres){ + Array ores = Array.with( + new OreEntry(Items.tungsten, 0.3f, seed), + new OreEntry(Items.coal, 0.284f, seed), + new OreEntry(Items.lead, 0.28f, seed), + new OreEntry(Items.titanium, 0.27f, seed), + new OreEntry(Items.thorium, 0.26f, seed) + ); - SeedRandom random = new SeedRandom(Mathf.random(99999)); + for(int x = 0; x < tiles.length; x++){ + for(int y = 0; y < tiles[0].length; y++){ - int width = tiles.length, height = tiles[0].length; + Tile tile = tiles[x][y]; - ObjectMap decoration = new ObjectMap<>(); + if(!tile.floor().hasOres || tile.cliffs != 0 || tile.block() != Blocks.air){ + continue; + } - decoration.put(Blocks.grass, Blocks.shrub); - decoration.put(Blocks.stone, Blocks.rock); - decoration.put(Blocks.ice, Blocks.icerock); - decoration.put(Blocks.snow, Blocks.icerock); - decoration.put(Blocks.blackstone, Blocks.blackrock); + for(int i = ores.size - 1; i >= 0; i--){ + OreEntry entry = ores.get(i); + if(entry.noise.octaveNoise2D(1, 0.7, 1f / (4 + i * 2), x, y) / 4f + + Math.abs(0.5f - entry.noise.octaveNoise2D(2, 0.7, 1f / (50 + i * 2), x, y)) > 0.48f && + Math.abs(0.5f - entry.noise.octaveNoise2D(1, 1, 1f / (55 + i * 4), x, y)) > 0.22f){ + tile.setFloor((Floor) OreBlocks.get(tile.floor(), entry.item)); + break; + } + } + } + } + } + } - for (int x = 0; x < width; x++) { - for (int y = 0; y < height; y++) { - Block floor = Blocks.stone; - Block wall = Blocks.air; + public static void generateMap(Tile[][] tiles, int seed){ + MathUtils.random.setSeed((long) (Math.random() * 99999999)); + Simplex sim = new Simplex(Mathf.random(99999)); + Simplex sim2 = new Simplex(Mathf.random(99999)); + Simplex sim3 = new Simplex(Mathf.random(99999)); - double elevation = sim.octaveNoise2D(3, 0.5, 1f/100, x, y) * 4.1 - 1; - double temp = sim3.octaveNoise2D(7, 0.54, 1f/320f, x, y); + SeedRandom random = new SeedRandom(Mathf.random(99999)); - double r = sim2.octaveNoise2D(1, 0.6, 1f/70, x, y); - double edgeDist = Math.max(width/2, height/2) - Math.max(Math.abs(x - width/2), Math.abs(y - height/2)); - double dst = Vector2.dst(width/2, height/2, x, y); - double elevDip = 30; + int width = tiles.length, height = tiles[0].length; - double border = 14; + ObjectMap decoration = new ObjectMap<>(); - if(edgeDist < border){ - elevation += (border - edgeDist)/6.0; - } + decoration.put(Blocks.grass, Blocks.shrub); + decoration.put(Blocks.stone, Blocks.rock); + decoration.put(Blocks.ice, Blocks.icerock); + decoration.put(Blocks.snow, Blocks.icerock); + decoration.put(Blocks.blackstone, Blocks.blackrock); - if(temp < 0.35){ - floor = Blocks.snow; - }else if(temp < 0.45){ - floor = Blocks.stone; - }else if(temp < 0.65){ - floor = Blocks.grass; - }else if(temp < 0.8){ - floor = Blocks.sand; - }else if(temp < 0.9){ - floor = Blocks.blackstone; - elevation = 0f; - }else{ - floor = Blocks.lava; - } + for(int x = 0; x < width; x++){ + for(int y = 0; y < height; y++){ + Block floor = Blocks.stone; + Block wall = Blocks.air; - if(dst < elevDip){ - elevation -= (elevDip - dst)/elevDip * 3.0; - }else if(r > 0.9){ - floor = Blocks.water; - elevation = 0; + double elevation = sim.octaveNoise2D(3, 0.5, 1f / 100, x, y) * 4.1 - 1; + double temp = sim3.octaveNoise2D(7, 0.54, 1f / 320f, x, y); - if(r > 0.94){ - floor = Blocks.deepwater; - } - } + double r = sim2.octaveNoise2D(1, 0.6, 1f / 70, x, y); + double edgeDist = Math.max(width / 2, height / 2) - Math.max(Math.abs(x - width / 2), Math.abs(y - height / 2)); + double dst = Vector2.dst(width / 2, height / 2, x, y); + double elevDip = 30; - if(wall == Blocks.air && decoration.containsKey(floor) && random.chance(0.03)){ - wall = decoration.get(floor); - } + double border = 14; - Tile tile = new Tile(x, y, (byte)floor.id, (byte)wall.id); - tile.elevation = (byte)Math.max(elevation, 0); - tiles[x][y] = tile; - } - } + if(edgeDist < border){ + elevation += (border - edgeDist) / 6.0; + } - for (int x = 0; x < width; x++) { - for (int y = 0; y < height; y++) { - Tile tile = tiles[x][y]; + if(temp < 0.35){ + floor = Blocks.snow; + }else if(temp < 0.45){ + floor = Blocks.stone; + }else if(temp < 0.65){ + floor = Blocks.grass; + }else if(temp < 0.8){ + floor = Blocks.sand; + }else if(temp < 0.9){ + floor = Blocks.blackstone; + elevation = 0f; + }else{ + floor = Blocks.lava; + } - byte elevation = tile.elevation; + if(dst < elevDip){ + elevation -= (elevDip - dst) / elevDip * 3.0; + }else if(r > 0.9){ + floor = Blocks.water; + elevation = 0; - for(GridPoint2 point : Geometry.d4){ - if(!Mathf.inBounds(x + point.x, y + point.y, width, height)) continue; - if(tiles[x + point.x][y + point.y].elevation < elevation){ + if(r > 0.94){ + floor = Blocks.deepwater; + } + } - if(Mathf.chance(0.05)){ - tile.elevation = -1; - } - break; - } - } - } - } + if(wall == Blocks.air && decoration.containsKey(floor) && random.chance(0.03)){ + wall = decoration.get(floor); + } - tiles[width/2][height/2].setBlock(StorageBlocks.core); - tiles[width/2][height/2].setTeam(Team.blue); - - prepareTiles(tiles, seed, true); - } + Tile tile = new Tile(x, y, (byte) floor.id, (byte) wall.id); + tile.elevation = (byte) Math.max(elevation, 0); + tiles[x][y] = tile; + } + } - public static class OreEntry{ - final float frequency; - final Item item; - final Simplex noise; - final RidgedPerlin ridge; - final int index; + for(int x = 0; x < width; x++){ + for(int y = 0; y < height; y++){ + Tile tile = tiles[x][y]; - OreEntry(Item item, float frequency, int seed) { - this.frequency = frequency; - this.item = item; - this.noise = new Simplex(seed + oreIndex); - this.ridge = new RidgedPerlin(seed + oreIndex, 2); - this.index = oreIndex ++; - } - } + byte elevation = tile.elevation; + + for(GridPoint2 point : Geometry.d4){ + if(!Mathf.inBounds(x + point.x, y + point.y, width, height)) continue; + if(tiles[x + point.x][y + point.y].elevation < elevation){ + + if(Mathf.chance(0.05)){ + tile.elevation = -1; + } + break; + } + } + } + } + + tiles[width / 2][height / 2].setBlock(StorageBlocks.core); + tiles[width / 2][height / 2].setTeam(Team.blue); + + prepareTiles(tiles, seed, true); + } + + public static class OreEntry{ + final float frequency; + final Item item; + final Simplex noise; + final RidgedPerlin ridge; + final int index; + + OreEntry(Item item, float frequency, int seed){ + this.frequency = frequency; + this.item = item; + this.noise = new Simplex(seed + oreIndex); + this.ridge = new RidgedPerlin(seed + oreIndex, 2); + this.index = oreIndex++; + } + } } diff --git a/core/src/io/anuke/mindustry/world/meta/BlockBar.java b/core/src/io/anuke/mindustry/world/meta/BlockBar.java index d322dffa5f..d692e152b5 100644 --- a/core/src/io/anuke/mindustry/world/meta/BlockBar.java +++ b/core/src/io/anuke/mindustry/world/meta/BlockBar.java @@ -3,12 +3,12 @@ package io.anuke.mindustry.world.meta; import io.anuke.mindustry.world.BarType; import io.anuke.mindustry.world.Tile; -public class BlockBar { +public class BlockBar{ public final ValueSupplier value; public final BarType type; public final boolean top; - public BlockBar(BarType type, boolean top, ValueSupplier value) { + public BlockBar(BarType type, boolean top, ValueSupplier value){ this.value = value; this.type = type; this.top = top; diff --git a/core/src/io/anuke/mindustry/world/meta/BlockBars.java b/core/src/io/anuke/mindustry/world/meta/BlockBars.java index 6b02067976..35507b616b 100644 --- a/core/src/io/anuke/mindustry/world/meta/BlockBars.java +++ b/core/src/io/anuke/mindustry/world/meta/BlockBars.java @@ -3,8 +3,8 @@ package io.anuke.mindustry.world.meta; import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.world.BarType; -public class BlockBars { - private Array list = Array.with(new BlockBar(BarType.health, false, tile -> tile.entity.health / (float)tile.block().health)); +public class BlockBars{ + private Array list = Array.with(new BlockBar(BarType.health, false, tile -> tile.entity.health / (float) tile.block().health)); public void add(BlockBar bar){ list.add(bar); @@ -36,7 +36,7 @@ public class BlockBars { list.removeAll(removals, true); } - public Array list() { + public Array list(){ return list; } } diff --git a/core/src/io/anuke/mindustry/world/meta/BlockFlag.java b/core/src/io/anuke/mindustry/world/meta/BlockFlag.java index 9fb0025c0c..44820e6646 100644 --- a/core/src/io/anuke/mindustry/world/meta/BlockFlag.java +++ b/core/src/io/anuke/mindustry/world/meta/BlockFlag.java @@ -1,17 +1,29 @@ package io.anuke.mindustry.world.meta; -public enum BlockFlag { - /**General important target for all types of units.*/ +public enum BlockFlag{ + /** + * General important target for all types of units. + */ target(0), - /**Point to resupply resources.*/ + /** + * Point to resupply resources. + */ resupplyPoint(Float.MAX_VALUE), - /**Point to drop off resources.*/ + /** + * Point to drop off resources. + */ dropPoint(Float.MAX_VALUE), - /**Producer of important goods.*/ + /** + * Producer of important goods. + */ producer(20), - /**Producer or storage unit of volatile materials.*/ + /** + * Producer or storage unit of volatile materials. + */ explosive(10), - /**Repair point.*/ + /** + * Repair point. + */ repair(Float.MAX_VALUE); public final float cost; diff --git a/core/src/io/anuke/mindustry/world/meta/BlockGroup.java b/core/src/io/anuke/mindustry/world/meta/BlockGroup.java index e9795a956a..dd90943ea0 100644 --- a/core/src/io/anuke/mindustry/world/meta/BlockGroup.java +++ b/core/src/io/anuke/mindustry/world/meta/BlockGroup.java @@ -1,5 +1,5 @@ package io.anuke.mindustry.world.meta; -public enum BlockGroup { +public enum BlockGroup{ none, walls, turrets, transportation, power, liquids, drills } diff --git a/core/src/io/anuke/mindustry/world/meta/BlockStat.java b/core/src/io/anuke/mindustry/world/meta/BlockStat.java index 03e715abdb..97f17c6c25 100644 --- a/core/src/io/anuke/mindustry/world/meta/BlockStat.java +++ b/core/src/io/anuke/mindustry/world/meta/BlockStat.java @@ -2,8 +2,10 @@ package io.anuke.mindustry.world.meta; import io.anuke.ucore.util.Bundles; -/**Describes one type of stat for a block.*/ -public enum BlockStat { +/** + * Describes one type of stat for a block. + */ +public enum BlockStat{ health(StatCategory.general), size(StatCategory.general), @@ -41,14 +43,12 @@ public enum BlockStat { shots(StatCategory.shooting), reload(StatCategory.shooting), powerShot(StatCategory.shooting), - targetsAir(StatCategory.shooting) -, - ; + targetsAir(StatCategory.shooting),; public final StatCategory category; - BlockStat(StatCategory category) { + BlockStat(StatCategory category){ this.category = category; } diff --git a/core/src/io/anuke/mindustry/world/meta/BlockStats.java b/core/src/io/anuke/mindustry/world/meta/BlockStats.java index e697c0255f..c4f9698616 100644 --- a/core/src/io/anuke/mindustry/world/meta/BlockStats.java +++ b/core/src/io/anuke/mindustry/world/meta/BlockStats.java @@ -10,50 +10,66 @@ import io.anuke.mindustry.world.meta.values.*; import io.anuke.ucore.util.Bundles; import io.anuke.ucore.util.Log; -/**Hold and organizes a list of block stats.*/ -public class BlockStats { +/** + * Hold and organizes a list of block stats. + */ +public class BlockStats{ private static final boolean errorWhenMissing = true; private final OrderedMap> map = new OrderedMap<>(); private final Block block; private boolean dirty; - public BlockStats(Block block) { + public BlockStats(Block block){ this.block = block; } - /**Adds a single float value with this stat, formatted to 2 decimal places.*/ + /** + * Adds a single float value with this stat, formatted to 2 decimal places. + */ public void add(BlockStat stat, float value, StatUnit unit){ add(stat, new NumberValue(value, unit)); } - /**Adds a single y/n boolean value.*/ + /** + * Adds a single y/n boolean value. + */ public void add(BlockStat stat, boolean value){ add(stat, new BooleanValue(value)); } - /**Adds an item value.*/ + /** + * Adds an item value. + */ public void add(BlockStat stat, Item item){ add(stat, new ItemValue(new ItemStack(item, 1))); } - /**Adds a liquid value.*/ + /** + * Adds a liquid value. + */ public void add(BlockStat stat, Liquid liquid){ add(stat, new LiquidValue(liquid)); } - /**Adds an item value.*/ + /** + * Adds an item value. + */ public void add(BlockStat stat, ItemStack item){ add(stat, new ItemValue(item)); } - /**Adds a single string value with this stat.*/ + /** + * Adds a single string value with this stat. + */ public void add(BlockStat stat, String format, Object... args){ add(stat, new StringValue(format, args)); } - /**Adds a stat value.*/ + /** + * Adds a stat value. + */ public void add(BlockStat stat, StatValue value){ if(!Bundles.has("text.blocks." + stat.name().toLowerCase())){ if(!errorWhenMissing){ @@ -72,7 +88,7 @@ public class BlockStats { } if(map.containsKey(stat.category) && map.get(stat.category).containsKey(stat)){ - throw new RuntimeException("Duplicate stat entry: \"" +stat + "\" in block '" + block.name + "'"); + throw new RuntimeException("Duplicate stat entry: \"" + stat + "\" in block '" + block.name + "'"); } if(!map.containsKey(stat.category)){ @@ -94,11 +110,11 @@ public class BlockStats { dirty = true; } - public OrderedMap> toMap() { + public OrderedMap> toMap(){ //sort stats by index if they've been modified - if(dirty) { + if(dirty){ map.orderedKeys().sort(); - for (Entry> entry : map.entries()) { + for(Entry> entry : map.entries()){ entry.value.orderedKeys().sort(); } diff --git a/core/src/io/anuke/mindustry/world/meta/ContentStatValue.java b/core/src/io/anuke/mindustry/world/meta/ContentStatValue.java index f3aca0b83d..6a8375522e 100644 --- a/core/src/io/anuke/mindustry/world/meta/ContentStatValue.java +++ b/core/src/io/anuke/mindustry/world/meta/ContentStatValue.java @@ -2,6 +2,6 @@ package io.anuke.mindustry.world.meta; import io.anuke.mindustry.game.UnlockableContent; -public interface ContentStatValue extends StatValue { +public interface ContentStatValue extends StatValue{ UnlockableContent[] getValueContent(); } diff --git a/core/src/io/anuke/mindustry/world/meta/StatCategory.java b/core/src/io/anuke/mindustry/world/meta/StatCategory.java index 4932b136fc..ce1ef5b6f2 100644 --- a/core/src/io/anuke/mindustry/world/meta/StatCategory.java +++ b/core/src/io/anuke/mindustry/world/meta/StatCategory.java @@ -1,7 +1,9 @@ package io.anuke.mindustry.world.meta; -/**A specific category for a stat.*/ -public enum StatCategory { +/** + * A specific category for a stat. + */ +public enum StatCategory{ general, power, liquids, diff --git a/core/src/io/anuke/mindustry/world/meta/StatUnit.java b/core/src/io/anuke/mindustry/world/meta/StatUnit.java index c093d31fb3..781f18806f 100644 --- a/core/src/io/anuke/mindustry/world/meta/StatUnit.java +++ b/core/src/io/anuke/mindustry/world/meta/StatUnit.java @@ -2,8 +2,10 @@ package io.anuke.mindustry.world.meta; import io.anuke.ucore.util.Bundles; -/**Defines a unit of measurement for block stats.*/ -public enum StatUnit { +/** + * Defines a unit of measurement for block stats. + */ +public enum StatUnit{ blocks, powerSecond, liquidSecond, diff --git a/core/src/io/anuke/mindustry/world/meta/StatValue.java b/core/src/io/anuke/mindustry/world/meta/StatValue.java index 7a6784ca88..5b95ff6e4d 100644 --- a/core/src/io/anuke/mindustry/world/meta/StatValue.java +++ b/core/src/io/anuke/mindustry/world/meta/StatValue.java @@ -2,9 +2,13 @@ package io.anuke.mindustry.world.meta; import io.anuke.ucore.scene.ui.layout.Table; -/**A base interface for a value of a stat that is displayed.*/ -public interface StatValue { - /**This method should all elements necessary to display this stat to the specified table. - * For example, a stat that is just text would add label to the table. */ +/** + * A base interface for a value of a stat that is displayed. + */ +public interface StatValue{ + /** + * This method should all elements necessary to display this stat to the specified table. + * For example, a stat that is just text would add label to the table. + */ void display(Table table); } diff --git a/core/src/io/anuke/mindustry/world/meta/values/BooleanValue.java b/core/src/io/anuke/mindustry/world/meta/values/BooleanValue.java index ace31e66ce..7adb9bb0b5 100644 --- a/core/src/io/anuke/mindustry/world/meta/values/BooleanValue.java +++ b/core/src/io/anuke/mindustry/world/meta/values/BooleanValue.java @@ -3,15 +3,15 @@ package io.anuke.mindustry.world.meta.values; import io.anuke.mindustry.world.meta.StatValue; import io.anuke.ucore.scene.ui.layout.Table; -public class BooleanValue implements StatValue { +public class BooleanValue implements StatValue{ private final boolean value; - public BooleanValue(boolean value) { + public BooleanValue(boolean value){ this.value = value; } @Override - public void display(Table table) { + public void display(Table table){ table.add(!value ? "$text.no" : "$text.yes"); } } diff --git a/core/src/io/anuke/mindustry/world/meta/values/ItemFilterValue.java b/core/src/io/anuke/mindustry/world/meta/values/ItemFilterValue.java index 60ac578f41..f0b4708968 100644 --- a/core/src/io/anuke/mindustry/world/meta/values/ItemFilterValue.java +++ b/core/src/io/anuke/mindustry/world/meta/values/ItemFilterValue.java @@ -6,24 +6,24 @@ import io.anuke.mindustry.world.meta.StatValue; import io.anuke.ucore.function.Predicate; import io.anuke.ucore.scene.ui.layout.Table; -public class ItemFilterValue implements StatValue { +public class ItemFilterValue implements StatValue{ private final Predicate filter; - public ItemFilterValue(Predicate filter) { + public ItemFilterValue(Predicate filter){ this.filter = filter; } @Override - public void display(Table table) { + public void display(Table table){ Array list = new Array<>(); for(Item item : Item.all()){ if(filter.test(item)) list.add(item); } - for (int i = 0; i < list.size; i++) { + for(int i = 0; i < list.size; i++){ Item item = list.get(i); - table.addImage(item.region).size(8*3).padRight(2).padLeft(2); + table.addImage(item.region).size(8 * 3).padRight(2).padLeft(2); if(i != list.size - 1){ table.add("/"); } diff --git a/core/src/io/anuke/mindustry/world/meta/values/ItemListValue.java b/core/src/io/anuke/mindustry/world/meta/values/ItemListValue.java index 77890bfe2e..9a236306a3 100644 --- a/core/src/io/anuke/mindustry/world/meta/values/ItemListValue.java +++ b/core/src/io/anuke/mindustry/world/meta/values/ItemListValue.java @@ -11,23 +11,23 @@ public class ItemListValue implements ContentStatValue{ private final Item[] items; private final ItemStack[] stacks; - public ItemListValue(Item[] items) { + public ItemListValue(Item[] items){ this.items = items; this.stacks = null; } - public ItemListValue(ItemStack[] stacks) { + public ItemListValue(ItemStack[] stacks){ this.stacks = stacks; this.items = null; } @Override - public UnlockableContent[] getValueContent() { + public UnlockableContent[] getValueContent(){ if(items != null){ return items; - }else { + }else{ Item[] res = new Item[stacks.length]; - for (int i = 0; i < res.length; i++) { + for(int i = 0; i < res.length; i++){ res[i] = stacks[i].item; } return res; @@ -35,14 +35,14 @@ public class ItemListValue implements ContentStatValue{ } @Override - public void display(Table table) { + public void display(Table table){ if(items != null){ for(Item item : items){ - table.addImage(item.region).size(8*3).padRight(5); + table.addImage(item.region).size(8 * 3).padRight(5); } }else{ for(ItemStack stack : stacks){ - table.add(new ItemImage(stack)).size(8*3).padRight(5); + table.add(new ItemImage(stack)).size(8 * 3).padRight(5); } } } diff --git a/core/src/io/anuke/mindustry/world/meta/values/ItemValue.java b/core/src/io/anuke/mindustry/world/meta/values/ItemValue.java index d36dd119d6..d42312c4d1 100644 --- a/core/src/io/anuke/mindustry/world/meta/values/ItemValue.java +++ b/core/src/io/anuke/mindustry/world/meta/values/ItemValue.java @@ -7,21 +7,21 @@ import io.anuke.mindustry.ui.ItemImage; import io.anuke.mindustry.world.meta.ContentStatValue; import io.anuke.ucore.scene.ui.layout.Table; -public class ItemValue implements ContentStatValue { +public class ItemValue implements ContentStatValue{ private final ItemStack item; - public ItemValue(ItemStack item) { + public ItemValue(ItemStack item){ this.item = item; } @Override - public UnlockableContent[] getValueContent() { + public UnlockableContent[] getValueContent(){ return new Item[]{item.item}; } @Override - public void display(Table table) { + public void display(Table table){ //TODO better implementation, quantity support - table.add(new ItemImage(item)).size(8*3); + table.add(new ItemImage(item)).size(8 * 3); } } diff --git a/core/src/io/anuke/mindustry/world/meta/values/LiquidFilterValue.java b/core/src/io/anuke/mindustry/world/meta/values/LiquidFilterValue.java index c585a7895f..c8206ad13f 100644 --- a/core/src/io/anuke/mindustry/world/meta/values/LiquidFilterValue.java +++ b/core/src/io/anuke/mindustry/world/meta/values/LiquidFilterValue.java @@ -6,24 +6,24 @@ import io.anuke.mindustry.world.meta.StatValue; import io.anuke.ucore.function.Predicate; import io.anuke.ucore.scene.ui.layout.Table; -public class LiquidFilterValue implements StatValue { +public class LiquidFilterValue implements StatValue{ private final Predicate filter; - public LiquidFilterValue(Predicate filter) { + public LiquidFilterValue(Predicate filter){ this.filter = filter; } @Override - public void display(Table table) { + public void display(Table table){ Array list = new Array<>(); for(Liquid item : Liquid.all()){ if(!item.isHidden() && filter.test(item)) list.add(item); } - for (int i = 0; i < list.size; i++) { + for(int i = 0; i < list.size; i++){ Liquid item = list.get(i); - table.addImage(item.getContentIcon()).size(8*3).padRight(2).padLeft(2).padTop(2).padBottom(2); + table.addImage(item.getContentIcon()).size(8 * 3).padRight(2).padLeft(2).padTop(2).padBottom(2); if(i != list.size - 1){ table.add("/"); } diff --git a/core/src/io/anuke/mindustry/world/meta/values/LiquidValue.java b/core/src/io/anuke/mindustry/world/meta/values/LiquidValue.java index 20db91051a..bdee87897e 100644 --- a/core/src/io/anuke/mindustry/world/meta/values/LiquidValue.java +++ b/core/src/io/anuke/mindustry/world/meta/values/LiquidValue.java @@ -5,20 +5,20 @@ import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.world.meta.ContentStatValue; import io.anuke.ucore.scene.ui.layout.Table; -public class LiquidValue implements ContentStatValue { +public class LiquidValue implements ContentStatValue{ private final Liquid liquid; - public LiquidValue(Liquid liquid) { + public LiquidValue(Liquid liquid){ this.liquid = liquid; } @Override - public UnlockableContent[] getValueContent() { + public UnlockableContent[] getValueContent(){ return new UnlockableContent[]{liquid}; } @Override - public void display(Table table) { - table.addImage(liquid.getContentIcon()).size(8*3); + public void display(Table table){ + table.addImage(liquid.getContentIcon()).size(8 * 3); } } diff --git a/core/src/io/anuke/mindustry/world/meta/values/NumberValue.java b/core/src/io/anuke/mindustry/world/meta/values/NumberValue.java index 65f6a48a78..0dd73ac91f 100644 --- a/core/src/io/anuke/mindustry/world/meta/values/NumberValue.java +++ b/core/src/io/anuke/mindustry/world/meta/values/NumberValue.java @@ -5,13 +5,15 @@ import io.anuke.mindustry.world.meta.StatValue; import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.util.Strings; -/**A stat that is a number with a unit attacked. - * The number is rounded to 2 decimal places by default.*/ +/** + * A stat that is a number with a unit attacked. + * The number is rounded to 2 decimal places by default. + */ public class NumberValue implements StatValue{ private final StatUnit unit; private final float value; - public NumberValue(float value, StatUnit unit) { + public NumberValue(float value, StatUnit unit){ this.unit = unit; this.value = value; @@ -21,8 +23,8 @@ public class NumberValue implements StatValue{ } @Override - public void display(Table table) { - float diff = Math.abs((int)value - value); + public void display(Table table){ + float diff = Math.abs((int) value - value); int precision = diff <= 0.01f ? 0 : diff <= 0.1f ? 1 : 2; table.add(Strings.toFixed(value, precision)); diff --git a/core/src/io/anuke/mindustry/world/meta/values/StringValue.java b/core/src/io/anuke/mindustry/world/meta/values/StringValue.java index 1e3ab92fdd..1a0bc458d0 100644 --- a/core/src/io/anuke/mindustry/world/meta/values/StringValue.java +++ b/core/src/io/anuke/mindustry/world/meta/values/StringValue.java @@ -4,15 +4,15 @@ import io.anuke.mindustry.world.meta.StatValue; import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.util.Strings; -public class StringValue implements StatValue { +public class StringValue implements StatValue{ private final String value; - public StringValue(String value, Object... args) { + public StringValue(String value, Object... args){ this.value = Strings.formatArgs(value, args); } @Override - public void display(Table table) { + public void display(Table table){ table.add(value); } } diff --git a/core/src/io/anuke/mindustry/world/modules/BlockModule.java b/core/src/io/anuke/mindustry/world/modules/BlockModule.java index 0b74bfb5e5..225b7c3e9d 100644 --- a/core/src/io/anuke/mindustry/world/modules/BlockModule.java +++ b/core/src/io/anuke/mindustry/world/modules/BlockModule.java @@ -4,7 +4,8 @@ import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; -public abstract class BlockModule { +public abstract class BlockModule{ public abstract void write(DataOutput stream) throws IOException; + public abstract void read(DataInput stream) throws IOException; } diff --git a/core/src/io/anuke/mindustry/world/modules/ConsumeModule.java b/core/src/io/anuke/mindustry/world/modules/ConsumeModule.java index c33e556ee8..40d06f6853 100644 --- a/core/src/io/anuke/mindustry/world/modules/ConsumeModule.java +++ b/core/src/io/anuke/mindustry/world/modules/ConsumeModule.java @@ -30,12 +30,12 @@ public class ConsumeModule extends BlockModule{ } @Override - public void write(DataOutput stream) throws IOException { + public void write(DataOutput stream) throws IOException{ stream.writeBoolean(valid); } @Override - public void read(DataInput stream) throws IOException { + public void read(DataInput stream) throws IOException{ valid = stream.readBoolean(); } } diff --git a/core/src/io/anuke/mindustry/world/modules/InventoryModule.java b/core/src/io/anuke/mindustry/world/modules/InventoryModule.java index f443a3bf3d..85a349f334 100644 --- a/core/src/io/anuke/mindustry/world/modules/InventoryModule.java +++ b/core/src/io/anuke/mindustry/world/modules/InventoryModule.java @@ -13,7 +13,7 @@ public class InventoryModule extends BlockModule{ private int total; public void forEach(ItemConsumer cons){ - for (int i = 0; i < items.length; i++) { + for(int i = 0; i < items.length; i++){ if(items[i] > 0){ cons.accept(Item.getByID(i), items[i]); } @@ -22,7 +22,7 @@ public class InventoryModule extends BlockModule{ public float sum(ItemCalculator calc){ float sum = 0f; - for (int i = 0; i < items.length; i++) { + for(int i = 0; i < items.length; i++){ if(items[i] > 0){ sum += calc.get(Item.getByID(i), items[i]); } @@ -47,12 +47,14 @@ public class InventoryModule extends BlockModule{ public boolean has(ItemStack[] stacks, float amountScaling){ for(ItemStack stack : stacks){ - if(!has(stack.item, (int)(stack.amount * amountScaling))) return false; + if(!has(stack.item, (int) (stack.amount * amountScaling))) return false; } return true; } - /**Returns true if this entity has at least one of each item in each stack.*/ + /** + * Returns true if this entity has at least one of each item in each stack. + */ public boolean hasOne(ItemStack[] stacks){ for(ItemStack stack : stacks){ if(!has(stack.item, 1)) return false; @@ -65,10 +67,10 @@ public class InventoryModule extends BlockModule{ } public Item take(){ - for(int i = 0; i < items.length; i ++){ + for(int i = 0; i < items.length; i++){ if(items[i] > 0){ - items[i] --; - total --; + items[i]--; + total--; return Item.getByID(i); } } @@ -104,15 +106,15 @@ public class InventoryModule extends BlockModule{ } @Override - public void write(DataOutput stream) throws IOException { + public void write(DataOutput stream) throws IOException{ byte amount = 0; - for (int item : items) { - if (item > 0) amount++; + for(int item : items){ + if(item > 0) amount++; } stream.writeByte(amount); //amount of items - for(int i = 0; i < items.length; i ++){ + for(int i = 0; i < items.length; i++){ if(items[i] > 0){ stream.writeByte(i); //item ID stream.writeInt(items[i]); //item amount @@ -121,11 +123,11 @@ public class InventoryModule extends BlockModule{ } @Override - public void read(DataInput stream) throws IOException { + public void read(DataInput stream) throws IOException{ byte count = stream.readByte(); total = 0; - for(int j = 0; j < count; j ++){ + for(int j = 0; j < count; j++){ int itemid = stream.readByte(); int itemamount = stream.readInt(); items[itemid] = itemamount; diff --git a/core/src/io/anuke/mindustry/world/modules/LiquidModule.java b/core/src/io/anuke/mindustry/world/modules/LiquidModule.java index dfd6a4d86e..12c87f1307 100644 --- a/core/src/io/anuke/mindustry/world/modules/LiquidModule.java +++ b/core/src/io/anuke/mindustry/world/modules/LiquidModule.java @@ -6,17 +6,21 @@ import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; -public class LiquidModule extends BlockModule { +public class LiquidModule extends BlockModule{ private float[] liquids = new float[Liquid.all().size]; private float total; private Liquid current = Liquid.getByID(0); - /**Returns total amount of liquids.*/ + /** + * Returns total amount of liquids. + */ public float total(){ return total; } - /**Last recieved or loaded liquid. Only valid for liquid modules with 1 type of liquid.*/ + /** + * Last recieved or loaded liquid. Only valid for liquid modules with 1 type of liquid. + */ public Liquid current(){ return current; } @@ -40,7 +44,7 @@ public class LiquidModule extends BlockModule { } public void forEach(LiquidConsumer cons){ - for (int i = 0; i < liquids.length; i++) { + for(int i = 0; i < liquids.length; i++){ if(liquids[i] > 0){ cons.accept(Liquid.getByID(i), liquids[i]); } @@ -49,7 +53,7 @@ public class LiquidModule extends BlockModule { public float sum(LiquidCalculator calc){ float sum = 0f; - for (int i = 0; i < liquids.length; i++) { + for(int i = 0; i < liquids.length; i++){ if(liquids[i] > 0){ sum += calc.get(Liquid.getByID(i), liquids[i]); } @@ -58,15 +62,15 @@ public class LiquidModule extends BlockModule { } @Override - public void write(DataOutput stream) throws IOException { + public void write(DataOutput stream) throws IOException{ byte amount = 0; - for (float liquid : liquids) { - if (liquid > 0) amount++; + for(float liquid : liquids){ + if(liquid > 0) amount++; } stream.writeByte(amount); //amount of liquids - for(int i = 0; i < liquids.length; i ++){ + for(int i = 0; i < liquids.length; i++){ if(liquids[i] > 0){ stream.writeByte(i); //liquid ID stream.writeFloat(liquids[i]); //item amount @@ -75,10 +79,10 @@ public class LiquidModule extends BlockModule { } @Override - public void read(DataInput stream) throws IOException { + public void read(DataInput stream) throws IOException{ byte count = stream.readByte(); - for(int j = 0; j < count; j ++){ + for(int j = 0; j < count; j++){ int liquidid = stream.readByte(); float amount = stream.readFloat(); liquids[liquidid] = amount; diff --git a/core/src/io/anuke/mindustry/world/modules/PowerModule.java b/core/src/io/anuke/mindustry/world/modules/PowerModule.java index fe35aa0d90..320408ec5e 100644 --- a/core/src/io/anuke/mindustry/world/modules/PowerModule.java +++ b/core/src/io/anuke/mindustry/world/modules/PowerModule.java @@ -26,7 +26,7 @@ public class PowerModule extends BlockModule{ } @Override - public void write(DataOutput stream) throws IOException { + public void write(DataOutput stream) throws IOException{ stream.writeFloat(amount); } diff --git a/desktop/src/io/anuke/mindustry/desktop/CrashHandler.java b/desktop/src/io/anuke/mindustry/desktop/CrashHandler.java index af32d6f065..c611915dfe 100644 --- a/desktop/src/io/anuke/mindustry/desktop/CrashHandler.java +++ b/desktop/src/io/anuke/mindustry/desktop/CrashHandler.java @@ -11,7 +11,7 @@ import java.nio.file.Paths; import java.text.SimpleDateFormat; import java.util.Date; -public class CrashHandler { +public class CrashHandler{ public static void handle(Throwable e){ //TODO send full error report to server via HTTP @@ -24,7 +24,7 @@ public class CrashHandler { netActive = Net.active(); netServer = Net.server(); Net.dispose(); - }catch (Throwable p){ + }catch(Throwable p){ p.printStackTrace(); } @@ -39,8 +39,8 @@ public class CrashHandler { header += "Net Active: " + netActive + "\n"; header += "Net Server: " + netServer + "\n"; header += "OS: " + System.getProperty("os.name") + "\n"; - header += "Multithreading: " + Settings.getBool("multithread")+ "\n----\n"; - }catch (Throwable e4){ + header += "Multithreading: " + Settings.getBool("multithread") + "\n----\n"; + }catch(Throwable e4){ header += "\n--error getting additional info--\n"; e4.printStackTrace(); } @@ -55,16 +55,16 @@ public class CrashHandler { try{ filename = "crash-report-" + new SimpleDateFormat("dd-MM-yy h.mm.ss").format(new Date()) + ".txt"; Files.write(Paths.get(System.getProperty("user.home"), "mindustry-crash-reports", filename), result.getBytes()); - }catch (Throwable i){ + }catch(Throwable i){ i.printStackTrace(); failed = true; } try{ javax.swing.JOptionPane.showMessageDialog(null, "An error has occured: \n" + result + "\n\n" + - (!failed ? "A crash report has been written to " + new File(filename).getAbsolutePath() + ".\nPlease send this file to the developer!" - : "Failed to generate crash report.\nPlease send an image of this crash log to the developer!")); - }catch (Throwable i){ + (!failed ? "A crash report has been written to " + new File(filename).getAbsolutePath() + ".\nPlease send this file to the developer!" + : "Failed to generate crash report.\nPlease send an image of this crash log to the developer!")); + }catch(Throwable i){ i.printStackTrace(); //what now? } diff --git a/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java b/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java index aef5a71b04..3c21144f6b 100644 --- a/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java +++ b/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java @@ -30,20 +30,24 @@ import static io.anuke.mindustry.Vars.*; public class DesktopLauncher extends Lwjgl3Application{ ObjectMap prefmap; - - public static void main (String[] arg) { - try { + + public DesktopLauncher(ApplicationListener listener, Lwjgl3ApplicationConfiguration config){ + super(listener, config); + } + + public static void main(String[] arg){ + try{ Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration(); config.setTitle("Mindustry"); config.setMaximized(true); config.setWindowedMode(960, 540); config.setWindowIcon("sprites/icon.png"); - if(OS.isMac) { + if(OS.isMac){ Application.getApplication().setOpenFileHandler(e -> { List list = e.getFiles(); - File target = (File)list.get(0); + File target = (File) list.get(0); Gdx.app.postRunnable(() -> { FileHandle file = OS.getAppDataDirectory("Mindustry").child("tmp").child(target.getName()); @@ -56,7 +60,7 @@ public class DesktopLauncher extends Lwjgl3Application{ try{ SaveSlot slot = control.getSaves().importSave(file); ui.load.runLoadSave(slot); - }catch (IOException e2){ + }catch(IOException e2){ ui.showError(Bundles.format("text.save.import.fail", Strings.parseException(e2, false))); } }else{ @@ -65,7 +69,7 @@ public class DesktopLauncher extends Lwjgl3Application{ }else if(file.extension().equalsIgnoreCase(mapExtension)){ //open map Gdx.app.postRunnable(() -> { - if (!ui.editor.isShown()) { + if(!ui.editor.isShown()){ ui.editor.show(); } @@ -80,26 +84,22 @@ public class DesktopLauncher extends Lwjgl3Application{ Net.setClientProvider(new KryoClient()); Net.setServerProvider(new KryoServer()); - new DesktopLauncher(new Mindustry(), config); - }catch (Throwable e){ - CrashHandler.handle(e); - } - } - - public DesktopLauncher(ApplicationListener listener, Lwjgl3ApplicationConfiguration config) { - super(listener, config); + new DesktopLauncher(new Mindustry(), config); + }catch(Throwable e){ + CrashHandler.handle(e); + } } @Override - public Preferences getPreferences(String name) { - String prefsDirectory = OS.getAppDataDirectoryString("Mindustry"); + public Preferences getPreferences(String name){ + String prefsDirectory = OS.getAppDataDirectoryString("Mindustry"); - if(prefmap == null){ - prefmap = new ObjectMap<>(); + if(prefmap == null){ + prefmap = new ObjectMap<>(); } - if(prefmap.containsKey(name)){ - return prefmap.get(name); + if(prefmap.containsKey(name)){ + return prefmap.get(name); }else{ Preferences prefs = new BinaryPreferences(new Lwjgl3FileHandle(new File(prefsDirectory, name), FileType.Absolute)); prefmap.put(name, prefs); diff --git a/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java b/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java index b0c2cc8a74..6511f3fe08 100644 --- a/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java +++ b/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java @@ -27,7 +27,7 @@ import java.util.Locale; import static io.anuke.mindustry.Vars.*; -public class DesktopPlatform extends Platform { +public class DesktopPlatform extends Platform{ final static boolean useDiscord = OS.is64Bit; final static String applicationId = "398246104468291591"; final static DateFormat format = SimpleDateFormat.getDateTimeInstance(); @@ -38,14 +38,14 @@ public class DesktopPlatform extends Platform { Vars.testMobile = isDebug() && Array.with(args).contains("-testMobile", false); - if(useDiscord) { + if(useDiscord){ DiscordEventHandlers handlers = new DiscordEventHandlers(); DiscordRPC.INSTANCE.Discord_Initialize(applicationId, handlers, true, ""); } } @Override - public void showFileChooser(String text, String content, Consumer cons, boolean open, String filter) { + public void showFileChooser(String text, String content, Consumer cons, boolean open, String filter){ new FileChooser(text, file -> file.extension().equalsIgnoreCase(filter), open, cons).show(); } @@ -70,7 +70,7 @@ public class DesktopPlatform extends Platform { } @Override - public void updateRPC() { + public void updateRPC(){ if(!useDiscord) return; @@ -89,7 +89,7 @@ public class DesktopPlatform extends Platform { }else{ if(ui.editor != null && ui.editor.isShown()){ presence.state = "In Editor"; - }else { + }else{ presence.state = "In Menu"; } } @@ -100,26 +100,27 @@ public class DesktopPlatform extends Platform { } @Override - public void onGameExit() { + public void onGameExit(){ if(useDiscord) DiscordRPC.INSTANCE.Discord_Shutdown(); } @Override - public boolean isDebug() { + public boolean isDebug(){ return args.length > 0 && args[0].equalsIgnoreCase("-debug_" + getUUID().hashCode()); } @Override - public ThreadProvider getThreadProvider() { + public ThreadProvider getThreadProvider(){ return new DefaultThreadImpl(); } @Override - public String getUUID() { - try { + public String getUUID(){ + try{ Enumeration e = NetworkInterface.getNetworkInterfaces(); NetworkInterface out; - for(out = e.nextElement(); out.getHardwareAddress() == null && e.hasMoreElements() && validAddress(out.getHardwareAddress()); out = e.nextElement()); + for(out = e.nextElement(); out.getHardwareAddress() == null && e.hasMoreElements() && validAddress(out.getHardwareAddress()); out = e.nextElement()) + ; byte[] bytes = out.getHardwareAddress(); byte[] result = new byte[8]; @@ -130,7 +131,7 @@ public class DesktopPlatform extends Platform { if(str.equals("AAAAAAAAAOA=")) throw new RuntimeException("Bad UUID."); return str; - }catch (Exception e){ + }catch(Exception e){ return super.getUUID(); } } diff --git a/server/src/io/anuke/mindustry/server/MindustryServer.java b/server/src/io/anuke/mindustry/server/MindustryServer.java index c82c4a5695..fdd846c7f3 100644 --- a/server/src/io/anuke/mindustry/server/MindustryServer.java +++ b/server/src/io/anuke/mindustry/server/MindustryServer.java @@ -11,7 +11,7 @@ import io.anuke.ucore.modules.ModuleCore; import static io.anuke.mindustry.Vars.*; -public class MindustryServer extends ModuleCore { +public class MindustryServer extends ModuleCore{ private String[] args; public MindustryServer(String[] args){ diff --git a/server/src/io/anuke/mindustry/server/ServerControl.java b/server/src/io/anuke/mindustry/server/ServerControl.java index 99c93b1b6d..5e310c46f4 100644 --- a/server/src/io/anuke/mindustry/server/ServerControl.java +++ b/server/src/io/anuke/mindustry/server/ServerControl.java @@ -33,21 +33,23 @@ import java.util.Scanner; import static io.anuke.mindustry.Vars.*; import static io.anuke.ucore.util.Log.*; -public class ServerControl extends Module { +public class ServerControl extends Module{ private final CommandHandler handler = new CommandHandler(""); private ShuffleMode mode; public ServerControl(String[] args){ Settings.defaultList( - "shufflemode", "normal", - "bans", "", - "admins", "" + "shufflemode", "normal", + "bans", "", + "admins", "" ); mode = ShuffleMode.valueOf(Settings.getString("shufflemode")); - Effects.setScreenShakeProvider((a, b) -> {}); - Effects.setEffectProvider((a, b, c, d, e, f) -> {}); + Effects.setScreenShakeProvider((a, b) -> { + }); + Effects.setEffectProvider((a, b, c, d, e, f) -> { + }); Sounds.setHeadless(true); String[] commands = {}; @@ -79,16 +81,16 @@ public class ServerControl extends Module { netServer.kick(connection.id, KickReason.gameover); } - if (mode != ShuffleMode.off) { - if(world.maps().all().size > 0) { + if(mode != ShuffleMode.off){ + if(world.maps().all().size > 0){ Array maps = mode == ShuffleMode.both ? world.maps().all() : mode == ShuffleMode.normal ? world.maps().defaultMaps() : world.maps().customMaps(); Map previous = world.getMap(); Map map = previous; - while (map == previous) map = maps.random(); + while(map == previous) map = maps.random(); - if(map != null) { + if(map != null){ info("Selected next map to be {0}.", map.name); state.set(State.playing); @@ -147,11 +149,11 @@ public class ServerControl extends Module { Map result = null; - if(arg.length > 0) { + if(arg.length > 0){ GameMode mode; try{ mode = GameMode.valueOf(arg[0]); - }catch (IllegalArgumentException e){ + }catch(IllegalArgumentException e){ err("No gamemode '{0}' found.", arg[0]); return; } @@ -159,14 +161,14 @@ public class ServerControl extends Module { info("Loading map..."); state.mode = mode; - if(arg.length > 1) { + if(arg.length > 1){ String search = arg[1]; - for (Map map : world.maps().all()) { - if (map.name.equalsIgnoreCase(search)) + for(Map map : world.maps().all()){ + if(map.name.equalsIgnoreCase(search)) result = map; } - if (result == null) { + if(result == null){ err("No map with name &y'{0}'&lr found.", search); return; } @@ -205,18 +207,18 @@ public class ServerControl extends Module { if(state.mode.disableWaveTimer){ info("&ly{0} enemies.", unitGroups[Team.red.ordinal()].size()); }else{ - info("&ly{0} seconds until next wave.", (int)(state.wavetime / 60)); + info("&ly{0} seconds until next wave.", (int) (state.wavetime / 60)); } - if(playerGroup.size() > 0) { + if(playerGroup.size() > 0){ info("&lyPlayers: {0}", playerGroup.size()); - for (Player p : playerGroup.all()) { + for(Player p : playerGroup.all()){ print(" &y" + p.name); } }else{ info("&lyNo players connected."); } - info("&lbFPS: {0}", (int)(60f/Timers.delta())); + info("&lbFPS: {0}", (int) (60f / Timers.delta())); } }); @@ -224,9 +226,9 @@ public class ServerControl extends Module { if(state.is(State.menu)){ info("&lyServer is closed."); }else{ - if(playerGroup.size() > 0) { + if(playerGroup.size() > 0){ info("&lyPlayers: {0}", playerGroup.size()); - for (Player p : playerGroup.all()) { + for(Player p : playerGroup.all()){ print(" &y{0} / Connection {1} / IP: {2}", p.name, p.con.id, p.con.address); } }else{ @@ -236,7 +238,7 @@ public class ServerControl extends Module { }); handler.register("say", "", "Send a message to all players.", arg -> { - if(!state.is(State.playing)) { + if(!state.is(State.playing)){ err("Not hosting. Host a game first."); return; } @@ -251,7 +253,7 @@ public class ServerControl extends Module { Difficulty diff = Difficulty.valueOf(arg[0]); state.difficulty = diff; info("Difficulty set to '{0}'.", arg[0]); - }catch (IllegalArgumentException e){ + }catch(IllegalArgumentException e){ err("No difficulty with name '{0}' found.", arg[0]); } }); @@ -286,13 +288,13 @@ public class ServerControl extends Module { err("Incorrect command usage."); } - if(arg.length >= 2) { - try { + if(arg.length >= 2){ + try{ int maxbreak = Integer.parseInt(arg[1]); int cooldown = (arg.length >= 3 ? Integer.parseInt(arg[2]) : Administration.defaultBreakCooldown); netServer.admins.setAntiGriefParams(maxbreak, cooldown); info("Anti-grief parameters set."); - } catch (NumberFormatException e) { + }catch(NumberFormatException e){ err("Invalid number format."); } } @@ -323,13 +325,13 @@ public class ServerControl extends Module { Settings.putString("shufflemode", arg[0]); Settings.save(); info("Shuffle mode set to '{0}'.", arg[0]); - }catch (Exception e){ + }catch(Exception e){ err("Unknown shuffle mode '{0}'.", arg[0]); } }); handler.register("kick", "", "Kick a person by name.", arg -> { - if(!state.is(State.playing)) { + if(!state.is(State.playing)){ err("Not hosting a game yet. Calm down."); return; } @@ -352,7 +354,7 @@ public class ServerControl extends Module { }); handler.register("ban", "", "Ban a person by name.", arg -> { - if(!state.is(State.playing)) { + if(!state.is(State.playing)){ err("Can't ban people by name with no players."); return; } @@ -397,7 +399,7 @@ public class ServerControl extends Module { Log.info("&lmBanned players [IP]:"); for(String string : ipbans){ PlayerInfo info = netServer.admins.findByIP(string); - if(info != null) { + if(info != null){ Log.info(" &lm '{0}' / Last known name: '{1}' / ID: '{2}'", string, info.lastName, info.id); }else{ Log.info(" &lm '{0}' (No known name or info)", string); @@ -407,7 +409,7 @@ public class ServerControl extends Module { }); handler.register("banip", "", "Ban a person by IP.", arg -> { - if(netServer.admins.banPlayerIP(arg[0])) { + if(netServer.admins.banPlayerIP(arg[0])){ info("Banned player by IP: {0}.", arg[0]); for(Player player : playerGroup.all()){ @@ -423,7 +425,7 @@ public class ServerControl extends Module { }); handler.register("banid", "", "Ban a person by their unique ID.", arg -> { - if(netServer.admins.banPlayerID(arg[0])) { + if(netServer.admins.banPlayerID(arg[0])){ info("Banned player by ID: {0}.", arg[0]); for(Player player : playerGroup.all()){ @@ -438,7 +440,7 @@ public class ServerControl extends Module { }); handler.register("unbanip", "", "Completely unban a person by IP.", arg -> { - if(netServer.admins.unbanPlayerIP(arg[0])) { + if(netServer.admins.unbanPlayerIP(arg[0])){ info("Unbanned player by IP: {0}.", arg[0]); }else{ err("That IP is not banned!"); @@ -446,7 +448,7 @@ public class ServerControl extends Module { }); handler.register("unbanid", "", "Completely unban a person by ID.", arg -> { - if(netServer.admins.unbanPlayerID(arg[0])) { + if(netServer.admins.unbanPlayerID(arg[0])){ info("&lmUnbanned player by ID: {0}.", arg[0]); }else{ err("That IP is not banned!"); @@ -454,7 +456,7 @@ public class ServerControl extends Module { }); handler.register("admin", "", "Make a user admin", arg -> { - if(!state.is(State.playing)) { + if(!state.is(State.playing)){ err("Open the server first."); return; } @@ -478,7 +480,7 @@ public class ServerControl extends Module { }); handler.register("unadmin", "", "Removes admin status from a player", arg -> { - if(!state.is(State.playing)) { + if(!state.is(State.playing)){ err("Open the server first."); return; } @@ -515,7 +517,7 @@ public class ServerControl extends Module { }); handler.register("runwave", "Trigger the next wave.", arg -> { - if(!state.is(State.playing)) { + if(!state.is(State.playing)){ err("Not hosting. Host a game first."); }else{ logic.runWave(); @@ -562,19 +564,19 @@ public class ServerControl extends Module { }); handler.register("griefers", "[min-break:place-ratio] [min-breakage]", "Find possible griefers currently online.", arg -> { - if(!state.is(State.playing)) { + if(!state.is(State.playing)){ err("Open the server first."); return; } - try { + try{ float ratio = arg.length > 0 ? Float.parseFloat(arg[0]) : 0.5f; int minbreak = arg.length > 1 ? Integer.parseInt(arg[1]) : 100; boolean found = false; - for (Player player : playerGroup.all()) { + for(Player player : playerGroup.all()){ TraceInfo info = netServer.admins.getTraceByID(player.uuid); if(info.totalBlocksBroken >= minbreak && info.totalBlocksBroken / Math.max(info.totalBlocksPlaced, 1f) >= ratio){ info("&ly - Player '{0}' / UUID &lm{1}&ly found: &lc{2}&ly broken and &lc{3}&ly placed.", @@ -583,19 +585,19 @@ public class ServerControl extends Module { } } - if (!found) { + if(!found){ info("No griefers matching the criteria have been found."); } - }catch (NumberFormatException e){ + }catch(NumberFormatException e){ err("Invalid number format."); } }); handler.register("gameover", "Force a game over.", arg -> { if(state.is(State.menu)){ - info("Not playing a map."); - return; + info("Not playing a map."); + return; } Events.fire(GameOverEvent.class); @@ -616,10 +618,10 @@ public class ServerControl extends Module { if(tile.entity != null){ Array arr = tile.block().getDebugInfo(tile); StringBuilder result = new StringBuilder(); - for(int i = 0; i < arr.size/2; i ++){ - result.append(arr.get(i*2)); + for(int i = 0; i < arr.size / 2; i++){ + result.append(arr.get(i * 2)); result.append(": "); - result.append(arr.get(i*2 + 1)); + result.append(arr.get(i * 2 + 1)); result.append("\n"); } Log.info("&ly{0}", result); @@ -629,7 +631,7 @@ public class ServerControl extends Module { }else{ Log.info("No tile at that location."); } - }catch (NumberFormatException e){ + }catch(NumberFormatException e){ Log.err("Invalid coordinates passed."); } }); @@ -639,7 +641,7 @@ public class ServerControl extends Module { Array infos = netServer.admins.findByName(arg[0], checkAll); - if(infos.size == 1) { + if(infos.size == 1){ PlayerInfo info = infos.peek(); Log.info("&lcTrace info for player '{0}' / UUID {1}:", info.lastName, info.id); Log.info(" &lyall names used: {0}", info.names); @@ -665,7 +667,7 @@ public class ServerControl extends Module { Array infos = netServer.admins.findByIPs(arg[0]); - if(infos.size == 1) { + if(infos.size == 1){ PlayerInfo info = infos.peek(); Log.info("&lcTrace info for player '{0}' / UUID {1}:", info.lastName, info.id); Log.info(" &lyall names used: {0}", info.names); @@ -707,7 +709,7 @@ public class ServerControl extends Module { }); handler.register("trace", "", "Trace a player's actions", arg -> { - if(!state.is(State.playing)) { + if(!state.is(State.playing)){ err("Open the server first."); return; } @@ -724,7 +726,7 @@ public class ServerControl extends Module { if(target != null){ TraceInfo info = netServer.admins.getTraceByID(target.uuid); Log.info("&lcTrace info for player '{0}':", target.name); - Log.info(" &lyEntity ID: {0}", info. playerid); + Log.info(" &lyEntity ID: {0}", info.playerid); Log.info(" &lyIP: {0}", info.ip); Log.info(" &lyUUID: {0}", info.uuid); Log.info(" &lycustom client: {0}", info.modclient); @@ -741,27 +743,27 @@ public class ServerControl extends Module { } }); - handler.register("rollback", "", "Rollback the block edits in the world", arg -> { - if(!state.is(State.playing)) { - err("Open the server first."); - return; - } + handler.register("rollback", "", "Rollback the block edits in the world", arg -> { + if(!state.is(State.playing)){ + err("Open the server first."); + return; + } - if(!Strings.canParsePostiveInt(arg[0])) { - err("Please input a valid, positive, number of times to rollback"); - return; - } + if(!Strings.canParsePostiveInt(arg[0])){ + err("Please input a valid, positive, number of times to rollback"); + return; + } - int rollbackTimes = Integer.valueOf(arg[0]); - IntMap> editLogs = netServer.admins.getEditLogs(); - if(editLogs.size == 0){ - err("Nothing to rollback!"); - return; - } + int rollbackTimes = Integer.valueOf(arg[0]); + IntMap> editLogs = netServer.admins.getEditLogs(); + if(editLogs.size == 0){ + err("Nothing to rollback!"); + return; + } - //netServer.admins.rollbackWorld(rollbackTimes); - info("Rollback done!"); - }); + //netServer.admins.rollbackWorld(rollbackTimes); + info("Rollback done!"); + }); } private void readCommands(){ @@ -772,7 +774,7 @@ public class ServerControl extends Module { Gdx.app.postRunnable(() -> { Response response = handler.handleMessage(line); - if (response.type == ResponseType.unknownCommand) { + if(response.type == ResponseType.unknownCommand){ int minDst = 0; Command closest = null; @@ -787,12 +789,12 @@ public class ServerControl extends Module { if(closest != null){ err("Command not found. Did you mean \"" + closest.text + "\"?"); - }else { + }else{ err("Invalid command. Type 'help' for help."); } - }else if (response.type == ResponseType.fewArguments) { + }else if(response.type == ResponseType.fewArguments){ err("Too few command arguments. Usage: " + response.command.text + " " + response.command.paramText); - }else if (response.type == ResponseType.manyArguments) { + }else if(response.type == ResponseType.manyArguments){ err("Too many command arguments. Usage: " + response.command.text + " " + response.command.paramText); } }); @@ -800,9 +802,9 @@ public class ServerControl extends Module { } private void host(){ - try { + try{ Net.host(port); - }catch (IOException e){ + }catch(IOException e){ Log.err(e); state.set(State.menu); } diff --git a/server/src/io/anuke/mindustry/server/ServerLauncher.java b/server/src/io/anuke/mindustry/server/ServerLauncher.java index 4a8c07ba20..dbc25ea35b 100644 --- a/server/src/io/anuke/mindustry/server/ServerLauncher.java +++ b/server/src/io/anuke/mindustry/server/ServerLauncher.java @@ -20,6 +20,37 @@ import java.io.File; public class ServerLauncher extends HeadlessApplication{ ObjectMap prefmap; + public ServerLauncher(ApplicationListener listener, HeadlessApplicationConfiguration config){ + super(listener, config); + + //don't do anything at all for GDX logging: don't want controller info and such + Gdx.app.setApplicationLogger(new ApplicationLogger(){ + @Override + public void log(String tag, String message){ + } + + @Override + public void log(String tag, String message, Throwable exception){ + } + + @Override + public void error(String tag, String message){ + } + + @Override + public void error(String tag, String message, Throwable exception){ + } + + @Override + public void debug(String tag, String message){ + } + + @Override + public void debug(String tag, String message, Throwable exception){ + } + }); + } + public static void main(String[] args){ Net.setClientProvider(new KryoClient()); @@ -33,7 +64,7 @@ public class ServerLauncher extends HeadlessApplication{ //find and handle uncaught exceptions in libGDX thread for(Thread thread : Thread.getAllStackTraces().keySet()){ if(thread.getName().equals("HeadlessApplication")){ - thread.setUncaughtExceptionHandler((t, throwable) ->{ + thread.setUncaughtExceptionHandler((t, throwable) -> { throwable.printStackTrace(); System.exit(-1); }); @@ -42,22 +73,8 @@ public class ServerLauncher extends HeadlessApplication{ } } - public ServerLauncher(ApplicationListener listener, HeadlessApplicationConfiguration config) { - super(listener, config); - - //don't do anything at all for GDX logging: don't want controller info and such - Gdx.app.setApplicationLogger(new ApplicationLogger() { - @Override public void log(String tag, String message) { } - @Override public void log(String tag, String message, Throwable exception) { } - @Override public void error(String tag, String message) { } - @Override public void error(String tag, String message, Throwable exception) { } - @Override public void debug(String tag, String message) { } - @Override public void debug(String tag, String message, Throwable exception) { } - }); - } - @Override - public Preferences getPreferences(String name) { + public Preferences getPreferences(String name){ String prefsDirectory = OS.getAppDataDirectoryString("Mindustry"); if(prefmap == null){