Formatting
This commit is contained in:
@@ -65,7 +65,7 @@ public class AndroidLauncher extends AndroidApplication{
|
|||||||
DateFormat format = SimpleDateFormat.getDateTimeInstance();
|
DateFormat format = SimpleDateFormat.getDateTimeInstance();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasDiscord() {
|
public boolean hasDiscord(){
|
||||||
return isPackageInstalled("com.discord");
|
return isPackageInstalled("com.discord");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,29 +90,29 @@ public class AndroidLauncher extends AndroidApplication{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void openDonations() {
|
public void openDonations(){
|
||||||
showDonations();
|
showDonations();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ThreadProvider getThreadProvider() {
|
public ThreadProvider getThreadProvider(){
|
||||||
return new DefaultThreadImpl();
|
return new DefaultThreadImpl();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDebug() {
|
public boolean isDebug(){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUUID() {
|
public String getUUID(){
|
||||||
try {
|
try{
|
||||||
String s = Secure.getString(getContext().getContentResolver(),
|
String s = Secure.getString(getContext().getContentResolver(),
|
||||||
Secure.ANDROID_ID);
|
Secure.ANDROID_ID);
|
||||||
|
|
||||||
int len = s.length();
|
int len = s.length();
|
||||||
byte[] data = new byte[len / 2];
|
byte[] data = new byte[len / 2];
|
||||||
for (int i = 0; i < len; i += 2) {
|
for(int i = 0; i < len; i += 2){
|
||||||
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
|
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
|
||||||
+ Character.digit(s.charAt(i + 1), 16));
|
+ Character.digit(s.charAt(i + 1), 16));
|
||||||
}
|
}
|
||||||
@@ -122,7 +122,7 @@ public class AndroidLauncher extends AndroidApplication{
|
|||||||
if(result.equals("AAAAAAAAAOA=")) throw new RuntimeException("Bad UUID.");
|
if(result.equals("AAAAAAAAAOA=")) throw new RuntimeException("Bad UUID.");
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}catch (Exception e){
|
}catch(Exception e){
|
||||||
return super.getUUID();
|
return super.getUUID();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -133,21 +133,21 @@ public class AndroidLauncher extends AndroidApplication{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void showFileChooser(String text, String content, Consumer<FileHandle> cons, boolean open, String filetype) {
|
public void showFileChooser(String text, String content, Consumer<FileHandle> cons, boolean open, String filetype){
|
||||||
chooser = new FileChooser(text, file -> file.extension().equalsIgnoreCase(filetype), open, cons);
|
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 &&
|
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)){
|
checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)){
|
||||||
chooser.show();
|
chooser.show();
|
||||||
chooser = null;
|
chooser = null;
|
||||||
}else {
|
}else{
|
||||||
ArrayList<String> perms = new ArrayList<>();
|
ArrayList<String> perms = new ArrayList<>();
|
||||||
|
|
||||||
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
if(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
|
||||||
perms.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
perms.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
if(checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
|
||||||
perms.add(Manifest.permission.READ_EXTERNAL_STORAGE);
|
perms.add(Manifest.permission.READ_EXTERNAL_STORAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,12 +156,12 @@ public class AndroidLauncher extends AndroidApplication{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beginForceLandscape() {
|
public void beginForceLandscape(){
|
||||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
|
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void endForceLandscape() {
|
public void endForceLandscape(){
|
||||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
|
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,12 +171,12 @@ public class AndroidLauncher extends AndroidApplication{
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try{
|
||||||
ProviderInstaller.installIfNeeded(this);
|
ProviderInstaller.installIfNeeded(this);
|
||||||
} catch (GooglePlayServicesRepairableException e) {
|
}catch(GooglePlayServicesRepairableException e){
|
||||||
GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
|
GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
|
||||||
apiAvailability.getErrorDialog(this, e.getConnectionStatusCode(), 0).show();
|
apiAvailability.getErrorDialog(this, e.getConnectionStatusCode(), 0).show();
|
||||||
} catch (GooglePlayServicesNotAvailableException e) {
|
}catch(GooglePlayServicesNotAvailableException e){
|
||||||
Log.e("SecurityException", "Google Play Services not available.");
|
Log.e("SecurityException", "Google Play Services not available.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,7 +195,7 @@ public class AndroidLauncher extends AndroidApplication{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
|
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults){
|
||||||
if(requestCode == PERMISSION_REQUEST_CODE){
|
if(requestCode == PERMISSION_REQUEST_CODE){
|
||||||
for(int i : grantResults){
|
for(int i : grantResults){
|
||||||
if(i != PackageManager.PERMISSION_GRANTED) return;
|
if(i != PackageManager.PERMISSION_GRANTED) return;
|
||||||
@@ -208,15 +208,15 @@ public class AndroidLauncher extends AndroidApplication{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void checkFiles(Intent intent){
|
private void checkFiles(Intent intent){
|
||||||
try {
|
try{
|
||||||
Uri uri = intent.getData();
|
Uri uri = intent.getData();
|
||||||
if (uri != null) {
|
if(uri != null){
|
||||||
File myFile = null;
|
File myFile = null;
|
||||||
String scheme = uri.getScheme();
|
String scheme = uri.getScheme();
|
||||||
if (scheme.equals("file")) {
|
if(scheme.equals("file")){
|
||||||
String fileName = uri.getEncodedPath();
|
String fileName = uri.getEncodedPath();
|
||||||
myFile = new File(fileName);
|
myFile = new File(fileName);
|
||||||
} else if (!scheme.equals("content")) {
|
}else if(!scheme.equals("content")){
|
||||||
//error
|
//error
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -225,7 +225,7 @@ public class AndroidLauncher extends AndroidApplication{
|
|||||||
boolean map = uri.getPath().endsWith(mapExtension);
|
boolean map = uri.getPath().endsWith(mapExtension);
|
||||||
|
|
||||||
InputStream inStream;
|
InputStream inStream;
|
||||||
if (myFile != null) inStream = new FileInputStream(myFile);
|
if(myFile != null) inStream = new FileInputStream(myFile);
|
||||||
else inStream = getContentResolver().openInputStream(uri);
|
else inStream = getContentResolver().openInputStream(uri);
|
||||||
|
|
||||||
Gdx.app.postRunnable(() -> {
|
Gdx.app.postRunnable(() -> {
|
||||||
@@ -239,7 +239,7 @@ public class AndroidLauncher extends AndroidApplication{
|
|||||||
try{
|
try{
|
||||||
SaveSlot slot = control.getSaves().importSave(file);
|
SaveSlot slot = control.getSaves().importSave(file);
|
||||||
ui.load.runLoadSave(slot);
|
ui.load.runLoadSave(slot);
|
||||||
}catch (IOException e){
|
}catch(IOException e){
|
||||||
ui.showError(Bundles.format("text.save.import.fail", Strings.parseException(e, false)));
|
ui.showError(Bundles.format("text.save.import.fail", Strings.parseException(e, false)));
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
@@ -249,7 +249,7 @@ public class AndroidLauncher extends AndroidApplication{
|
|||||||
}else if(map){ //open map
|
}else if(map){ //open map
|
||||||
Gdx.app.postRunnable(() -> {
|
Gdx.app.postRunnable(() -> {
|
||||||
System.out.println("Opening map.");
|
System.out.println("Opening map.");
|
||||||
if (!ui.editor.isShown()) {
|
if(!ui.editor.isShown()){
|
||||||
ui.editor.show();
|
ui.editor.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,22 +259,22 @@ public class AndroidLauncher extends AndroidApplication{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}catch (IOException e){
|
}catch(IOException e){
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isPackageInstalled(String packagename) {
|
private boolean isPackageInstalled(String packagename){
|
||||||
try {
|
try{
|
||||||
getPackageManager().getPackageInfo(packagename, 0);
|
getPackageManager().getPackageInfo(packagename, 0);
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
}catch(Exception e){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isTablet(Context context) {
|
private boolean isTablet(Context context){
|
||||||
TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
|
TelephonyManager manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
|
||||||
return manager.getPhoneType() == TelephonyManager.PHONE_TYPE_NONE;
|
return manager.getPhoneType() == TelephonyManager.PHONE_TYPE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,12 +17,12 @@ public class AndroidTextFieldDialog{
|
|||||||
private TextPromptListener listener;
|
private TextPromptListener listener;
|
||||||
private boolean isBuild;
|
private boolean isBuild;
|
||||||
|
|
||||||
public AndroidTextFieldDialog() {
|
public AndroidTextFieldDialog(){
|
||||||
this.activity = (Activity)Gdx.app;
|
this.activity = (Activity) Gdx.app;
|
||||||
load();
|
load();
|
||||||
}
|
}
|
||||||
|
|
||||||
public AndroidTextFieldDialog show() {
|
public AndroidTextFieldDialog show(){
|
||||||
|
|
||||||
activity.runOnUiThread(() -> {
|
activity.runOnUiThread(() -> {
|
||||||
AlertDialog dialog = builder.create();
|
AlertDialog dialog = builder.create();
|
||||||
@@ -36,7 +36,7 @@ public class AndroidTextFieldDialog{
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private AndroidTextFieldDialog load() {
|
private AndroidTextFieldDialog load(){
|
||||||
|
|
||||||
activity.runOnUiThread(() -> {
|
activity.runOnUiThread(() -> {
|
||||||
|
|
||||||
@@ -56,19 +56,20 @@ public class AndroidTextFieldDialog{
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Wait till TextPrompt is built.
|
// Wait till TextPrompt is built.
|
||||||
while (!isBuild) {
|
while(!isBuild){
|
||||||
try {
|
try{
|
||||||
Thread.sleep(10);
|
Thread.sleep(10);
|
||||||
} catch (InterruptedException e) { }
|
}catch(InterruptedException e){
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getResourceId(String pVariableName, String pVariableType) {
|
public int getResourceId(String pVariableName, String pVariableType){
|
||||||
try {
|
try{
|
||||||
return activity.getResources().getIdentifier(pVariableName, pVariableType, activity.getPackageName());
|
return activity.getResources().getIdentifier(pVariableName, pVariableType, activity.getPackageName());
|
||||||
} catch (Exception e) {
|
}catch(Exception e){
|
||||||
Gdx.app.error("Android Dialogs", "Cannot find resouce with name: " + pVariableName
|
Gdx.app.error("Android Dialogs", "Cannot find resouce with name: " + pVariableName
|
||||||
+ " Did you copy the layouts to /res/layouts and /res/layouts_v14 ?");
|
+ " Did you copy the layouts to /res/layouts and /res/layouts_v14 ?");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -76,19 +77,19 @@ public class AndroidTextFieldDialog{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public AndroidTextFieldDialog setText(CharSequence value) {
|
public AndroidTextFieldDialog setText(CharSequence value){
|
||||||
userInput.append(value);
|
userInput.append(value);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AndroidTextFieldDialog setCancelButtonLabel(CharSequence label) {
|
public AndroidTextFieldDialog setCancelButtonLabel(CharSequence label){
|
||||||
builder.setNegativeButton(label, (dialog, id) -> dialog.cancel());
|
builder.setNegativeButton(label, (dialog, id) -> dialog.cancel());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AndroidTextFieldDialog setConfirmButtonLabel(CharSequence label) {
|
public AndroidTextFieldDialog setConfirmButtonLabel(CharSequence label){
|
||||||
builder.setPositiveButton(label, (dialog, id) -> {
|
builder.setPositiveButton(label, (dialog, id) -> {
|
||||||
if (listener != null && !userInput.getText().toString().isEmpty()) {
|
if(listener != null && !userInput.getText().toString().isEmpty()){
|
||||||
listener.confirm(userInput.getText().toString());
|
listener.confirm(userInput.getText().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,18 +97,18 @@ public class AndroidTextFieldDialog{
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AndroidTextFieldDialog setTextPromptListener(TextPromptListener listener) {
|
public AndroidTextFieldDialog setTextPromptListener(TextPromptListener listener){
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AndroidTextFieldDialog setInputType(int type) {
|
public AndroidTextFieldDialog setInputType(int type){
|
||||||
userInput.setInputType(type);
|
userInput.setInputType(type);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AndroidTextFieldDialog setMaxLength(int length) {
|
public AndroidTextFieldDialog setMaxLength(int length){
|
||||||
userInput.setFilters(new InputFilter[] { new InputFilter.LengthFilter(length) });
|
userInput.setFilters(new InputFilter[]{new InputFilter.LengthFilter(length)});
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,12 +8,9 @@ import android.support.v4.app.FragmentManager;
|
|||||||
import android.support.v4.app.FragmentTransaction;
|
import android.support.v4.app.FragmentTransaction;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
|
|
||||||
import org.sufficientlysecure.donations.DonationsFragment;
|
import org.sufficientlysecure.donations.DonationsFragment;
|
||||||
|
|
||||||
public class DonationsActivity extends FragmentActivity {
|
public class DonationsActivity extends FragmentActivity{
|
||||||
DonationsFragment donationsFragment;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Google
|
* Google
|
||||||
*/
|
*/
|
||||||
@@ -21,13 +18,14 @@ public class DonationsActivity extends FragmentActivity {
|
|||||||
private static final String[] GOOGLE_CATALOG = new String[]{
|
private static final String[] GOOGLE_CATALOG = new String[]{
|
||||||
"mindustry.donation.1", "mindustry.donation.2", "mindustry.donation.5",
|
"mindustry.donation.1", "mindustry.donation.2", "mindustry.donation.5",
|
||||||
"mindustry.donation.10", "mindustry.donation.15",
|
"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.
|
* Called when the activity is first created.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState){
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
setTheme(R.style.GdxTheme);
|
setTheme(R.style.GdxTheme);
|
||||||
@@ -35,7 +33,7 @@ public class DonationsActivity extends FragmentActivity {
|
|||||||
setContentView(R.layout.donations_activity);
|
setContentView(R.layout.donations_activity);
|
||||||
|
|
||||||
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
|
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
|
||||||
if (BuildConfig.DONATIONS_GOOGLE) {
|
if(BuildConfig.DONATIONS_GOOGLE){
|
||||||
donationsFragment = DonationsFragment.newInstance(BuildConfig.DEBUG, true, GOOGLE_PUBKEY, GOOGLE_CATALOG,
|
donationsFragment = DonationsFragment.newInstance(BuildConfig.DEBUG, true, GOOGLE_PUBKEY, GOOGLE_CATALOG,
|
||||||
getResources().getStringArray(R.array.donation_google_catalog_values), false, null, null,
|
getResources().getStringArray(R.array.donation_google_catalog_values), false, null, null,
|
||||||
null, false, null, null, false, null);
|
null, false, null, null, false, null);
|
||||||
@@ -48,9 +46,10 @@ public class DonationsActivity extends FragmentActivity {
|
|||||||
|
|
||||||
public void onStart(){
|
public void onStart(){
|
||||||
super.onStart();
|
super.onStart();
|
||||||
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.setOnClickListener(new View.OnClickListener() {
|
b.setOnClickListener(new View.OnClickListener(){
|
||||||
@Override public void onClick(View view) {
|
@Override
|
||||||
|
public void onClick(View view){
|
||||||
donationsFragment.donateGoogleOnClick(donationsFragment.getView());
|
donationsFragment.donateGoogleOnClick(donationsFragment.getView());
|
||||||
b.setEnabled(false);
|
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
|
* 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.
|
* the Fragment like in startActivityForResult(). Thus we need to propagate manually to our Fragment.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
protected void onActivityResult(int requestCode, int resultCode, Intent data){
|
||||||
super.onActivityResult(requestCode, resultCode, 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);
|
b.setEnabled(true);
|
||||||
|
|
||||||
FragmentManager fragmentManager = getSupportFragmentManager();
|
FragmentManager fragmentManager = getSupportFragmentManager();
|
||||||
Fragment fragment = fragmentManager.findFragmentByTag("donationsFragment");
|
Fragment fragment = fragmentManager.findFragmentByTag("donationsFragment");
|
||||||
if (fragment != null) {
|
if(fragment != null){
|
||||||
fragment.onActivityResult(requestCode, resultCode, data);
|
fragment.onActivityResult(requestCode, resultCode, data);
|
||||||
//TODO donation event, set settings?
|
//TODO donation event, set settings?
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,10 +15,17 @@ public class TextFieldDialogListener extends ClickListener{
|
|||||||
private int type;
|
private int type;
|
||||||
private int max;
|
private int max;
|
||||||
|
|
||||||
|
//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, int type, int max){
|
public static void add(TextField field, int type, int max){
|
||||||
field.addListener(new TextFieldDialogListener(field, type, max));
|
field.addListener(new TextFieldDialogListener(field, type, max));
|
||||||
field.addListener(new InputListener(){
|
field.addListener(new InputListener(){
|
||||||
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){
|
||||||
Gdx.input.setOnscreenKeyboardVisible(false);
|
Gdx.input.setOnscreenKeyboardVisible(false);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -29,13 +36,6 @@ public class TextFieldDialogListener extends ClickListener{
|
|||||||
add(field, 0, 16);
|
add(field, 0, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
//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 void clicked(final InputEvent event, float x, float y){
|
public void clicked(final InputEvent event, float x, float y){
|
||||||
|
|
||||||
if(Gdx.app.getType() == ApplicationType.Desktop) return;
|
if(Gdx.app.getType() == ApplicationType.Desktop) return;
|
||||||
|
|||||||
@@ -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.<br>
|
* 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.<br>
|
||||||
* These events may optionally also trigger on the caller client/server as well.<br>
|
* These events may optionally also trigger on the caller client/server as well.<br>
|
||||||
*/
|
*/
|
||||||
public class Annotations {
|
public class Annotations{
|
||||||
|
|
||||||
/**Marks a method as invokable remotely across a server/client connection.*/
|
public enum PacketPriority{
|
||||||
@Target(ElementType.METHOD)
|
/** Gets put in a queue and processed if not connected. */
|
||||||
@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()}.<br>
|
|
||||||
* 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()}. <br>
|
|
||||||
* 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.*/
|
|
||||||
normal,
|
normal,
|
||||||
/**Gets handled immediately, regardless of connection status.*/
|
/** Gets handled immediately, regardless of connection status. */
|
||||||
high,
|
high,
|
||||||
/**Does not get handled unless client is connected.*/
|
/** Does not get handled unless client is connected. */
|
||||||
low
|
low
|
||||||
}
|
}
|
||||||
|
|
||||||
/**A set of two booleans, one specifying server and one specifying client.*/
|
/** A set of two booleans, one specifying server and one specifying client. */
|
||||||
public enum Loc {
|
public enum Loc{
|
||||||
/**Method can only be invoked on the client from the server.*/
|
/** Method can only be invoked on the client from the server. */
|
||||||
server(true, false),
|
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),
|
client(false, true),
|
||||||
/**Method can be invoked from anywhere*/
|
/** Method can be invoked from anywhere */
|
||||||
both(true, true),
|
both(true, true),
|
||||||
/**Neither server nor client.*/
|
/** Neither server nor client. */
|
||||||
none(false, false);
|
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;
|
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;
|
public final boolean isClient;
|
||||||
|
|
||||||
Loc(boolean server, boolean client){
|
Loc(boolean server, boolean client){
|
||||||
@@ -81,12 +42,12 @@ public class Annotations {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Variant {
|
public enum Variant{
|
||||||
/**Method can only be invoked targeting one player.*/
|
/** Method can only be invoked targeting one player. */
|
||||||
one(true, false),
|
one(true, false),
|
||||||
/**Method can only be invoked targeting all players.*/
|
/** Method can only be invoked targeting all players. */
|
||||||
all(false, true),
|
all(false, true),
|
||||||
/**Method targets both one player and all players.*/
|
/** Method targets both one player and all players. */
|
||||||
both(true, true);
|
both(true, true);
|
||||||
|
|
||||||
public final boolean isOne, isAll;
|
public final boolean isOne, isAll;
|
||||||
@@ -96,4 +57,55 @@ public class Annotations {
|
|||||||
this.isAll = isAll;
|
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()}.<br>
|
||||||
|
* 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()}. <br>
|
||||||
|
* 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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,14 +2,14 @@ package io.anuke.annotations;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
/**Represents a class witha list method entries to include in it.*/
|
/** Represents a class witha list method entries to include in it. */
|
||||||
public class ClassEntry {
|
public class ClassEntry{
|
||||||
/**All methods in this generated class.*/
|
/** All methods in this generated class. */
|
||||||
public final ArrayList<MethodEntry> methods = new ArrayList<>();
|
public final ArrayList<MethodEntry> methods = new ArrayList<>();
|
||||||
/**Simple class name.*/
|
/** Simple class name. */
|
||||||
public final String name;
|
public final String name;
|
||||||
|
|
||||||
public ClassEntry(String name) {
|
public ClassEntry(String name){
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,12 +10,16 @@ import javax.tools.Diagnostic.Kind;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Set;
|
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.*/
|
* This class finds reader and writer methods annotated by the {@link io.anuke.annotations.Annotations.WriteClass}
|
||||||
public class IOFinder {
|
* 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<String, ClassSerializer> findSerializers(RoundEnvironment env){
|
public HashMap<String, ClassSerializer> findSerializers(RoundEnvironment env){
|
||||||
HashMap<String, ClassSerializer> result = new HashMap<>();
|
HashMap<String, ClassSerializer> result = new HashMap<>();
|
||||||
|
|
||||||
@@ -51,33 +55,33 @@ public class IOFinder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String getValue(WriteClass write){
|
private String getValue(WriteClass write){
|
||||||
try {
|
try{
|
||||||
Class<?> type = write.value();
|
Class<?> type = write.value();
|
||||||
return type.getName();
|
return type.getName();
|
||||||
}catch (MirroredTypeException e){
|
}catch(MirroredTypeException e){
|
||||||
return e.getTypeMirror().toString();
|
return e.getTypeMirror().toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getValue(ReadClass read){
|
private String getValue(ReadClass read){
|
||||||
try {
|
try{
|
||||||
Class<?> type = read.value();
|
Class<?> type = read.value();
|
||||||
return type.getName();
|
return type.getName();
|
||||||
}catch (MirroredTypeException e){
|
}catch(MirroredTypeException e){
|
||||||
return e.getTypeMirror().toString();
|
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{
|
public static class ClassSerializer{
|
||||||
/**Fully qualified method name of the reader.*/
|
/** Fully qualified method name of the reader. */
|
||||||
public final String readMethod;
|
public final String readMethod;
|
||||||
/**Fully qualified method name of the writer.*/
|
/** Fully qualified method name of the writer. */
|
||||||
public final String writeMethod;
|
public final String writeMethod;
|
||||||
/**Fully qualified class type name.*/
|
/** Fully qualified class type name. */
|
||||||
public final String classType;
|
public final String classType;
|
||||||
|
|
||||||
public ClassSerializer(String readMethod, String writeMethod, String classType) {
|
public ClassSerializer(String readMethod, String writeMethod, String classType){
|
||||||
this.readMethod = readMethod;
|
this.readMethod = readMethod;
|
||||||
this.writeMethod = writeMethod;
|
this.writeMethod = writeMethod;
|
||||||
this.classType = classType;
|
this.classType = classType;
|
||||||
|
|||||||
@@ -6,32 +6,34 @@ import io.anuke.annotations.Annotations.Variant;
|
|||||||
|
|
||||||
import javax.lang.model.element.ExecutableElement;
|
import javax.lang.model.element.ExecutableElement;
|
||||||
|
|
||||||
/**Class that repesents a remote method to be constructed and put into a class.*/
|
/** Class that repesents a remote method to be constructed and put into a class. */
|
||||||
public class MethodEntry {
|
public class MethodEntry{
|
||||||
/**Simple target class name.*/
|
/** Simple target class name. */
|
||||||
public final String className;
|
public final String className;
|
||||||
/**Fully qualified target method to call.*/
|
/** Fully qualified target method to call. */
|
||||||
public final String targetMethod;
|
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;
|
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;
|
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;
|
public final Loc local;
|
||||||
/**Whether this method is unreliable and uses UDP.*/
|
/** Whether this method is unreliable and uses UDP. */
|
||||||
public final boolean unreliable;
|
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;
|
public final boolean forward;
|
||||||
/**Unique method ID.*/
|
/** Unique method ID. */
|
||||||
public final int id;
|
public final int id;
|
||||||
/**The element method associated with this entry.*/
|
/** The element method associated with this entry. */
|
||||||
public final ExecutableElement element;
|
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 final PacketPriority priority;
|
||||||
|
|
||||||
public MethodEntry(String className, String targetMethod, Loc where, Variant target,
|
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.className = className;
|
||||||
this.forward = forward;
|
this.forward = forward;
|
||||||
this.targetMethod = targetMethod;
|
this.targetMethod = targetMethod;
|
||||||
@@ -45,7 +47,7 @@ public class MethodEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode(){
|
||||||
return targetMethod.hashCode();
|
return targetMethod.hashCode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,25 +18,25 @@ import java.util.*;
|
|||||||
import java.util.stream.Collectors;
|
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)
|
@SupportedSourceVersion(SourceVersion.RELEASE_8)
|
||||||
@SupportedAnnotationTypes({
|
@SupportedAnnotationTypes({
|
||||||
"io.anuke.annotations.Annotations.Remote",
|
"io.anuke.annotations.Annotations.Remote",
|
||||||
"io.anuke.annotations.Annotations.WriteClass",
|
"io.anuke.annotations.Annotations.WriteClass",
|
||||||
"io.anuke.annotations.Annotations.ReadClass",
|
"io.anuke.annotations.Annotations.ReadClass",
|
||||||
})
|
})
|
||||||
public class RemoteMethodAnnotationProcessor extends AbstractProcessor {
|
public class RemoteMethodAnnotationProcessor extends AbstractProcessor{
|
||||||
/**Maximum size of each event packet.*/
|
/** Maximum size of each event packet. */
|
||||||
public static final int maxPacketSize = 4096;
|
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";
|
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";
|
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";
|
private static final String readClientName = "RemoteReadClient";
|
||||||
|
|
||||||
/**Processing round number.*/
|
/** Processing round number. */
|
||||||
private int round;
|
private int round;
|
||||||
|
|
||||||
//class serializers
|
//class serializers
|
||||||
@@ -51,7 +51,7 @@ public class RemoteMethodAnnotationProcessor extends AbstractProcessor {
|
|||||||
private ArrayList<ClassEntry> classes;
|
private ArrayList<ClassEntry> classes;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void init(ProcessingEnvironment processingEnv) {
|
public synchronized void init(ProcessingEnvironment processingEnv){
|
||||||
super.init(processingEnv);
|
super.init(processingEnv);
|
||||||
//put all relevant utils into utils class
|
//put all relevant utils into utils class
|
||||||
Utils.typeUtils = processingEnv.getTypeUtils();
|
Utils.typeUtils = processingEnv.getTypeUtils();
|
||||||
@@ -61,15 +61,15 @@ public class RemoteMethodAnnotationProcessor extends AbstractProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv){
|
||||||
if(round > 1) return false; //only process 2 rounds
|
if(round > 1) return false; //only process 2 rounds
|
||||||
|
|
||||||
round ++;
|
round++;
|
||||||
|
|
||||||
try {
|
try{
|
||||||
|
|
||||||
//round 1: find all annotations, generate *writers*
|
//round 1: find all annotations, generate *writers*
|
||||||
if(round == 1) {
|
if(round == 1){
|
||||||
//get serializers
|
//get serializers
|
||||||
serializers = new IOFinder().findSerializers(roundEnv);
|
serializers = new IOFinder().findSerializers(roundEnv);
|
||||||
|
|
||||||
@@ -88,21 +88,21 @@ public class RemoteMethodAnnotationProcessor extends AbstractProcessor {
|
|||||||
orderedElements.sort(Comparator.comparing(Object::toString));
|
orderedElements.sort(Comparator.comparing(Object::toString));
|
||||||
|
|
||||||
//create methods
|
//create methods
|
||||||
for (Element element : orderedElements) {
|
for(Element element : orderedElements){
|
||||||
Remote annotation = element.getAnnotation(Remote.class);
|
Remote annotation = element.getAnnotation(Remote.class);
|
||||||
|
|
||||||
//check for static
|
//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);
|
Utils.messager.printMessage(Kind.ERROR, "All @Remote methods must be public and static: ", element);
|
||||||
}
|
}
|
||||||
|
|
||||||
//can't generate none methods
|
//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);
|
Utils.messager.printMessage(Kind.ERROR, "A @Remote method's targets() cannot be equal to 'none':", element);
|
||||||
}
|
}
|
||||||
|
|
||||||
//get and create class entry if needed
|
//get and create class entry if needed
|
||||||
if (!classMap.containsKey(annotation.in())) {
|
if(!classMap.containsKey(annotation.in())){
|
||||||
ClassEntry clas = new ClassEntry(annotation.in());
|
ClassEntry clas = new ClassEntry(annotation.in());
|
||||||
classMap.put(annotation.in(), clas);
|
classMap.put(annotation.in(), clas);
|
||||||
classes.add(clas);
|
classes.add(clas);
|
||||||
@@ -127,7 +127,7 @@ public class RemoteMethodAnnotationProcessor extends AbstractProcessor {
|
|||||||
writegen.generateFor(classes, packageName);
|
writegen.generateFor(classes, packageName);
|
||||||
|
|
||||||
return true;
|
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);
|
RemoteReadGenerator readgen = new RemoteReadGenerator(serializers);
|
||||||
|
|
||||||
//generate server readers
|
//generate server readers
|
||||||
@@ -147,7 +147,7 @@ public class RemoteMethodAnnotationProcessor extends AbstractProcessor {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}catch (Exception e){
|
}catch(Exception e){
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,22 +14,25 @@ import java.nio.ByteBuffer;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**Generates code for reading remote invoke packets on the client and server.*/
|
/** Generates code for reading remote invoke packets on the client and server. */
|
||||||
public class RemoteReadGenerator {
|
public class RemoteReadGenerator{
|
||||||
private final HashMap<String, ClassSerializer> serializers;
|
private final HashMap<String, ClassSerializer> serializers;
|
||||||
|
|
||||||
/**Creates a read generator that uses the supplied serializer setup.*/
|
/** Creates a read generator that uses the supplied serializer setup. */
|
||||||
public RemoteReadGenerator(HashMap<String, ClassSerializer> serializers) {
|
public RemoteReadGenerator(HashMap<String, ClassSerializer> serializers){
|
||||||
this.serializers = 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 entries List of methods to use/
|
||||||
* @param className Simple target class name.
|
* @param className Simple target class name.
|
||||||
* @param packageName Full target package 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<MethodEntry> entries, String className, String packageName, boolean needsPlayer)
|
public void generateFor(List<MethodEntry> 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);
|
TypeSpec.Builder classBuilder = TypeSpec.classBuilder(className).addModifiers(Modifier.PUBLIC);
|
||||||
|
|
||||||
@@ -69,10 +72,10 @@ public class RemoteReadGenerator {
|
|||||||
StringBuilder varResult = new StringBuilder();
|
StringBuilder varResult = new StringBuilder();
|
||||||
|
|
||||||
//go through each parameter
|
//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);
|
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
|
//full type name of parameter
|
||||||
String typeName = var.asType().toString();
|
String typeName = var.asType().toString();
|
||||||
//name of parameter
|
//name of parameter
|
||||||
@@ -81,17 +84,17 @@ public class RemoteReadGenerator {
|
|||||||
String capName = typeName.equals("byte") ? "" : Character.toUpperCase(typeName.charAt(0)) + typeName.substring(1);
|
String capName = typeName.equals("byte") ? "" : Character.toUpperCase(typeName.charAt(0)) + typeName.substring(1);
|
||||||
|
|
||||||
//write primitives automatically
|
//write primitives automatically
|
||||||
if (Utils.isPrimitive(typeName)) {
|
if(Utils.isPrimitive(typeName)){
|
||||||
if (typeName.equals("boolean")) {
|
if(typeName.equals("boolean")){
|
||||||
readBlock.addStatement("boolean " + varName + " = buffer.get() == 1");
|
readBlock.addStatement("boolean " + varName + " = buffer.get() == 1");
|
||||||
} else {
|
}else{
|
||||||
readBlock.addStatement(typeName + " " + varName + " = buffer.get" + capName + "()");
|
readBlock.addStatement(typeName + " " + varName + " = buffer.get" + capName + "()");
|
||||||
}
|
}
|
||||||
} else {
|
}else{
|
||||||
//else, try and find a serializer
|
//else, try and find a serializer
|
||||||
ClassSerializer ser = serializers.get(typeName);
|
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);
|
Utils.messager.printMessage(Kind.ERROR, "No @ReadClass method to read class type: '" + typeName + "'", var);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -121,7 +124,7 @@ public class RemoteReadGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
readBlock.nextControlFlow("catch (java.lang.Exception e)");
|
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();
|
readBlock.endControlFlow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,17 +14,17 @@ import java.nio.ByteBuffer;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**Generates code for writing remote invoke packets on the client and server.*/
|
/** Generates code for writing remote invoke packets on the client and server. */
|
||||||
public class RemoteWriteGenerator {
|
public class RemoteWriteGenerator{
|
||||||
private final HashMap<String, ClassSerializer> serializers;
|
private final HashMap<String, ClassSerializer> serializers;
|
||||||
|
|
||||||
/**Creates a write generator that uses the supplied serializer setup.*/
|
/** Creates a write generator that uses the supplied serializer setup. */
|
||||||
public RemoteWriteGenerator(HashMap<String, ClassSerializer> serializers) {
|
public RemoteWriteGenerator(HashMap<String, ClassSerializer> serializers){
|
||||||
this.serializers = serializers;
|
this.serializers = serializers;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Generates all classes in this list.*/
|
/** Generates all classes in this list. */
|
||||||
public void generateFor(List<ClassEntry> entries, String packageName) throws IOException {
|
public void generateFor(List<ClassEntry> entries, String packageName) throws IOException{
|
||||||
|
|
||||||
for(ClassEntry entry : entries){
|
for(ClassEntry entry : entries){
|
||||||
//create builder
|
//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){
|
private void writeMethodVariant(TypeSpec.Builder classBuilder, MethodEntry methodEntry, boolean toAll, boolean forwarded){
|
||||||
ExecutableElement elem = methodEntry.element;
|
ExecutableElement elem = methodEntry.element;
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ public class RemoteWriteGenerator {
|
|||||||
if(!forwarded && methodEntry.local != Loc.none){
|
if(!forwarded && methodEntry.local != Loc.none){
|
||||||
//add in local checks
|
//add in local checks
|
||||||
if(methodEntry.local != Loc.both){
|
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
|
//concatenate parameters
|
||||||
@@ -109,16 +109,16 @@ public class RemoteWriteGenerator {
|
|||||||
//special case: calling local-only methods uses the local player
|
//special case: calling local-only methods uses the local player
|
||||||
if(index == 0 && methodEntry.where == Loc.client){
|
if(index == 0 && methodEntry.where == Loc.client){
|
||||||
results.append("io.anuke.mindustry.Vars.players[0]");
|
results.append("io.anuke.mindustry.Vars.players[0]");
|
||||||
}else {
|
}else{
|
||||||
results.append(var.getSimpleName());
|
results.append(var.getSimpleName());
|
||||||
}
|
}
|
||||||
if(index != elem.getParameters().size() - 1) results.append(", ");
|
if(index != elem.getParameters().size() - 1) results.append(", ");
|
||||||
index ++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//add the statement to call it
|
//add the statement to call it
|
||||||
method.addStatement("$N." + elem.getSimpleName() + "(" + results.toString() + ")",
|
method.addStatement("$N." + elem.getSimpleName() + "(" + results.toString() + ")",
|
||||||
((TypeElement)elem.getEnclosingElement()).getQualifiedName().toString());
|
((TypeElement) elem.getEnclosingElement()).getQualifiedName().toString());
|
||||||
|
|
||||||
if(methodEntry.local != Loc.both){
|
if(methodEntry.local != Loc.both){
|
||||||
method.endControlFlow();
|
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
|
//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
|
//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");
|
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
|
//rewind buffer
|
||||||
method.addStatement("TEMP_BUFFER.position(0)");
|
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
|
//first argument is skipped as it is always the player caller
|
||||||
if((!methodEntry.where.isServer/* || methodEntry.mode == Loc.both*/) && i == 0){
|
if((!methodEntry.where.isServer/* || methodEntry.mode == Loc.both*/) && i == 0){
|
||||||
continue;
|
continue;
|
||||||
@@ -164,7 +164,7 @@ public class RemoteWriteGenerator {
|
|||||||
method.beginControlFlow("if(io.anuke.mindustry.net.Net.server())");
|
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
|
if(typeName.equals("boolean")){ //booleans are special
|
||||||
method.addStatement("TEMP_BUFFER.put(" + varName + " ? (byte)1 : 0)");
|
method.addStatement("TEMP_BUFFER.put(" + varName + " ? (byte)1 : 0)");
|
||||||
}else{
|
}else{
|
||||||
@@ -181,7 +181,7 @@ public class RemoteWriteGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//add statement for writing it
|
//add statement for writing it
|
||||||
method.addStatement(ser.writeMethod + "(TEMP_BUFFER, " + varName +")");
|
method.addStatement(ser.writeMethod + "(TEMP_BUFFER, " + varName + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(writePlayerSkipCheck){ //write end check
|
if(writePlayerSkipCheck){ //write end check
|
||||||
@@ -197,7 +197,7 @@ public class RemoteWriteGenerator {
|
|||||||
if(forwarded){ //forward packet
|
if(forwarded){ //forward packet
|
||||||
if(!methodEntry.local.isClient){ //if the client doesn't get it called locally, forward it back after validation
|
if(!methodEntry.local.isClient){ //if the client doesn't get it called locally, forward it back after validation
|
||||||
sendString = "send(";
|
sendString = "send(";
|
||||||
}else {
|
}else{
|
||||||
sendString = "sendExcept(exceptSenderID, ";
|
sendString = "sendExcept(exceptSenderID, ";
|
||||||
}
|
}
|
||||||
}else if(toAll){ //send to all players / to server
|
}else if(toAll){ //send to all players / to server
|
||||||
@@ -207,8 +207,8 @@ public class RemoteWriteGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//send the actual packet
|
//send the actual packet
|
||||||
method.addStatement("io.anuke.mindustry.net.Net." + sendString + "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")+")");
|
(methodEntry.unreliable ? "io.anuke.mindustry.net.Net.SendMode.udp" : "io.anuke.mindustry.net.Net.SendMode.tcp") + ")");
|
||||||
|
|
||||||
|
|
||||||
//end check for server/client
|
//end check for server/client
|
||||||
|
|||||||
@@ -7,14 +7,14 @@ import javax.lang.model.element.TypeElement;
|
|||||||
import javax.lang.model.util.Elements;
|
import javax.lang.model.util.Elements;
|
||||||
import javax.lang.model.util.Types;
|
import javax.lang.model.util.Types;
|
||||||
|
|
||||||
public class Utils {
|
public class Utils{
|
||||||
public static Types typeUtils;
|
public static Types typeUtils;
|
||||||
public static Elements elementUtils;
|
public static Elements elementUtils;
|
||||||
public static Filer filer;
|
public static Filer filer;
|
||||||
public static Messager messager;
|
public static Messager messager;
|
||||||
|
|
||||||
public static String getMethodName(Element element){
|
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){
|
public static boolean isPrimitive(String type){
|
||||||
|
|||||||
+19
-19
@@ -1,22 +1,22 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<module>
|
<module>
|
||||||
<source path="io/anuke/mindustry" />
|
<source path="io/anuke/mindustry"/>
|
||||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.world.Tile" />
|
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.world.Tile"/>
|
||||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.game.Content" />
|
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.game.Content"/>
|
||||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.io.Maps" />
|
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.io.Maps"/>
|
||||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.world.Map" />
|
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.world.Map"/>
|
||||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.game.SpawnGroup" />
|
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.game.SpawnGroup"/>
|
||||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.core.GameState" />
|
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.core.GameState"/>
|
||||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.game.EventType" />
|
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.game.EventType"/>
|
||||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.io.SaveFileVersion" />
|
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.io.SaveFileVersion"/>
|
||||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.ucore.entities.impl.EffectEntity" />
|
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.ucore.entities.impl.EffectEntity"/>
|
||||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.net.Packets" />
|
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.net.Packets"/>
|
||||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.net.Packet" />
|
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.net.Packet"/>
|
||||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.entities.effect" />
|
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.entities.effect"/>
|
||||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.entities.bullet.Bullet" />
|
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.entities.bullet.Bullet"/>
|
||||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.game.Team" />
|
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.game.Team"/>
|
||||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.net.Streamable" />
|
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.net.Streamable"/>
|
||||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.world.meta.BlockBar" />
|
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.world.meta.BlockBar"/>
|
||||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.world.mapgen.WorldGenerator" />
|
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.world.mapgen.WorldGenerator"/>
|
||||||
<extend-configuration-property name="gdx.reflect.include" value="com.badlogic.gdx.utils.Predicate" />
|
<extend-configuration-property name="gdx.reflect.include" value="com.badlogic.gdx.utils.Predicate"/>
|
||||||
</module>
|
</module>
|
||||||
@@ -8,7 +8,7 @@ import io.anuke.ucore.util.Log;
|
|||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
public class Mindustry extends ModuleCore {
|
public class Mindustry extends ModuleCore{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(){
|
public void init(){
|
||||||
|
|||||||
@@ -19,14 +19,54 @@ import io.anuke.mindustry.io.Version;
|
|||||||
import io.anuke.mindustry.net.Net;
|
import io.anuke.mindustry.net.Net;
|
||||||
import io.anuke.ucore.entities.Entities;
|
import io.anuke.ucore.entities.Entities;
|
||||||
import io.anuke.ucore.entities.EntityGroup;
|
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.impl.EffectEntity;
|
||||||
|
import io.anuke.ucore.entities.trait.DrawTrait;
|
||||||
import io.anuke.ucore.scene.ui.layout.Unit;
|
import io.anuke.ucore.scene.ui.layout.Unit;
|
||||||
import io.anuke.ucore.util.OS;
|
import io.anuke.ucore.util.OS;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
public class Vars{
|
public class Vars{
|
||||||
|
//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;
|
public static boolean testMobile;
|
||||||
//shorthand for whether or not this is running on android or ios
|
//shorthand for whether or not this is running on android or ios
|
||||||
public static boolean mobile;
|
public static boolean mobile;
|
||||||
@@ -34,21 +74,6 @@ public class Vars{
|
|||||||
public static boolean android;
|
public static boolean android;
|
||||||
//shorthand for whether or not this is running on GWT
|
//shorthand for whether or not this is running on GWT
|
||||||
public static boolean 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
|
//directory for user-created map data
|
||||||
public static FileHandle customMapDirectory;
|
public static FileHandle customMapDirectory;
|
||||||
//save file directory
|
//save file directory
|
||||||
@@ -74,54 +99,12 @@ public class Vars{
|
|||||||
public static boolean showUI = true;
|
public static boolean showUI = true;
|
||||||
//whether to show block debug
|
//whether to show block debug
|
||||||
public static boolean showBlockDebug = false;
|
public static boolean showBlockDebug = false;
|
||||||
|
|
||||||
public static boolean showFog = true;
|
public static boolean showFog = true;
|
||||||
|
|
||||||
public static final int maxTextLength = 150;
|
|
||||||
public static final int maxNameLength = 40;
|
|
||||||
public static final int maxCharNameLength = 20;
|
|
||||||
|
|
||||||
public static boolean headless = false;
|
public static boolean headless = false;
|
||||||
|
|
||||||
public static float controllerMin = 0.25f;
|
public static float controllerMin = 0.25f;
|
||||||
|
|
||||||
public static float baseControllerSpeed = 11f;
|
public static float baseControllerSpeed = 11f;
|
||||||
|
|
||||||
public static final int saveSlots = 64;
|
|
||||||
|
|
||||||
public static final float itemSize = 5f;
|
|
||||||
|
|
||||||
//only if smoothCamera
|
//only if smoothCamera
|
||||||
public static boolean snapCamera = true;
|
public static boolean snapCamera = true;
|
||||||
|
|
||||||
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 GameState state;
|
public static GameState state;
|
||||||
public static ThreadHandler threads;
|
public static ThreadHandler threads;
|
||||||
|
|
||||||
@@ -180,12 +163,12 @@ public class Vars{
|
|||||||
android = Gdx.app.getType() == ApplicationType.Android;
|
android = Gdx.app.getType() == ApplicationType.Android;
|
||||||
gwt = Gdx.app.getType() == ApplicationType.WebGL;
|
gwt = Gdx.app.getType() == ApplicationType.WebGL;
|
||||||
|
|
||||||
if(!gwt) {
|
if(!gwt){
|
||||||
customMapDirectory = OS.getAppDataDirectory("Mindustry").child("maps/");
|
customMapDirectory = OS.getAppDataDirectory("Mindustry").child("maps/");
|
||||||
saveDirectory = OS.getAppDataDirectory("Mindustry").child("saves/");
|
saveDirectory = OS.getAppDataDirectory("Mindustry").child("saves/");
|
||||||
}
|
}
|
||||||
|
|
||||||
fontScale = Math.max(Unit.dp.scl(1f)/2f, 0.5f);
|
fontScale = Math.max(Unit.dp.scl(1f) / 2f, 0.5f);
|
||||||
baseCameraScale = Math.round(Unit.dp.scl(4));
|
baseCameraScale = Math.round(Unit.dp.scl(4));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,32 +26,53 @@ import static io.anuke.mindustry.Vars.*;
|
|||||||
|
|
||||||
//TODO consider using quadtrees for finding specific types of blocks within an area
|
//TODO consider using quadtrees for finding specific types of blocks within an area
|
||||||
//TODO maybe use Arrays instead of ObjectSets?
|
//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;
|
private final static int oreQuadrantSize = 20;
|
||||||
/**Size of one structure quadrant.*/
|
/**
|
||||||
|
* Size of one structure quadrant.
|
||||||
|
*/
|
||||||
private final static int structQuadrantSize = 12;
|
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<Item> scanOres = ObjectSet.with(Items.tungsten, Items.coal, Items.lead, Items.thorium, Items.titanium);
|
private final ObjectSet<Item> scanOres = ObjectSet.with(Items.tungsten, Items.coal, Items.lead, Items.thorium, Items.titanium);
|
||||||
/**Stores all ore quadtrants on the map.*/
|
|
||||||
private ObjectMap<Item, ObjectSet<Tile>> ores;
|
|
||||||
|
|
||||||
private final ObjectSet<Item> itemSet = new ObjectSet<>();
|
private final ObjectSet<Item> itemSet = new ObjectSet<>();
|
||||||
|
/**
|
||||||
/**Tags all quadrants.*/
|
* Stores all ore quadtrants on the map.
|
||||||
|
*/
|
||||||
|
private ObjectMap<Item, ObjectSet<Tile>> ores;
|
||||||
|
/**
|
||||||
|
* Tags all quadrants.
|
||||||
|
*/
|
||||||
private Bits[] structQuadrants;
|
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<BlockFlag, ObjectSet<Tile>> enemyMap = new ObjectMap<>();
|
private ObjectMap<BlockFlag, ObjectSet<Tile>> 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<BlockFlag, ObjectSet<Tile>> allyMap = new ObjectMap<>();
|
private ObjectMap<BlockFlag, ObjectSet<Tile>> allyMap = new ObjectMap<>();
|
||||||
/**Empty map for invalid teams.*/
|
/**
|
||||||
|
* Empty map for invalid teams.
|
||||||
|
*/
|
||||||
private ObjectMap<BlockFlag, ObjectSet<Tile>> emptyMap = new ObjectMap<>();
|
private ObjectMap<BlockFlag, ObjectSet<Tile>> 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<TileIndex> typeMap = new IntMap<>();
|
private IntMap<TileIndex> typeMap = new IntMap<>();
|
||||||
/**Empty array used for returning.*/
|
/**
|
||||||
|
* Empty array used for returning.
|
||||||
|
*/
|
||||||
private ObjectSet<Tile> emptyArray = new ObjectSet<>();
|
private ObjectSet<Tile> emptyArray = new ObjectSet<>();
|
||||||
|
|
||||||
public BlockIndexer(){
|
public BlockIndexer(){
|
||||||
@@ -74,18 +95,18 @@ public class BlockIndexer {
|
|||||||
|
|
||||||
//create bitset for each team type that contains each quadrant
|
//create bitset for each team type that contains each quadrant
|
||||||
structQuadrants = new Bits[Team.all.length];
|
structQuadrants = new Bits[Team.all.length];
|
||||||
for(int i = 0; i < Team.all.length; i ++){
|
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));
|
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 x = 0; x < world.width(); x++){
|
||||||
for (int y = 0; y < world.height(); y++) {
|
for(int y = 0; y < world.height(); y++){
|
||||||
process(world.tile(x, y));
|
process(world.tile(x, y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int x = 0; x < quadWidth(); x++) {
|
for(int x = 0; x < quadWidth(); x++){
|
||||||
for (int y = 0; y < quadHeight(); y++) {
|
for(int y = 0; y < quadHeight(); y++){
|
||||||
updateQuadrant(world.tile(x * structQuadrantSize, y * structQuadrantSize));
|
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<Tile> getAllied(Team team, BlockFlag type){
|
public ObjectSet<Tile> getAllied(Team team, BlockFlag type){
|
||||||
return (state.teams.get(team).ally ? allyMap : enemyMap).get(type, emptyArray);
|
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<Tile> getEnemy(Team team, BlockFlag type){
|
public ObjectSet<Tile> getEnemy(Team team, BlockFlag type){
|
||||||
return (!state.teams.get(team).ally ? allyMap : enemyMap).get(type, emptyArray);
|
return (!state.teams.get(team).ally ? allyMap : enemyMap).get(type, emptyArray);
|
||||||
}
|
}
|
||||||
@@ -108,13 +133,13 @@ public class BlockIndexer {
|
|||||||
Entity closest = null;
|
Entity closest = null;
|
||||||
float dst = 0;
|
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 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 ry = Math.max((int) ((y - range) / tilesize / structQuadrantSize), 0); ry <= (int) ((y + range) / tilesize / structQuadrantSize) && ry < quadHeight(); ry++){
|
||||||
|
|
||||||
if(!getQuad(team, rx, ry)) continue;
|
if(!getQuad(team, rx, ry)) continue;
|
||||||
|
|
||||||
for(int tx = rx * structQuadrantSize; tx < (rx + 1) * structQuadrantSize && tx < world.width(); tx ++){
|
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 ty = ry * structQuadrantSize; ty < (ry + 1) * structQuadrantSize && ty < world.height(); ty++){
|
||||||
Tile other = world.tile(tx, ty);
|
Tile other = world.tile(tx, ty);
|
||||||
|
|
||||||
if(other == null || other.entity == null || !pred.test(other)) continue;
|
if(other == null || other.entity == null || !pred.test(other)) continue;
|
||||||
@@ -134,22 +159,26 @@ public class BlockIndexer {
|
|||||||
return (TileEntity) closest;
|
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,
|
* 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.
|
* 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<Tile> getOrePositions(Item item){
|
public ObjectSet<Tile> getOrePositions(Item item){
|
||||||
return ores.get(item, emptyArray);
|
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){
|
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;
|
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 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 y = Math.max(0, tile.y - oreQuadrantSize / 2); y < tile.y + oreQuadrantSize / 2 && y < world.height(); y++){
|
||||||
Tile res = world.tile(x, y);
|
Tile res = world.tile(x, y);
|
||||||
if(res.block() == Blocks.air && res.floor().drops != null && res.floor().drops.item == item){
|
if(res.block() == Blocks.air && res.floor().drops != null && res.floor().drops.item == item){
|
||||||
return res;
|
return res;
|
||||||
@@ -186,12 +215,12 @@ public class BlockIndexer {
|
|||||||
int quadrantY = tile.y / oreQuadrantSize;
|
int quadrantY = tile.y / oreQuadrantSize;
|
||||||
itemSet.clear();
|
itemSet.clear();
|
||||||
|
|
||||||
Tile rounded = world.tile(Mathf.clamp(quadrantX * oreQuadrantSize + oreQuadrantSize /2, 0, world.width() - 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));
|
Mathf.clamp(quadrantY * oreQuadrantSize + oreQuadrantSize / 2, 0, world.height() - 1));
|
||||||
|
|
||||||
//find all items that this quadrant contains
|
//find all items that this quadrant contains
|
||||||
for (int x = quadrantX * structQuadrantSize; x < world.width() && x < (quadrantX + 1) * structQuadrantSize; x++) {
|
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 y = quadrantY * structQuadrantSize; y < world.height() && y < (quadrantY + 1) * structQuadrantSize; y++){
|
||||||
Tile result = world.tile(x, y);
|
Tile result = world.tile(x, y);
|
||||||
if(result.block().drops == null || !scanOres.contains(result.block().drops.item)) continue;
|
if(result.block().drops == null || !scanOres.contains(result.block().drops.item)) continue;
|
||||||
|
|
||||||
@@ -200,7 +229,7 @@ public class BlockIndexer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//update quadrant at this position
|
//update quadrant at this position
|
||||||
for (Item item : scanOres){
|
for(Item item : scanOres){
|
||||||
ObjectSet<Tile> set = ores.get(item);
|
ObjectSet<Tile> set = ores.get(item);
|
||||||
|
|
||||||
//update quadrant status depending on whether the item is in it
|
//update quadrant status depending on whether the item is in it
|
||||||
@@ -219,7 +248,7 @@ public class BlockIndexer {
|
|||||||
int index = quadrantX + quadrantY * quadWidth();
|
int index = quadrantX + quadrantY * quadWidth();
|
||||||
//Log.info("Updating quadrant: {0} {1}", quadrantX, quadrantY);
|
//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
|
//fast-set this quadrant to 'occupied' if the tile just placed is already of this team
|
||||||
if(tile.getTeam() == data.team && tile.entity != null){
|
if(tile.getTeam() == data.team && tile.entity != null){
|
||||||
@@ -230,8 +259,8 @@ public class BlockIndexer {
|
|||||||
structQuadrants[data.team.ordinal()].clear(index);
|
structQuadrants[data.team.ordinal()].clear(index);
|
||||||
|
|
||||||
outer:
|
outer:
|
||||||
for (int x = quadrantX * structQuadrantSize; x < world.width() && x < (quadrantX + 1) * structQuadrantSize; x++) {
|
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 y = quadrantY * structQuadrantSize; y < world.height() && y < (quadrantY + 1) * structQuadrantSize; y++){
|
||||||
Tile result = world.tile(x, y);
|
Tile result = world.tile(x, y);
|
||||||
//when a targetable block is found, mark this quadrant as occupied and stop searching
|
//when a targetable block is found, mark this quadrant as occupied and stop searching
|
||||||
if(result.entity != null && result.getTeam() == data.team){
|
if(result.entity != null && result.getTeam() == data.team){
|
||||||
@@ -244,16 +273,16 @@ public class BlockIndexer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean getQuad(Team team, int quadrantX, int quadrantY){
|
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);
|
return structQuadrants[team.ordinal()].get(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int quadWidth(){
|
private int quadWidth(){
|
||||||
return Mathf.ceil(world.width() / (float)structQuadrantSize);
|
return Mathf.ceil(world.width() / (float) structQuadrantSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int quadHeight(){
|
private int quadHeight(){
|
||||||
return Mathf.ceil(world.height() / (float)structQuadrantSize);
|
return Mathf.ceil(world.height() / (float) structQuadrantSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ObjectMap<BlockFlag, ObjectSet<Tile>> getMap(Team team){
|
private ObjectMap<BlockFlag, ObjectSet<Tile>> getMap(Team team){
|
||||||
@@ -269,10 +298,10 @@ public class BlockIndexer {
|
|||||||
ores.put(item, new ObjectSet<>());
|
ores.put(item, new ObjectSet<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int x = 0; x < world.width(); x ++){
|
for(int x = 0; x < world.width(); x++){
|
||||||
for (int y = 0; y < world.height(); y++) {
|
for(int y = 0; y < world.height(); y++){
|
||||||
int qx = (x/ oreQuadrantSize);
|
int qx = (x / oreQuadrantSize);
|
||||||
int qy = (y/ oreQuadrantSize);
|
int qy = (y / oreQuadrantSize);
|
||||||
|
|
||||||
Tile tile = world.tile(x, y);
|
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){
|
if(tile.floor().drops != null && scanOres.contains(tile.floor().drops.item) && tile.block() == Blocks.air){
|
||||||
ores.get(tile.floor().drops.item).add(world.tile(
|
ores.get(tile.floor().drops.item).add(world.tile(
|
||||||
//make sure to clamp quadrant middle position, since it might go off bounds
|
//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(qx * oreQuadrantSize + oreQuadrantSize / 2, 0, world.width() - 1),
|
||||||
Mathf.clamp(qy * oreQuadrantSize + oreQuadrantSize /2, 0, world.height() - 1)));
|
Mathf.clamp(qy * oreQuadrantSize + oreQuadrantSize / 2, 0, world.height() - 1)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -291,7 +320,7 @@ public class BlockIndexer {
|
|||||||
public final EnumSet<BlockFlag> flags;
|
public final EnumSet<BlockFlag> flags;
|
||||||
public final Team team;
|
public final Team team;
|
||||||
|
|
||||||
public TileIndex(EnumSet<BlockFlag> flags, Team team) {
|
public TileIndex(EnumSet<BlockFlag> flags, Team team){
|
||||||
this.flags = flags;
|
this.flags = flags;
|
||||||
this.team = team;
|
this.team = team;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import io.anuke.ucore.util.Log;
|
|||||||
import static io.anuke.mindustry.Vars.state;
|
import static io.anuke.mindustry.Vars.state;
|
||||||
import static io.anuke.mindustry.Vars.world;
|
import static io.anuke.mindustry.Vars.world;
|
||||||
|
|
||||||
public class Pathfinder {
|
public class Pathfinder{
|
||||||
private long maxUpdate = TimeUtils.millisToNanos(4);
|
private long maxUpdate = TimeUtils.millisToNanos(4);
|
||||||
private PathData[] paths;
|
private PathData[] paths;
|
||||||
private IntArray blocked = new IntArray();
|
private IntArray blocked = new IntArray();
|
||||||
@@ -56,7 +56,7 @@ public class Pathfinder {
|
|||||||
|
|
||||||
Tile target = null;
|
Tile target = null;
|
||||||
float tl = 0f;
|
float tl = 0f;
|
||||||
for(GridPoint2 point : Geometry.d8) {
|
for(GridPoint2 point : Geometry.d8){
|
||||||
int dx = tile.x + point.x, dy = tile.y + point.y;
|
int dx = tile.x + point.x, dy = tile.y + point.y;
|
||||||
|
|
||||||
Tile other = world.tile(dx, dy);
|
Tile other = world.tile(dx, dy);
|
||||||
@@ -89,16 +89,16 @@ public class Pathfinder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void update(Tile tile, Team team){
|
private void update(Tile tile, Team team){
|
||||||
if(paths[team.ordinal()] != null) {
|
if(paths[team.ordinal()] != null){
|
||||||
PathData path = paths[team.ordinal()];
|
PathData path = paths[team.ordinal()];
|
||||||
|
|
||||||
if(!passable(tile, team)){
|
if(!passable(tile, team)){
|
||||||
path.weights[tile.x][tile.y] = Float.MAX_VALUE;
|
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();
|
path.frontier.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,17 +115,17 @@ public class Pathfinder {
|
|||||||
|
|
||||||
private void createFor(Team team){
|
private void createFor(Team team){
|
||||||
PathData path = new PathData();
|
PathData path = new PathData();
|
||||||
path.search ++;
|
path.search++;
|
||||||
path.frontier.ensureCapacity((world.width() + world.height()) * 3);
|
path.frontier.ensureCapacity((world.width() + world.height()) * 3);
|
||||||
|
|
||||||
paths[team.ordinal()] = path;
|
paths[team.ordinal()] = path;
|
||||||
|
|
||||||
for (int x = 0; x < world.width(); x++) {
|
for(int x = 0; x < world.width(); x++){
|
||||||
for (int y = 0; y < world.height(); y++) {
|
for(int y = 0; y < world.height(); y++){
|
||||||
Tile tile = world.tile(x, y);
|
Tile tile = world.tile(x, y);
|
||||||
|
|
||||||
if (tile.block().flags != null && state.teams.areEnemies(tile.getTeam(), team)
|
if(tile.block().flags != null && state.teams.areEnemies(tile.getTeam(), team)
|
||||||
&& tile.block().flags.contains(BlockFlag.target)) {
|
&& tile.block().flags.contains(BlockFlag.target)){
|
||||||
path.frontier.addFirst(tile);
|
path.frontier.addFirst(tile);
|
||||||
path.weights[x][y] = 0;
|
path.weights[x][y] = 0;
|
||||||
path.searches[x][y] = path.search;
|
path.searches[x][y] = path.search;
|
||||||
@@ -143,20 +143,20 @@ public class Pathfinder {
|
|||||||
|
|
||||||
long start = TimeUtils.nanoTime();
|
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();
|
Tile tile = path.frontier.removeLast();
|
||||||
float cost = path.weights[tile.x][tile.y];
|
float cost = path.weights[tile.x][tile.y];
|
||||||
|
|
||||||
if (cost < Float.MAX_VALUE) {
|
if(cost < Float.MAX_VALUE){
|
||||||
for (GridPoint2 point : Geometry.d4) {
|
for(GridPoint2 point : Geometry.d4){
|
||||||
|
|
||||||
int dx = tile.x + point.x, dy = tile.y + point.y;
|
int dx = tile.x + point.x, dy = tile.y + point.y;
|
||||||
Tile other = world.tile(dx, dy);
|
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)){
|
&& passable(other, team)){
|
||||||
path.frontier.addFirst(world.tile(dx, dy));
|
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;
|
path.searches[dx][dy] = path.search;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import java.io.IOException;
|
|||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
public class WaveSpawner {
|
public class WaveSpawner{
|
||||||
private static final int quadsize = 4;
|
private static final int quadsize = 4;
|
||||||
|
|
||||||
private Bits quadrants;
|
private Bits quadrants;
|
||||||
@@ -34,28 +34,28 @@ public class WaveSpawner {
|
|||||||
|
|
||||||
public void write(DataOutput output) throws IOException{
|
public void write(DataOutput output) throws IOException{
|
||||||
output.writeShort(flySpawns.size);
|
output.writeShort(flySpawns.size);
|
||||||
for (FlyerSpawn spawn : flySpawns){
|
for(FlyerSpawn spawn : flySpawns){
|
||||||
output.writeFloat(spawn.angle);
|
output.writeFloat(spawn.angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
output.writeShort(groundSpawns.size);
|
output.writeShort(groundSpawns.size);
|
||||||
for (GroundSpawn spawn : groundSpawns){
|
for(GroundSpawn spawn : groundSpawns){
|
||||||
output.writeShort((short)spawn.x);
|
output.writeShort((short) spawn.x);
|
||||||
output.writeShort((short)spawn.y);
|
output.writeShort((short) spawn.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void read(DataInput input) throws IOException{
|
public void read(DataInput input) throws IOException{
|
||||||
short flya = input.readShort();
|
short flya = input.readShort();
|
||||||
|
|
||||||
for (int i = 0; i < flya; i++) {
|
for(int i = 0; i < flya; i++){
|
||||||
FlyerSpawn spawn = new FlyerSpawn();
|
FlyerSpawn spawn = new FlyerSpawn();
|
||||||
spawn.angle = input.readFloat();
|
spawn.angle = input.readFloat();
|
||||||
flySpawns.add(spawn);
|
flySpawns.add(spawn);
|
||||||
}
|
}
|
||||||
|
|
||||||
short grounda = input.readShort();
|
short grounda = input.readShort();
|
||||||
for (int i = 0; i < grounda; i++) {
|
for(int i = 0; i < grounda; i++){
|
||||||
GroundSpawn spawn = new GroundSpawn();
|
GroundSpawn spawn = new GroundSpawn();
|
||||||
spawn.x = input.readShort();
|
spawn.x = input.readShort();
|
||||||
spawn.y = input.readShort();
|
spawn.y = input.readShort();
|
||||||
@@ -80,13 +80,13 @@ public class WaveSpawner {
|
|||||||
int addGround = groundGroups - groundSpawns.size, addFly = flyGroups - flySpawns.size;
|
int addGround = groundGroups - groundSpawns.size, addFly = flyGroups - flySpawns.size;
|
||||||
|
|
||||||
//add extra groups if the total exceeds it
|
//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();
|
GroundSpawn spawn = new GroundSpawn();
|
||||||
findLocation(spawn);
|
findLocation(spawn);
|
||||||
groundSpawns.add(spawn);
|
groundSpawns.add(spawn);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < addFly; i++) {
|
for(int i = 0; i < addFly; i++){
|
||||||
FlyerSpawn spawn = new FlyerSpawn();
|
FlyerSpawn spawn = new FlyerSpawn();
|
||||||
findLocation(spawn);
|
findLocation(spawn);
|
||||||
flySpawns.add(spawn);
|
flySpawns.add(spawn);
|
||||||
@@ -99,7 +99,7 @@ public class WaveSpawner {
|
|||||||
int groups = group.getGroupsSpawned(state.wave);
|
int groups = group.getGroupsSpawned(state.wave);
|
||||||
int spawned = group.getUnitsSpawned(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();
|
Squad squad = new Squad();
|
||||||
float spawnX, spawnY;
|
float spawnX, spawnY;
|
||||||
float spread;
|
float spread;
|
||||||
@@ -109,11 +109,11 @@ public class WaveSpawner {
|
|||||||
//TODO verify flyer spawn
|
//TODO verify flyer spawn
|
||||||
|
|
||||||
float margin = 40f; //how far away from the edge flying units 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);
|
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);
|
spawnY = world.height() * tilesize / 2f + Mathf.sqrwavey(spawn.angle) * (world.height() / 2f * tilesize + margin);
|
||||||
spread = margin / 1.5f;
|
spread = margin / 1.5f;
|
||||||
|
|
||||||
flyCount ++;
|
flyCount++;
|
||||||
}else{
|
}else{
|
||||||
GroundSpawn spawn = groundSpawns.get(groundCount);
|
GroundSpawn spawn = groundSpawns.get(groundCount);
|
||||||
checkQuadrant(spawn.x, spawn.y);
|
checkQuadrant(spawn.x, spawn.y);
|
||||||
@@ -121,14 +121,14 @@ public class WaveSpawner {
|
|||||||
findLocation(spawn);
|
findLocation(spawn);
|
||||||
}
|
}
|
||||||
|
|
||||||
spawnX = spawn.x * quadsize * tilesize + quadsize * tilesize/2f;
|
spawnX = spawn.x * quadsize * tilesize + quadsize * tilesize / 2f;
|
||||||
spawnY = spawn.y * quadsize * tilesize + quadsize * tilesize/2f;
|
spawnY = spawn.y * quadsize * tilesize + quadsize * tilesize / 2f;
|
||||||
spread = quadsize*tilesize/3f;
|
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);
|
BaseUnit unit = group.createUnit(Team.red);
|
||||||
unit.setWave();
|
unit.setWave();
|
||||||
unit.setSquad(squad);
|
unit.setSquad(squad);
|
||||||
@@ -140,8 +140,8 @@ public class WaveSpawner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void checkAllQuadrants(){
|
public void checkAllQuadrants(){
|
||||||
for(int x = 0; x < quadWidth(); x ++){
|
for(int x = 0; x < quadWidth(); x++){
|
||||||
for(int y = 0; y < quadHeight(); y ++){
|
for(int y = 0; y < quadHeight(); y++){
|
||||||
checkQuadrant(x, y);
|
checkQuadrant(x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -151,8 +151,8 @@ public class WaveSpawner {
|
|||||||
setQuad(quadx, quady, true);
|
setQuad(quadx, quady, true);
|
||||||
|
|
||||||
outer:
|
outer:
|
||||||
for (int x = quadx * quadsize; x < world.width() && x < (quadx + 1)*quadsize; x++) {
|
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 y = quady * quadsize; y < world.height() && y < (quady + 1) * quadsize; y++){
|
||||||
Tile tile = world.tile(x, y);
|
Tile tile = world.tile(x, y);
|
||||||
|
|
||||||
if(tile == null || tile.solid() || world.pathfinder().getValueforTeam(Team.red, x, y) == Float.MAX_VALUE){
|
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.x = -1;
|
||||||
spawn.y = -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);
|
shellWidth = Math.min(quadWidth() * quadHeight() / 4, shellWidth);
|
||||||
|
|
||||||
Mathf.traverseSpiral(quadWidth(), quadHeight(), Mathf.random(shellWidth), (x, y) -> {
|
Mathf.traverseSpiral(quadWidth(), quadHeight(), Mathf.random(shellWidth), (x, y) -> {
|
||||||
@@ -210,11 +210,11 @@ public class WaveSpawner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int quadWidth(){
|
private int quadWidth(){
|
||||||
return Mathf.ceil(world.width() / (float)quadsize);
|
return Mathf.ceil(world.width() / (float) quadsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int quadHeight(){
|
private int quadHeight(){
|
||||||
return Mathf.ceil(world.height() / (float)quadsize);
|
return Mathf.ceil(world.height() / (float) quadsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class FlyerSpawn{
|
private class FlyerSpawn{
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import io.anuke.mindustry.game.Content;
|
|||||||
import io.anuke.mindustry.type.AmmoType;
|
import io.anuke.mindustry.type.AmmoType;
|
||||||
import io.anuke.mindustry.type.ContentList;
|
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,
|
public static AmmoType bulletTungsten, bulletLead, bulletCarbide, bulletThorium, bulletSilicon, bulletPyratite,
|
||||||
shotgunTungsten, bombExplosive, bombIncendiary, bombOil, shellCarbide, flamerThermite, weaponMissile,
|
shotgunTungsten, bombExplosive, bombIncendiary, bombOil, shellCarbide, flamerThermite, weaponMissile,
|
||||||
flakLead, flakExplosive, flakPlastic, flakSurge, missileExplosive, missileIncindiary, missileSurge,
|
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;
|
basicFlame, lancerLaser, lightning, spectreLaser, meltdownLaser, fuseShotgun, oil, water, lava, cryofluid;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
|
|
||||||
//weapon specific
|
//weapon specific
|
||||||
|
|
||||||
shotgunTungsten = new AmmoType(Items.tungsten, WeaponBullets.tungstenShotgun, 2) {{
|
shotgunTungsten = new AmmoType(Items.tungsten, WeaponBullets.tungstenShotgun, 2){{
|
||||||
shootEffect = ShootFx.shootBig;
|
shootEffect = ShootFx.shootBig;
|
||||||
smokeEffect = ShootFx.shootBigSmoke;
|
smokeEffect = ShootFx.shootBigSmoke;
|
||||||
recoil = 1f;
|
recoil = 1f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
shellCarbide = new AmmoType(Items.carbide, WeaponBullets.shellCarbide, 2) {{
|
shellCarbide = new AmmoType(Items.carbide, WeaponBullets.shellCarbide, 2){{
|
||||||
shootEffect = ShootFx.shootBig;
|
shootEffect = ShootFx.shootBig;
|
||||||
smokeEffect = ShootFx.shootBigSmoke;
|
smokeEffect = ShootFx.shootBigSmoke;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
bombExplosive = new AmmoType(Items.blastCompound, WeaponBullets.bombExplosive, 3) {{
|
bombExplosive = new AmmoType(Items.blastCompound, WeaponBullets.bombExplosive, 3){{
|
||||||
shootEffect = Fx.none;
|
shootEffect = Fx.none;
|
||||||
smokeEffect = Fx.none;
|
smokeEffect = Fx.none;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
bombIncendiary = new AmmoType(Items.pyratite, WeaponBullets.bombIncendiary, 3) {{
|
bombIncendiary = new AmmoType(Items.pyratite, WeaponBullets.bombIncendiary, 3){{
|
||||||
shootEffect = Fx.none;
|
shootEffect = Fx.none;
|
||||||
smokeEffect = Fx.none;
|
smokeEffect = Fx.none;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
bombOil = new AmmoType(Items.coal, WeaponBullets.bombOil, 3) {{
|
bombOil = new AmmoType(Items.coal, WeaponBullets.bombOil, 3){{
|
||||||
shootEffect = Fx.none;
|
shootEffect = Fx.none;
|
||||||
smokeEffect = Fx.none;
|
smokeEffect = Fx.none;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
flamerThermite = new AmmoType(Items.pyratite, TurretBullets.basicFlame, 3) {{
|
flamerThermite = new AmmoType(Items.pyratite, TurretBullets.basicFlame, 3){{
|
||||||
shootEffect = ShootFx.shootSmallFlame;
|
shootEffect = ShootFx.shootSmallFlame;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
weaponMissile = new AmmoType(Items.carbide, MissileBullets.javelin, 2) {{
|
weaponMissile = new AmmoType(Items.carbide, MissileBullets.javelin, 2){{
|
||||||
shootEffect = BulletFx.hitBulletSmall;
|
shootEffect = BulletFx.hitBulletSmall;
|
||||||
smokeEffect = Fx.none;
|
smokeEffect = Fx.none;
|
||||||
reloadMultiplier = 1.2f;
|
reloadMultiplier = 1.2f;
|
||||||
@@ -59,37 +59,37 @@ public class AmmoTypes implements ContentList {
|
|||||||
|
|
||||||
//bullets
|
//bullets
|
||||||
|
|
||||||
bulletLead = new AmmoType(Items.lead, StandardBullets.lead, 5) {{
|
bulletLead = new AmmoType(Items.lead, StandardBullets.lead, 5){{
|
||||||
shootEffect = ShootFx.shootSmall;
|
shootEffect = ShootFx.shootSmall;
|
||||||
smokeEffect = ShootFx.shootSmallSmoke;
|
smokeEffect = ShootFx.shootSmallSmoke;
|
||||||
reloadMultiplier = 1.6f;
|
reloadMultiplier = 1.6f;
|
||||||
inaccuracy = 5f;
|
inaccuracy = 5f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
bulletTungsten = new AmmoType(Items.tungsten, StandardBullets.tungsten, 2) {{
|
bulletTungsten = new AmmoType(Items.tungsten, StandardBullets.tungsten, 2){{
|
||||||
shootEffect = ShootFx.shootSmall;
|
shootEffect = ShootFx.shootSmall;
|
||||||
smokeEffect = ShootFx.shootSmallSmoke;
|
smokeEffect = ShootFx.shootSmallSmoke;
|
||||||
reloadMultiplier = 0.8f;
|
reloadMultiplier = 0.8f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
bulletCarbide = new AmmoType(Items.carbide, StandardBullets.carbide, 2) {{
|
bulletCarbide = new AmmoType(Items.carbide, StandardBullets.carbide, 2){{
|
||||||
shootEffect = ShootFx.shootSmall;
|
shootEffect = ShootFx.shootSmall;
|
||||||
smokeEffect = ShootFx.shootSmallSmoke;
|
smokeEffect = ShootFx.shootSmallSmoke;
|
||||||
reloadMultiplier = 0.6f;
|
reloadMultiplier = 0.6f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
bulletThorium = new AmmoType(Items.thorium, StandardBullets.thorium, 2) {{
|
bulletThorium = new AmmoType(Items.thorium, StandardBullets.thorium, 2){{
|
||||||
shootEffect = ShootFx.shootBig;
|
shootEffect = ShootFx.shootBig;
|
||||||
smokeEffect = ShootFx.shootBigSmoke;
|
smokeEffect = ShootFx.shootBigSmoke;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
bulletSilicon = new AmmoType(Items.silicon, StandardBullets.homing, 5) {{
|
bulletSilicon = new AmmoType(Items.silicon, StandardBullets.homing, 5){{
|
||||||
shootEffect = ShootFx.shootSmall;
|
shootEffect = ShootFx.shootSmall;
|
||||||
smokeEffect = ShootFx.shootSmallSmoke;
|
smokeEffect = ShootFx.shootSmallSmoke;
|
||||||
reloadMultiplier = 1.4f;
|
reloadMultiplier = 1.4f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
bulletPyratite = new AmmoType(Items.pyratite, StandardBullets.tracer, 3) {{
|
bulletPyratite = new AmmoType(Items.pyratite, StandardBullets.tracer, 3){{
|
||||||
shootEffect = ShootFx.shootSmall;
|
shootEffect = ShootFx.shootSmall;
|
||||||
smokeEffect = ShootFx.shootSmallSmoke;
|
smokeEffect = ShootFx.shootSmallSmoke;
|
||||||
inaccuracy = 3f;
|
inaccuracy = 3f;
|
||||||
@@ -97,71 +97,71 @@ public class AmmoTypes implements ContentList {
|
|||||||
|
|
||||||
//flak
|
//flak
|
||||||
|
|
||||||
flakLead = new AmmoType(Items.lead, FlakBullets.lead, 5) {{
|
flakLead = new AmmoType(Items.lead, FlakBullets.lead, 5){{
|
||||||
shootEffect = ShootFx.shootSmall;
|
shootEffect = ShootFx.shootSmall;
|
||||||
smokeEffect = ShootFx.shootSmallSmoke;
|
smokeEffect = ShootFx.shootSmallSmoke;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
flakExplosive = new AmmoType(Items.blastCompound, FlakBullets.explosive, 5) {{
|
flakExplosive = new AmmoType(Items.blastCompound, FlakBullets.explosive, 5){{
|
||||||
shootEffect = ShootFx.shootSmall;
|
shootEffect = ShootFx.shootSmall;
|
||||||
smokeEffect = ShootFx.shootSmallSmoke;
|
smokeEffect = ShootFx.shootSmallSmoke;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
flakPlastic = new AmmoType(Items.plastanium, FlakBullets.plastic, 5) {{
|
flakPlastic = new AmmoType(Items.plastanium, FlakBullets.plastic, 5){{
|
||||||
shootEffect = ShootFx.shootSmall;
|
shootEffect = ShootFx.shootSmall;
|
||||||
smokeEffect = ShootFx.shootSmallSmoke;
|
smokeEffect = ShootFx.shootSmallSmoke;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
flakSurge = new AmmoType(Items.surgealloy, FlakBullets.surge, 5) {{
|
flakSurge = new AmmoType(Items.surgealloy, FlakBullets.surge, 5){{
|
||||||
shootEffect = ShootFx.shootSmall;
|
shootEffect = ShootFx.shootSmall;
|
||||||
smokeEffect = ShootFx.shootSmallSmoke;
|
smokeEffect = ShootFx.shootSmallSmoke;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
//missiles
|
//missiles
|
||||||
|
|
||||||
missileExplosive = new AmmoType(Items.blastCompound, MissileBullets.explosive, 1) {{
|
missileExplosive = new AmmoType(Items.blastCompound, MissileBullets.explosive, 1){{
|
||||||
shootEffect = ShootFx.shootBig2;
|
shootEffect = ShootFx.shootBig2;
|
||||||
smokeEffect = ShootFx.shootBigSmoke2;
|
smokeEffect = ShootFx.shootBigSmoke2;
|
||||||
reloadMultiplier = 1.2f;
|
reloadMultiplier = 1.2f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
missileIncindiary = new AmmoType(Items.pyratite, MissileBullets.incindiary, 1) {{
|
missileIncindiary = new AmmoType(Items.pyratite, MissileBullets.incindiary, 1){{
|
||||||
shootEffect = ShootFx.shootBig2;
|
shootEffect = ShootFx.shootBig2;
|
||||||
smokeEffect = ShootFx.shootBigSmoke2;
|
smokeEffect = ShootFx.shootBigSmoke2;
|
||||||
reloadMultiplier = 1.0f;
|
reloadMultiplier = 1.0f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
missileSurge = new AmmoType(Items.surgealloy, MissileBullets.surge, 1) {{
|
missileSurge = new AmmoType(Items.surgealloy, MissileBullets.surge, 1){{
|
||||||
shootEffect = ShootFx.shootBig2;
|
shootEffect = ShootFx.shootBig2;
|
||||||
smokeEffect = ShootFx.shootBigSmoke2;
|
smokeEffect = ShootFx.shootBigSmoke2;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
//artillery
|
//artillery
|
||||||
|
|
||||||
artilleryCarbide = new AmmoType(Items.carbide, ArtilleryBullets.carbide, 2) {{
|
artilleryCarbide = new AmmoType(Items.carbide, ArtilleryBullets.carbide, 2){{
|
||||||
shootEffect = ShootFx.shootBig2;
|
shootEffect = ShootFx.shootBig2;
|
||||||
smokeEffect = ShootFx.shootBigSmoke2;
|
smokeEffect = ShootFx.shootBigSmoke2;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
artilleryPlastic = new AmmoType(Items.plastanium, ArtilleryBullets.plastic, 2) {{
|
artilleryPlastic = new AmmoType(Items.plastanium, ArtilleryBullets.plastic, 2){{
|
||||||
shootEffect = ShootFx.shootBig2;
|
shootEffect = ShootFx.shootBig2;
|
||||||
smokeEffect = ShootFx.shootBigSmoke2;
|
smokeEffect = ShootFx.shootBigSmoke2;
|
||||||
reloadMultiplier = 1.4f;
|
reloadMultiplier = 1.4f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
artilleryHoming = new AmmoType(Items.silicon, ArtilleryBullets.homing, 1) {{
|
artilleryHoming = new AmmoType(Items.silicon, ArtilleryBullets.homing, 1){{
|
||||||
shootEffect = ShootFx.shootBig2;
|
shootEffect = ShootFx.shootBig2;
|
||||||
smokeEffect = ShootFx.shootBigSmoke2;
|
smokeEffect = ShootFx.shootBigSmoke2;
|
||||||
reloadMultiplier = 0.9f;
|
reloadMultiplier = 0.9f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
artilleryIncindiary = new AmmoType(Items.pyratite, ArtilleryBullets.incindiary, 2) {{
|
artilleryIncindiary = new AmmoType(Items.pyratite, ArtilleryBullets.incindiary, 2){{
|
||||||
shootEffect = ShootFx.shootBig2;
|
shootEffect = ShootFx.shootBig2;
|
||||||
smokeEffect = ShootFx.shootBigSmoke2;
|
smokeEffect = ShootFx.shootBigSmoke2;
|
||||||
reloadMultiplier = 1.2f;
|
reloadMultiplier = 1.2f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
artilleryExplosive = new AmmoType(Items.blastCompound, ArtilleryBullets.explosive, 1) {{
|
artilleryExplosive = new AmmoType(Items.blastCompound, ArtilleryBullets.explosive, 1){{
|
||||||
shootEffect = ShootFx.shootBig2;
|
shootEffect = ShootFx.shootBig2;
|
||||||
smokeEffect = ShootFx.shootBigSmoke2;
|
smokeEffect = ShootFx.shootBigSmoke2;
|
||||||
reloadMultiplier = 1.6f;
|
reloadMultiplier = 1.6f;
|
||||||
@@ -169,7 +169,7 @@ public class AmmoTypes implements ContentList {
|
|||||||
|
|
||||||
//flame
|
//flame
|
||||||
|
|
||||||
basicFlame = new AmmoType(Liquids.oil, TurretBullets.basicFlame, 0.3f) {{
|
basicFlame = new AmmoType(Liquids.oil, TurretBullets.basicFlame, 0.3f){{
|
||||||
shootEffect = ShootFx.shootSmallFlame;
|
shootEffect = ShootFx.shootSmallFlame;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
@@ -198,7 +198,7 @@ public class AmmoTypes implements ContentList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Array<? extends Content> getAll() {
|
public Array<? extends Content> getAll(){
|
||||||
return AmmoType.all();
|
return AmmoType.all();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,41 +12,41 @@ public class Items implements ContentList{
|
|||||||
biomatter, sand, blastCompound, pyratite;
|
biomatter, sand, blastCompound, pyratite;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
|
|
||||||
stone = new Item("stone", Color.valueOf("777777")) {{
|
stone = new Item("stone", Color.valueOf("777777")){{
|
||||||
hardness = 3;
|
hardness = 3;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
tungsten = new Item("tungsten", Color.valueOf("a0b0c8")) {{
|
tungsten = new Item("tungsten", Color.valueOf("a0b0c8")){{
|
||||||
type = ItemType.material;
|
type = ItemType.material;
|
||||||
hardness = 1;
|
hardness = 1;
|
||||||
cost = 0.75f;
|
cost = 0.75f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
lead = new Item("lead", Color.valueOf("8e85a2")) {{
|
lead = new Item("lead", Color.valueOf("8e85a2")){{
|
||||||
type = ItemType.material;
|
type = ItemType.material;
|
||||||
hardness = 1;
|
hardness = 1;
|
||||||
cost = 0.6f;
|
cost = 0.6f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
coal = new Item("coal", Color.valueOf("272727")) {{
|
coal = new Item("coal", Color.valueOf("272727")){{
|
||||||
explosiveness = 0.2f;
|
explosiveness = 0.2f;
|
||||||
flammability = 0.5f;
|
flammability = 0.5f;
|
||||||
hardness = 2;
|
hardness = 2;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
carbide = new Item("carbide", Color.valueOf("e2e2e2")) {{
|
carbide = new Item("carbide", Color.valueOf("e2e2e2")){{
|
||||||
type = ItemType.material;
|
type = ItemType.material;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
titanium = new Item("titanium", Color.valueOf("8da1e3")) {{
|
titanium = new Item("titanium", Color.valueOf("8da1e3")){{
|
||||||
type = ItemType.material;
|
type = ItemType.material;
|
||||||
hardness = 3;
|
hardness = 3;
|
||||||
cost = 1.1f;
|
cost = 1.1f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
thorium = new Item("thorium", Color.valueOf("f9a3c7")) {{
|
thorium = new Item("thorium", Color.valueOf("f9a3c7")){{
|
||||||
type = ItemType.material;
|
type = ItemType.material;
|
||||||
explosiveness = 0.1f;
|
explosiveness = 0.1f;
|
||||||
hardness = 4;
|
hardness = 4;
|
||||||
@@ -54,49 +54,49 @@ public class Items implements ContentList{
|
|||||||
cost = 1.2f;
|
cost = 1.2f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
silicon = new Item("silicon", Color.valueOf("53565c")) {{
|
silicon = new Item("silicon", Color.valueOf("53565c")){{
|
||||||
type = ItemType.material;
|
type = ItemType.material;
|
||||||
cost = 0.9f;
|
cost = 0.9f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
plastanium = new Item("plastanium", Color.valueOf("e9ead3")) {{
|
plastanium = new Item("plastanium", Color.valueOf("e9ead3")){{
|
||||||
type = ItemType.material;
|
type = ItemType.material;
|
||||||
flammability = 0.1f;
|
flammability = 0.1f;
|
||||||
explosiveness = 0.1f;
|
explosiveness = 0.1f;
|
||||||
cost = 1.5f;
|
cost = 1.5f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
phasematter = new Item("phase-matter", Color.valueOf("f4ba6e")) {{
|
phasematter = new Item("phase-matter", Color.valueOf("f4ba6e")){{
|
||||||
type = ItemType.material;
|
type = ItemType.material;
|
||||||
cost = 1.5f;
|
cost = 1.5f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
surgealloy = new Item("surge-alloy", Color.valueOf("b4d5c7")) {{
|
surgealloy = new Item("surge-alloy", Color.valueOf("b4d5c7")){{
|
||||||
type = ItemType.material;
|
type = ItemType.material;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
biomatter = new Item("biomatter", Color.valueOf("648b55")) {{
|
biomatter = new Item("biomatter", Color.valueOf("648b55")){{
|
||||||
flammability = 0.4f;
|
flammability = 0.4f;
|
||||||
fluxiness = 0.2f;
|
fluxiness = 0.2f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
sand = new Item("sand", Color.valueOf("e3d39e")) {{
|
sand = new Item("sand", Color.valueOf("e3d39e")){{
|
||||||
fluxiness = 0.5f;
|
fluxiness = 0.5f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
blastCompound = new Item("blast-compound", Color.valueOf("ff795e")) {{
|
blastCompound = new Item("blast-compound", Color.valueOf("ff795e")){{
|
||||||
flammability = 0.2f;
|
flammability = 0.2f;
|
||||||
explosiveness = 0.6f;
|
explosiveness = 0.6f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
pyratite = new Item("pyratite", Color.valueOf("ffaa5f")) {{
|
pyratite = new Item("pyratite", Color.valueOf("ffaa5f")){{
|
||||||
flammability = 0.7f;
|
flammability = 0.7f;
|
||||||
explosiveness = 0.2f;
|
explosiveness = 0.2f;
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Array<? extends Content> getAll() {
|
public Array<? extends Content> getAll(){
|
||||||
return Item.all();
|
return Item.all();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ import io.anuke.mindustry.game.Content;
|
|||||||
import io.anuke.mindustry.type.ContentList;
|
import io.anuke.mindustry.type.ContentList;
|
||||||
import io.anuke.mindustry.type.Liquid;
|
import io.anuke.mindustry.type.Liquid;
|
||||||
|
|
||||||
public class Liquids implements ContentList {
|
public class Liquids implements ContentList{
|
||||||
public static Liquid water, lava, oil, cryofluid;
|
public static Liquid water, lava, oil, cryofluid;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
|
|
||||||
water = new Liquid("water", Color.valueOf("486acd")) {
|
water = new Liquid("water", Color.valueOf("486acd")){
|
||||||
{
|
{
|
||||||
heatCapacity = 0.4f;
|
heatCapacity = 0.4f;
|
||||||
tier = 0;
|
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;
|
temperature = 0.8f;
|
||||||
viscosity = 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;
|
viscosity = 0.7f;
|
||||||
flammability = 0.6f;
|
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;
|
heatCapacity = 0.9f;
|
||||||
temperature = 0.25f;
|
temperature = 0.25f;
|
||||||
@@ -50,7 +50,7 @@ public class Liquids implements ContentList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Array<? extends Content> getAll() {
|
public Array<? extends Content> getAll(){
|
||||||
return Liquid.all();
|
return Liquid.all();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,14 +8,16 @@ import io.anuke.mindustry.type.ContentList;
|
|||||||
import io.anuke.mindustry.type.Mech;
|
import io.anuke.mindustry.type.Mech;
|
||||||
import io.anuke.mindustry.type.Upgrade;
|
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;
|
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;
|
public static Mech starterDesktop, starterMobile;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
|
|
||||||
alpha = new Mech("alpha-mech", false){{
|
alpha = new Mech("alpha-mech", false){{
|
||||||
drillPower = 1;
|
drillPower = 1;
|
||||||
@@ -85,7 +87,7 @@ public class Mechs implements ContentList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Array<? extends Content> getAll() {
|
public Array<? extends Content> getAll(){
|
||||||
return Upgrade.all();
|
return Upgrade.all();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,19 +12,19 @@ import static io.anuke.mindustry.type.Category.*;
|
|||||||
public class Recipes implements ContentList{
|
public class Recipes implements ContentList{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load (){
|
public void load(){
|
||||||
//WALLS
|
//WALLS
|
||||||
new Recipe(defense, DefenseBlocks.tungstenWall, new ItemStack(Items.tungsten, 12));
|
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.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.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.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
|
//TURRETS
|
||||||
new Recipe(weapon, TurretBlocks.duo, new ItemStack(Items.tungsten, 40));
|
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(production, ProductionBlocks.oilextractor, new ItemStack(Items.titanium, 40), new ItemStack(Items.surgealloy, 40));*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//new Recipe(distribution, DistributionBlocks.massDriver, new ItemStack(Items.carbide, 1));
|
//new Recipe(distribution, DistributionBlocks.massDriver, new ItemStack(Items.carbide, 1));
|
||||||
|
|
||||||
|
|
||||||
@@ -282,7 +281,7 @@ public class Recipes implements ContentList{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Array<? extends Content> getAll() {
|
public Array<? extends Content> getAll(){
|
||||||
return Recipe.all();
|
return Recipe.all();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,30 +3,30 @@ package io.anuke.mindustry.content;
|
|||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
import io.anuke.mindustry.content.fx.EnvironmentFx;
|
import io.anuke.mindustry.content.fx.EnvironmentFx;
|
||||||
import io.anuke.mindustry.entities.StatusController.StatusEntry;
|
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.entities.Unit;
|
||||||
|
import io.anuke.mindustry.game.Content;
|
||||||
import io.anuke.mindustry.type.ContentList;
|
import io.anuke.mindustry.type.ContentList;
|
||||||
|
import io.anuke.mindustry.type.StatusEffect;
|
||||||
import io.anuke.ucore.core.Effects;
|
import io.anuke.ucore.core.Effects;
|
||||||
import io.anuke.ucore.core.Timers;
|
import io.anuke.ucore.core.Timers;
|
||||||
import io.anuke.ucore.util.Mathf;
|
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;
|
public static StatusEffect none, burning, freezing, wet, melting, tarred, overdrive, shielded;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
|
|
||||||
none = new StatusEffect(0);
|
none = new StatusEffect(0);
|
||||||
|
|
||||||
burning = new StatusEffect(4 * 60f) {
|
burning = new StatusEffect(4 * 60f){
|
||||||
{
|
{
|
||||||
oppositeScale = 0.5f;
|
oppositeScale = 0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StatusEntry getTransition(Unit unit, StatusEffect to, float time, float newTime, StatusEntry result) {
|
public StatusEntry getTransition(Unit unit, StatusEffect to, float time, float newTime, StatusEntry result){
|
||||||
if (to == tarred) {
|
if(to == tarred){
|
||||||
unit.damage(1f);
|
unit.damage(1f);
|
||||||
Effects.effect(EnvironmentFx.burning, unit.x + Mathf.range(unit.getSize() / 2f), unit.y + Mathf.range(unit.getSize() / 2f));
|
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));
|
return result.set(this, Math.min(time + newTime, baseDuration + tarred.baseDuration));
|
||||||
@@ -36,45 +36,45 @@ public class StatusEffects implements ContentList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Unit unit, float time) {
|
public void update(Unit unit, float time){
|
||||||
unit.damagePeriodic(0.04f);
|
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));
|
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;
|
oppositeScale = 0.4f;
|
||||||
speedMultiplier = 0.7f;
|
speedMultiplier = 0.7f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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));
|
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;
|
oppositeScale = 0.5f;
|
||||||
speedMultiplier = 0.999f;
|
speedMultiplier = 0.999f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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.wet, unit.x + Mathf.range(unit.getSize() / 2f), unit.y + Mathf.range(unit.getSize() / 2f));
|
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;
|
oppositeScale = 0.2f;
|
||||||
speedMultiplier = 0.8f;
|
speedMultiplier = 0.8f;
|
||||||
@@ -82,8 +82,8 @@ public class StatusEffects implements ContentList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StatusEntry getTransition(Unit unit, StatusEffect to, float time, float newTime, StatusEntry result) {
|
public StatusEntry getTransition(Unit unit, StatusEffect to, float time, float newTime, StatusEntry result){
|
||||||
if (to == tarred) {
|
if(to == tarred){
|
||||||
return result.set(this, Math.min(time + newTime / 2f, baseDuration));
|
return result.set(this, Math.min(time + newTime / 2f, baseDuration));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,30 +91,30 @@ public class StatusEffects implements ContentList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Unit unit, float time) {
|
public void update(Unit unit, float time){
|
||||||
unit.damagePeriodic(0.3f);
|
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));
|
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;
|
speedMultiplier = 0.6f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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.oily, unit.x + Mathf.range(unit.getSize() / 2f), unit.y + Mathf.range(unit.getSize() / 2f));
|
Effects.effect(EnvironmentFx.oily, unit.x + Mathf.range(unit.getSize() / 2f), unit.y + Mathf.range(unit.getSize() / 2f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StatusEntry getTransition(Unit unit, StatusEffect to, float time, float newTime, StatusEntry result) {
|
public StatusEntry getTransition(Unit unit, StatusEffect to, float time, float newTime, StatusEntry result){
|
||||||
if (to == melting || to == burning) {
|
if(to == melting || to == burning){
|
||||||
return result.set(to, newTime + time);
|
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;
|
armorMultiplier = 0.95f;
|
||||||
speedMultiplier = 1.05f;
|
speedMultiplier = 1.05f;
|
||||||
@@ -130,13 +130,13 @@ public class StatusEffects implements ContentList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Unit unit, float time) {
|
public void update(Unit unit, float time){
|
||||||
//idle regen boosted
|
//idle regen boosted
|
||||||
unit.health += 0.01f * Timers.delta();
|
unit.health += 0.01f * Timers.delta();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
shielded = new StatusEffect(6f) {
|
shielded = new StatusEffect(6f){
|
||||||
{
|
{
|
||||||
armorMultiplier = 3f;
|
armorMultiplier = 3f;
|
||||||
}
|
}
|
||||||
@@ -149,7 +149,7 @@ public class StatusEffects implements ContentList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Array<? extends Content> getAll() {
|
public Array<? extends Content> getAll(){
|
||||||
return StatusEffect.all();
|
return StatusEffect.all();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ import io.anuke.mindustry.entities.units.types.*;
|
|||||||
import io.anuke.mindustry.game.Content;
|
import io.anuke.mindustry.game.Content;
|
||||||
import io.anuke.mindustry.type.ContentList;
|
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;
|
public static UnitType drone, scout, vtol, monsoon, titan, fabricator;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
drone = new UnitType("drone", Drone.class, Drone::new){{
|
drone = new UnitType("drone", Drone.class, Drone::new){{
|
||||||
isFlying = true;
|
isFlying = true;
|
||||||
drag = 0.01f;
|
drag = 0.01f;
|
||||||
@@ -73,7 +73,7 @@ public class UnitTypes implements ContentList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Array<? extends Content> getAll() {
|
public Array<? extends Content> getAll(){
|
||||||
return UnitType.all();
|
return UnitType.all();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ import io.anuke.mindustry.type.ContentList;
|
|||||||
import io.anuke.mindustry.type.Upgrade;
|
import io.anuke.mindustry.type.Upgrade;
|
||||||
import io.anuke.mindustry.type.Weapon;
|
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;
|
public static Weapon blaster, chainBlaster, shockgun, sapper, swarmer, bomber, flakgun, flamethrower, missiles;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
|
|
||||||
blaster = new Weapon("blaster") {{
|
blaster = new Weapon("blaster"){{
|
||||||
length = 1.5f;
|
length = 1.5f;
|
||||||
reload = 15f;
|
reload = 15f;
|
||||||
roundrobin = true;
|
roundrobin = true;
|
||||||
@@ -22,7 +22,7 @@ public class Weapons implements ContentList {
|
|||||||
setAmmo(AmmoTypes.bulletLead);
|
setAmmo(AmmoTypes.bulletLead);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
missiles = new Weapon("missiles") {{
|
missiles = new Weapon("missiles"){{
|
||||||
length = 1.5f;
|
length = 1.5f;
|
||||||
reload = 40f;
|
reload = 40f;
|
||||||
shots = 2;
|
shots = 2;
|
||||||
@@ -33,7 +33,7 @@ public class Weapons implements ContentList {
|
|||||||
setAmmo(AmmoTypes.weaponMissile);
|
setAmmo(AmmoTypes.weaponMissile);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
chainBlaster = new Weapon("chain-blaster") {{
|
chainBlaster = new Weapon("chain-blaster"){{
|
||||||
length = 1.5f;
|
length = 1.5f;
|
||||||
reload = 30f;
|
reload = 30f;
|
||||||
roundrobin = true;
|
roundrobin = true;
|
||||||
@@ -41,7 +41,7 @@ public class Weapons implements ContentList {
|
|||||||
setAmmo(AmmoTypes.bulletLead, AmmoTypes.bulletCarbide, AmmoTypes.bulletTungsten, AmmoTypes.bulletSilicon, AmmoTypes.bulletThorium);
|
setAmmo(AmmoTypes.bulletLead, AmmoTypes.bulletCarbide, AmmoTypes.bulletTungsten, AmmoTypes.bulletSilicon, AmmoTypes.bulletThorium);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
shockgun = new Weapon("shockgun") {{
|
shockgun = new Weapon("shockgun"){{
|
||||||
length = 1f;
|
length = 1f;
|
||||||
reload = 50f;
|
reload = 50f;
|
||||||
roundrobin = true;
|
roundrobin = true;
|
||||||
@@ -53,7 +53,7 @@ public class Weapons implements ContentList {
|
|||||||
setAmmo(AmmoTypes.shotgunTungsten);
|
setAmmo(AmmoTypes.shotgunTungsten);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
flakgun = new Weapon("flakgun") {{
|
flakgun = new Weapon("flakgun"){{
|
||||||
length = 1f;
|
length = 1f;
|
||||||
reload = 70f;
|
reload = 70f;
|
||||||
roundrobin = true;
|
roundrobin = true;
|
||||||
@@ -65,7 +65,7 @@ public class Weapons implements ContentList {
|
|||||||
setAmmo(AmmoTypes.shellCarbide);
|
setAmmo(AmmoTypes.shellCarbide);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
flamethrower = new Weapon("flamethrower") {{
|
flamethrower = new Weapon("flamethrower"){{
|
||||||
length = 1f;
|
length = 1f;
|
||||||
reload = 14f;
|
reload = 14f;
|
||||||
roundrobin = true;
|
roundrobin = true;
|
||||||
@@ -74,7 +74,7 @@ public class Weapons implements ContentList {
|
|||||||
setAmmo(AmmoTypes.flamerThermite);
|
setAmmo(AmmoTypes.flamerThermite);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
sapper = new Weapon("sapper") {{
|
sapper = new Weapon("sapper"){{
|
||||||
length = 1.5f;
|
length = 1.5f;
|
||||||
reload = 12f;
|
reload = 12f;
|
||||||
roundrobin = true;
|
roundrobin = true;
|
||||||
@@ -82,7 +82,7 @@ public class Weapons implements ContentList {
|
|||||||
setAmmo(AmmoTypes.bulletCarbide);
|
setAmmo(AmmoTypes.bulletCarbide);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
swarmer = new Weapon("swarmer") {{
|
swarmer = new Weapon("swarmer"){{
|
||||||
length = 1.5f;
|
length = 1.5f;
|
||||||
reload = 10f;
|
reload = 10f;
|
||||||
roundrobin = true;
|
roundrobin = true;
|
||||||
@@ -90,7 +90,7 @@ public class Weapons implements ContentList {
|
|||||||
setAmmo(AmmoTypes.bulletPyratite);
|
setAmmo(AmmoTypes.bulletPyratite);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
bomber = new Weapon("bomber") {{
|
bomber = new Weapon("bomber"){{
|
||||||
length = 0f;
|
length = 0f;
|
||||||
width = 2f;
|
width = 2f;
|
||||||
reload = 5f;
|
reload = 5f;
|
||||||
@@ -103,7 +103,7 @@ public class Weapons implements ContentList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Array<? extends Content> getAll() {
|
public Array<? extends Content> getAll(){
|
||||||
return Upgrade.all();
|
return Upgrade.all();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ import io.anuke.mindustry.game.Content;
|
|||||||
import io.anuke.mindustry.type.ContentList;
|
import io.anuke.mindustry.type.ContentList;
|
||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.Block;
|
||||||
|
|
||||||
public abstract class BlockList implements ContentList {
|
public abstract class BlockList implements ContentList{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Array<? extends Content> getAll() {
|
public Array<? extends Content> getAll(){
|
||||||
return Block.all();
|
return Block.all();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
public static Block air, spawn, blockpart, space, metalfloor, deepwater, water, lava, oil, stone, blackstone, dirt, sand, ice, snow, grass, shrub, rock, icerock, blackrock;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
air = new Floor("air") {
|
air = new Floor("air"){
|
||||||
{
|
{
|
||||||
blend = false;
|
blend = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//don't draw
|
//don't draw
|
||||||
public void draw(Tile tile) {}
|
public void draw(Tile tile){
|
||||||
public void load() {}
|
}
|
||||||
public void init() {}
|
|
||||||
|
public void load(){
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(){
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
blockpart = new BlockPart();
|
blockpart = new BlockPart();
|
||||||
|
|
||||||
for(int i = 1; i <= 6; i ++){
|
for(int i = 1; i <= 6; i++){
|
||||||
new BuildBlock("build" + i);
|
new BuildBlock("build" + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
space = new Floor("space") {{
|
space = new Floor("space"){{
|
||||||
placeableOn = false;
|
placeableOn = false;
|
||||||
variants = 0;
|
variants = 0;
|
||||||
cacheLayer = CacheLayer.space;
|
cacheLayer = CacheLayer.space;
|
||||||
@@ -43,11 +48,11 @@ public class Blocks extends BlockList implements ContentList{
|
|||||||
minimapColor = Color.valueOf("000001");
|
minimapColor = Color.valueOf("000001");
|
||||||
}};
|
}};
|
||||||
|
|
||||||
metalfloor = new Floor("metalfloor") {{
|
metalfloor = new Floor("metalfloor"){{
|
||||||
variants = 6;
|
variants = 6;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
deepwater = new Floor("deepwater") {{
|
deepwater = new Floor("deepwater"){{
|
||||||
liquidColor = Color.valueOf("546bb3");
|
liquidColor = Color.valueOf("546bb3");
|
||||||
speedMultiplier = 0.2f;
|
speedMultiplier = 0.2f;
|
||||||
variants = 0;
|
variants = 0;
|
||||||
@@ -60,7 +65,7 @@ public class Blocks extends BlockList implements ContentList{
|
|||||||
minimapColor = Color.valueOf("465a96");
|
minimapColor = Color.valueOf("465a96");
|
||||||
}};
|
}};
|
||||||
|
|
||||||
water = new Floor("water") {{
|
water = new Floor("water"){{
|
||||||
liquidColor = Color.valueOf("546bb3");
|
liquidColor = Color.valueOf("546bb3");
|
||||||
speedMultiplier = 0.5f;
|
speedMultiplier = 0.5f;
|
||||||
variants = 0;
|
variants = 0;
|
||||||
@@ -72,7 +77,7 @@ public class Blocks extends BlockList implements ContentList{
|
|||||||
minimapColor = Color.valueOf("506eb4");
|
minimapColor = Color.valueOf("506eb4");
|
||||||
}};
|
}};
|
||||||
|
|
||||||
lava = new Floor("lava") {{
|
lava = new Floor("lava"){{
|
||||||
liquidColor = Color.valueOf("ed5334");
|
liquidColor = Color.valueOf("ed5334");
|
||||||
speedMultiplier = 0.2f;
|
speedMultiplier = 0.2f;
|
||||||
damageTaken = 0.5f;
|
damageTaken = 0.5f;
|
||||||
@@ -85,7 +90,7 @@ public class Blocks extends BlockList implements ContentList{
|
|||||||
minimapColor = Color.valueOf("ed5334");
|
minimapColor = Color.valueOf("ed5334");
|
||||||
}};
|
}};
|
||||||
|
|
||||||
oil = new Floor("oil") {{
|
oil = new Floor("oil"){{
|
||||||
liquidColor = Color.valueOf("292929");
|
liquidColor = Color.valueOf("292929");
|
||||||
status = StatusEffects.tarred;
|
status = StatusEffects.tarred;
|
||||||
statusIntensity = 1f;
|
statusIntensity = 1f;
|
||||||
@@ -97,7 +102,7 @@ public class Blocks extends BlockList implements ContentList{
|
|||||||
minimapColor = Color.valueOf("292929");
|
minimapColor = Color.valueOf("292929");
|
||||||
}};
|
}};
|
||||||
|
|
||||||
stone = new Floor("stone") {{
|
stone = new Floor("stone"){{
|
||||||
hasOres = true;
|
hasOres = true;
|
||||||
drops = new ItemStack(Items.stone, 1);
|
drops = new ItemStack(Items.stone, 1);
|
||||||
blends = block -> block != this && !(block instanceof Ore);
|
blends = block -> block != this && !(block instanceof Ore);
|
||||||
@@ -105,7 +110,7 @@ public class Blocks extends BlockList implements ContentList{
|
|||||||
playerUnmineable = true;
|
playerUnmineable = true;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
blackstone = new Floor("blackstone") {{
|
blackstone = new Floor("blackstone"){{
|
||||||
drops = new ItemStack(Items.stone, 1);
|
drops = new ItemStack(Items.stone, 1);
|
||||||
minimapColor = Color.valueOf("252525");
|
minimapColor = Color.valueOf("252525");
|
||||||
playerUnmineable = true;
|
playerUnmineable = true;
|
||||||
@@ -115,14 +120,14 @@ public class Blocks extends BlockList implements ContentList{
|
|||||||
minimapColor = Color.valueOf("6e501e");
|
minimapColor = Color.valueOf("6e501e");
|
||||||
}};
|
}};
|
||||||
|
|
||||||
sand = new Floor("sand") {{
|
sand = new Floor("sand"){{
|
||||||
drops = new ItemStack(Items.sand, 1);
|
drops = new ItemStack(Items.sand, 1);
|
||||||
minimapColor = Color.valueOf("988a67");
|
minimapColor = Color.valueOf("988a67");
|
||||||
hasOres = true;
|
hasOres = true;
|
||||||
playerUnmineable = true;
|
playerUnmineable = true;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
ice = new Floor("ice") {{
|
ice = new Floor("ice"){{
|
||||||
dragMultiplier = 0.3f;
|
dragMultiplier = 0.3f;
|
||||||
speedMultiplier = 0.4f;
|
speedMultiplier = 0.4f;
|
||||||
minimapColor = Color.valueOf("c4e3e7");
|
minimapColor = Color.valueOf("c4e3e7");
|
||||||
@@ -143,15 +148,15 @@ public class Blocks extends BlockList implements ContentList{
|
|||||||
shadow = "shrubshadow";
|
shadow = "shrubshadow";
|
||||||
}};
|
}};
|
||||||
|
|
||||||
rock = new Rock("rock") {{
|
rock = new Rock("rock"){{
|
||||||
variants = 2;
|
variants = 2;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
icerock = new Rock("icerock") {{
|
icerock = new Rock("icerock"){{
|
||||||
variants = 2;
|
variants = 2;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
blackrock = new Rock("blackrock") {{
|
blackrock = new Rock("blackrock"){{
|
||||||
variants = 1;
|
variants = 1;
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,14 +10,14 @@ import io.anuke.mindustry.type.ItemStack;
|
|||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.Block;
|
||||||
import io.anuke.mindustry.world.blocks.production.*;
|
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,
|
public static Block smelter, arcsmelter, siliconsmelter, plastaniumCompressor, phaseWeaver, alloysmelter, alloyfuser,
|
||||||
pyratiteMixer, blastMixer,
|
pyratiteMixer, blastMixer,
|
||||||
cryofluidmixer, melter, separator, centrifuge, biomatterCompressor, pulverizer, solidifier, incinerator;
|
cryofluidmixer, melter, separator, centrifuge, biomatterCompressor, pulverizer, solidifier, incinerator;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
smelter = new Smelter("smelter") {{
|
smelter = new Smelter("smelter"){{
|
||||||
health = 70;
|
health = 70;
|
||||||
result = Items.carbide;
|
result = Items.carbide;
|
||||||
craftTime = 45f;
|
craftTime = 45f;
|
||||||
@@ -28,7 +28,7 @@ public class CraftingBlocks extends BlockList implements ContentList {
|
|||||||
consumes.item(Items.coal);
|
consumes.item(Items.coal);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
arcsmelter = new PowerSmelter("arc-smelter") {{
|
arcsmelter = new PowerSmelter("arc-smelter"){{
|
||||||
health = 90;
|
health = 90;
|
||||||
craftEffect = BlockFx.smeltsmoke;
|
craftEffect = BlockFx.smeltsmoke;
|
||||||
result = Items.carbide;
|
result = Items.carbide;
|
||||||
@@ -42,7 +42,7 @@ public class CraftingBlocks extends BlockList implements ContentList {
|
|||||||
consumes.power(0.1f);
|
consumes.power(0.1f);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
siliconsmelter = new PowerSmelter("silicon-smelter") {{
|
siliconsmelter = new PowerSmelter("silicon-smelter"){{
|
||||||
health = 90;
|
health = 90;
|
||||||
craftEffect = BlockFx.smeltsmoke;
|
craftEffect = BlockFx.smeltsmoke;
|
||||||
result = Items.silicon;
|
result = Items.silicon;
|
||||||
@@ -55,7 +55,7 @@ public class CraftingBlocks extends BlockList implements ContentList {
|
|||||||
consumes.power(0.05f);
|
consumes.power(0.05f);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
plastaniumCompressor = new PlastaniumCompressor("plastanium-compressor") {{
|
plastaniumCompressor = new PlastaniumCompressor("plastanium-compressor"){{
|
||||||
hasItems = true;
|
hasItems = true;
|
||||||
liquidCapacity = 60f;
|
liquidCapacity = 60f;
|
||||||
craftTime = 80f;
|
craftTime = 80f;
|
||||||
@@ -72,7 +72,7 @@ public class CraftingBlocks extends BlockList implements ContentList {
|
|||||||
consumes.item(Items.titanium, 2);
|
consumes.item(Items.titanium, 2);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
phaseWeaver = new PhaseWeaver("phase-weaver") {{
|
phaseWeaver = new PhaseWeaver("phase-weaver"){{
|
||||||
health = 90;
|
health = 90;
|
||||||
craftEffect = BlockFx.smeltsmoke;
|
craftEffect = BlockFx.smeltsmoke;
|
||||||
result = Items.phasematter;
|
result = Items.phasematter;
|
||||||
@@ -83,7 +83,7 @@ public class CraftingBlocks extends BlockList implements ContentList {
|
|||||||
consumes.power(0.5f);
|
consumes.power(0.5f);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
alloysmelter = new PowerSmelter("alloy-smelter") {{
|
alloysmelter = new PowerSmelter("alloy-smelter"){{
|
||||||
health = 90;
|
health = 90;
|
||||||
craftEffect = BlockFx.smeltsmoke;
|
craftEffect = BlockFx.smeltsmoke;
|
||||||
result = Items.surgealloy;
|
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)});
|
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;
|
health = 90;
|
||||||
craftEffect = BlockFx.smeltsmoke;
|
craftEffect = BlockFx.smeltsmoke;
|
||||||
result = Items.surgealloy;
|
result = Items.surgealloy;
|
||||||
@@ -111,7 +111,7 @@ public class CraftingBlocks extends BlockList implements ContentList {
|
|||||||
consumes.power(0.4f);
|
consumes.power(0.4f);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
cryofluidmixer = new LiquidMixer("cryofluidmixer") {{
|
cryofluidmixer = new LiquidMixer("cryofluidmixer"){{
|
||||||
health = 200;
|
health = 200;
|
||||||
outputLiquid = Liquids.cryofluid;
|
outputLiquid = Liquids.cryofluid;
|
||||||
liquidPerItem = 50f;
|
liquidPerItem = 50f;
|
||||||
@@ -124,7 +124,7 @@ public class CraftingBlocks extends BlockList implements ContentList {
|
|||||||
consumes.liquid(Liquids.water, 0.3f);
|
consumes.liquid(Liquids.water, 0.3f);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
blastMixer = new GenericCrafter("blast-mixer") {{
|
blastMixer = new GenericCrafter("blast-mixer"){{
|
||||||
itemCapacity = 20;
|
itemCapacity = 20;
|
||||||
hasItems = true;
|
hasItems = true;
|
||||||
hasPower = true;
|
hasPower = true;
|
||||||
@@ -137,7 +137,7 @@ public class CraftingBlocks extends BlockList implements ContentList {
|
|||||||
consumes.power(0.04f);
|
consumes.power(0.04f);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
pyratiteMixer = new PowerSmelter("pyratite-mixer") {{
|
pyratiteMixer = new PowerSmelter("pyratite-mixer"){{
|
||||||
flameColor = Color.CLEAR;
|
flameColor = Color.CLEAR;
|
||||||
itemCapacity = 20;
|
itemCapacity = 20;
|
||||||
hasItems = true;
|
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)});
|
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;
|
health = 200;
|
||||||
outputLiquid = Liquids.lava;
|
outputLiquid = Liquids.lava;
|
||||||
outputLiquidAmount = 0.75f;
|
outputLiquidAmount = 0.75f;
|
||||||
@@ -162,7 +162,7 @@ public class CraftingBlocks extends BlockList implements ContentList {
|
|||||||
consumes.item(Items.stone, 2);
|
consumes.item(Items.stone, 2);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
separator = new Separator("separator") {{
|
separator = new Separator("separator"){{
|
||||||
results = new Item[]{
|
results = new Item[]{
|
||||||
null, null, null, null, null, null, null, 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, 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);
|
consumes.liquid(Liquids.water, 0.3f);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
centrifuge = new Separator("centrifuge") {{
|
centrifuge = new Separator("centrifuge"){{
|
||||||
results = new Item[]{
|
results = new Item[]{
|
||||||
null, null, null, null, null, null, null, null, null, null, null, null, null,
|
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,
|
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);
|
consumes.liquid(Liquids.water, 0.5f);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
biomatterCompressor = new Compressor("biomattercompressor") {{
|
biomatterCompressor = new Compressor("biomattercompressor"){{
|
||||||
liquidCapacity = 60f;
|
liquidCapacity = 60f;
|
||||||
itemCapacity = 50;
|
itemCapacity = 50;
|
||||||
craftTime = 25f;
|
craftTime = 25f;
|
||||||
@@ -221,7 +221,7 @@ public class CraftingBlocks extends BlockList implements ContentList {
|
|||||||
consumes.power(0.06f);
|
consumes.power(0.06f);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
pulverizer = new Pulverizer("pulverizer") {{
|
pulverizer = new Pulverizer("pulverizer"){{
|
||||||
itemCapacity = 40;
|
itemCapacity = 40;
|
||||||
output = Items.sand;
|
output = Items.sand;
|
||||||
health = 80;
|
health = 80;
|
||||||
@@ -234,7 +234,7 @@ public class CraftingBlocks extends BlockList implements ContentList {
|
|||||||
consumes.power(0.2f);
|
consumes.power(0.2f);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
solidifier = new GenericCrafter("solidifer") {{
|
solidifier = new GenericCrafter("solidifer"){{
|
||||||
liquidCapacity = 21f;
|
liquidCapacity = 21f;
|
||||||
craftTime = 14;
|
craftTime = 14;
|
||||||
output = Items.stone;
|
output = Items.stone;
|
||||||
@@ -246,7 +246,7 @@ public class CraftingBlocks extends BlockList implements ContentList {
|
|||||||
consumes.liquid(Liquids.lava, 1f);
|
consumes.liquid(Liquids.lava, 1f);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
incinerator = new Incinerator("incinerator") {{
|
incinerator = new Incinerator("incinerator"){{
|
||||||
health = 90;
|
health = 90;
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,45 +28,52 @@ import java.io.IOException;
|
|||||||
public class DebugBlocks extends BlockList implements ContentList{
|
public class DebugBlocks extends BlockList implements ContentList{
|
||||||
public static Block powerVoid, powerInfinite, itemSource, liquidSource, itemVoid;
|
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
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
powerVoid = new PowerBlock("powervoid") {
|
powerVoid = new PowerBlock("powervoid"){
|
||||||
{
|
{
|
||||||
powerCapacity = Float.MAX_VALUE;
|
powerCapacity = Float.MAX_VALUE;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
powerInfinite = new PowerNode("powerinfinite") {
|
powerInfinite = new PowerNode("powerinfinite"){
|
||||||
{
|
{
|
||||||
powerCapacity = 10000f;
|
powerCapacity = 10000f;
|
||||||
powerSpeed = 100f;
|
powerSpeed = 100f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Tile tile) {
|
public void update(Tile tile){
|
||||||
super.update(tile);
|
super.update(tile);
|
||||||
tile.entity.power.amount = powerCapacity;
|
tile.entity.power.amount = powerCapacity;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
itemSource = new Sorter("itemsource") {
|
itemSource = new Sorter("itemsource"){
|
||||||
{
|
{
|
||||||
hasItems = true;
|
hasItems = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Tile tile) {
|
public void update(Tile tile){
|
||||||
SorterEntity entity = tile.entity();
|
SorterEntity entity = tile.entity();
|
||||||
entity.items.set(entity.sortItem, 1);
|
entity.items.set(entity.sortItem, 1);
|
||||||
tryDump(tile, entity.sortItem);
|
tryDump(tile, entity.sortItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean acceptItem(Item item, Tile tile, Tile source) {
|
public boolean acceptItem(Item item, Tile tile, Tile source){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
liquidSource = new Block("liquidsource") {
|
liquidSource = new Block("liquidsource"){
|
||||||
{
|
{
|
||||||
update = true;
|
update = true;
|
||||||
solid = true;
|
solid = true;
|
||||||
@@ -76,7 +83,7 @@ public class DebugBlocks extends BlockList implements ContentList{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Tile tile) {
|
public void update(Tile tile){
|
||||||
LiquidSourceEntity entity = tile.entity();
|
LiquidSourceEntity entity = tile.entity();
|
||||||
|
|
||||||
tile.entity.liquids.add(entity.source, liquidCapacity);
|
tile.entity.liquids.add(entity.source, liquidCapacity);
|
||||||
@@ -84,7 +91,7 @@ public class DebugBlocks extends BlockList implements ContentList{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(Tile tile) {
|
public void draw(Tile tile){
|
||||||
super.draw(tile);
|
super.draw(tile);
|
||||||
|
|
||||||
LiquidSourceEntity entity = tile.entity();
|
LiquidSourceEntity entity = tile.entity();
|
||||||
@@ -95,7 +102,7 @@ public class DebugBlocks extends BlockList implements ContentList{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void buildTable(Tile tile, Table table) {
|
public void buildTable(Tile tile, Table table){
|
||||||
LiquidSourceEntity entity = tile.entity();
|
LiquidSourceEntity entity = tile.entity();
|
||||||
|
|
||||||
Array<Liquid> items = Liquid.all();
|
Array<Liquid> items = Liquid.all();
|
||||||
@@ -103,8 +110,8 @@ public class DebugBlocks extends BlockList implements ContentList{
|
|||||||
ButtonGroup<ImageButton> group = new ButtonGroup<>();
|
ButtonGroup<ImageButton> group = new ButtonGroup<>();
|
||||||
Table cont = new Table();
|
Table cont = new Table();
|
||||||
|
|
||||||
for (int i = 0; i < items.size; i++) {
|
for(int i = 0; i < items.size; i++){
|
||||||
if (i == 0) continue;
|
if(i == 0) continue;
|
||||||
final int f = i;
|
final int f = i;
|
||||||
ImageButton button = cont.addImageButton("white", "toggle", 24, () -> {
|
ImageButton button = cont.addImageButton("white", "toggle", 24, () -> {
|
||||||
CallBlocks.setLiquidSourceLiquid(null, tile, items.get(f));
|
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.getStyle().imageUpColor = items.get(i).color;
|
||||||
button.setChecked(entity.source.id == f);
|
button.setChecked(entity.source.id == f);
|
||||||
|
|
||||||
if (i % 4 == 3) {
|
if(i % 4 == 3){
|
||||||
cont.row();
|
cont.row();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -121,43 +128,37 @@ public class DebugBlocks extends BlockList implements ContentList{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TileEntity getEntity() {
|
public TileEntity getEntity(){
|
||||||
return new LiquidSourceEntity();
|
return new LiquidSourceEntity();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
itemVoid = new Block("itemvoid") {
|
itemVoid = new Block("itemvoid"){
|
||||||
{
|
{
|
||||||
update = solid = true;
|
update = solid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleItem(Item item, Tile tile, Tile source) {
|
public void handleItem(Item item, Tile tile, Tile source){
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean acceptItem(Item item, Tile tile, Tile source) {
|
public boolean acceptItem(Item item, Tile tile, Tile source){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Remote(targets = Loc.both, called = Loc.both, in = In.blocks, forward = true)
|
class LiquidSourceEntity extends TileEntity{
|
||||||
public static void setLiquidSourceLiquid(Player player, Tile tile, Liquid liquid){
|
|
||||||
LiquidSourceEntity entity = tile.entity();
|
|
||||||
entity.source = liquid;
|
|
||||||
}
|
|
||||||
|
|
||||||
class LiquidSourceEntity extends TileEntity {
|
|
||||||
public Liquid source = Liquids.water;
|
public Liquid source = Liquids.water;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(DataOutputStream stream) throws IOException {
|
public void write(DataOutputStream stream) throws IOException{
|
||||||
stream.writeByte(source.id);
|
stream.writeByte(source.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(DataInputStream stream) throws IOException {
|
public void read(DataInputStream stream) throws IOException{
|
||||||
source = Liquid.getByID(stream.readByte());
|
source = Liquid.getByID(stream.readByte());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.Door;
|
||||||
import io.anuke.mindustry.world.blocks.defense.PhaseWall;
|
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,
|
public static Block tungstenWall, tungstenWallLarge, carbideWall, carbideWallLarge, thoriumWall, thoriumWallLarge, door, doorLarge, deflectorwall, deflectorwalllarge,
|
||||||
phasewall, phasewalllarge;
|
phasewall, phasewalllarge;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
int wallHealthMultiplier = 4;
|
int wallHealthMultiplier = 4;
|
||||||
|
|
||||||
tungstenWall = new Wall("tungsten-wall") {{
|
tungstenWall = new Wall("tungsten-wall"){{
|
||||||
health = 80 * wallHealthMultiplier;
|
health = 80 * wallHealthMultiplier;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
tungstenWallLarge = new Wall("tungsten-wall-large") {{
|
tungstenWallLarge = new Wall("tungsten-wall-large"){{
|
||||||
health = 80 * 4 * wallHealthMultiplier;
|
health = 80 * 4 * wallHealthMultiplier;
|
||||||
size = 2;
|
size = 2;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
carbideWall = new Wall("carbide-wall") {{
|
carbideWall = new Wall("carbide-wall"){{
|
||||||
health = 110 * wallHealthMultiplier;
|
health = 110 * wallHealthMultiplier;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
carbideWallLarge = new Wall("carbide-wall-large") {{
|
carbideWallLarge = new Wall("carbide-wall-large"){{
|
||||||
health = 110 * wallHealthMultiplier*4;
|
health = 110 * wallHealthMultiplier * 4;
|
||||||
size = 2;
|
size = 2;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
thoriumWall = new Wall("thorium-wall") {{
|
thoriumWall = new Wall("thorium-wall"){{
|
||||||
health = 200 * wallHealthMultiplier;
|
health = 200 * wallHealthMultiplier;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
thoriumWallLarge = new Wall("thorium-wall-large") {{
|
thoriumWallLarge = new Wall("thorium-wall-large"){{
|
||||||
health = 200 * wallHealthMultiplier*4;
|
health = 200 * wallHealthMultiplier * 4;
|
||||||
size = 2;
|
size = 2;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
deflectorwall = new DeflectorWall("deflector-wall") {{
|
deflectorwall = new DeflectorWall("deflector-wall"){{
|
||||||
health = 150 * wallHealthMultiplier;
|
health = 150 * wallHealthMultiplier;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
deflectorwalllarge = new DeflectorWall("deflector-wall-large") {{
|
deflectorwalllarge = new DeflectorWall("deflector-wall-large"){{
|
||||||
health = 150 * 4 * wallHealthMultiplier;
|
health = 150 * 4 * wallHealthMultiplier;
|
||||||
size = 2;
|
size = 2;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
phasewall = new PhaseWall("phase-wall") {{
|
phasewall = new PhaseWall("phase-wall"){{
|
||||||
health = 150 * wallHealthMultiplier;
|
health = 150 * wallHealthMultiplier;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
phasewalllarge = new PhaseWall("phase-wall-large") {{
|
phasewalllarge = new PhaseWall("phase-wall-large"){{
|
||||||
health = 150 * 4 * wallHealthMultiplier;
|
health = 150 * 4 * wallHealthMultiplier;
|
||||||
size = 2;
|
size = 2;
|
||||||
regenSpeed = 0.5f;
|
regenSpeed = 0.5f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
door = new Door("door") {{
|
door = new Door("door"){{
|
||||||
health = 100 * wallHealthMultiplier;
|
health = 100 * wallHealthMultiplier;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
doorLarge = new Door("door-large") {{
|
doorLarge = new Door("door-large"){{
|
||||||
openfx = BlockFx.dooropenlarge;
|
openfx = BlockFx.dooropenlarge;
|
||||||
closefx = BlockFx.doorcloselarge;
|
closefx = BlockFx.doorcloselarge;
|
||||||
health = 100 * 4 * wallHealthMultiplier;
|
health = 100 * 4 * wallHealthMultiplier;
|
||||||
|
|||||||
@@ -9,29 +9,29 @@ public class DistributionBlocks extends BlockList implements ContentList{
|
|||||||
bridgeConveyor, phaseConveyor, sorter, splitter, overflowGate, massDriver;
|
bridgeConveyor, phaseConveyor, sorter, splitter, overflowGate, massDriver;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
|
|
||||||
conveyor = new Conveyor("conveyor") {{
|
conveyor = new Conveyor("conveyor"){{
|
||||||
health = 45;
|
health = 45;
|
||||||
speed = 0.03f;
|
speed = 0.03f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
titaniumconveyor = new Conveyor("titanium-conveyor") {{
|
titaniumconveyor = new Conveyor("titanium-conveyor"){{
|
||||||
health = 65;
|
health = 65;
|
||||||
speed = 0.07f;
|
speed = 0.07f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
junction = new Junction("junction") {{
|
junction = new Junction("junction"){{
|
||||||
speed = 26;
|
speed = 26;
|
||||||
capacity = 32;
|
capacity = 32;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
bridgeConveyor = new BufferedItemBridge("bridge-conveyor") {{
|
bridgeConveyor = new BufferedItemBridge("bridge-conveyor"){{
|
||||||
range = 3;
|
range = 3;
|
||||||
hasPower = false;
|
hasPower = false;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
phaseConveyor = new ItemBridge("phase-conveyor") {{
|
phaseConveyor = new ItemBridge("phase-conveyor"){{
|
||||||
range = 7;
|
range = 7;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ public class DistributionBlocks extends BlockList implements ContentList{
|
|||||||
|
|
||||||
splitter = new Splitter("splitter");
|
splitter = new Splitter("splitter");
|
||||||
|
|
||||||
distributor = new Splitter("distributor") {{
|
distributor = new Splitter("distributor"){{
|
||||||
size = 2;
|
size = 2;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -9,15 +9,15 @@ public class LiquidBlocks extends BlockList implements ContentList{
|
|||||||
public static Block mechanicalPump, rotaryPump, thermalPump, conduit, pulseConduit, liquidRouter, liquidtank, liquidJunction, bridgeConduit, phaseConduit;
|
public static Block mechanicalPump, rotaryPump, thermalPump, conduit, pulseConduit, liquidRouter, liquidtank, liquidJunction, bridgeConduit, phaseConduit;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
|
|
||||||
mechanicalPump = new Pump("mechanical-pump") {{
|
mechanicalPump = new Pump("mechanical-pump"){{
|
||||||
shadow = "shadow-round-1";
|
shadow = "shadow-round-1";
|
||||||
pumpAmount = 0.1f;
|
pumpAmount = 0.1f;
|
||||||
tier = 0;
|
tier = 0;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
rotaryPump = new Pump("rotary-pump") {{
|
rotaryPump = new Pump("rotary-pump"){{
|
||||||
shadow = "shadow-rounded-2";
|
shadow = "shadow-rounded-2";
|
||||||
pumpAmount = 0.25f;
|
pumpAmount = 0.25f;
|
||||||
consumes.power(0.015f);
|
consumes.power(0.015f);
|
||||||
@@ -27,7 +27,7 @@ public class LiquidBlocks extends BlockList implements ContentList{
|
|||||||
tier = 1;
|
tier = 1;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
thermalPump = new Pump("thermal-pump") {{
|
thermalPump = new Pump("thermal-pump"){{
|
||||||
pumpAmount = 0.3f;
|
pumpAmount = 0.3f;
|
||||||
consumes.power(0.05f);
|
consumes.power(0.05f);
|
||||||
liquidCapacity = 40f;
|
liquidCapacity = 40f;
|
||||||
@@ -35,21 +35,21 @@ public class LiquidBlocks extends BlockList implements ContentList{
|
|||||||
tier = 2;
|
tier = 2;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
conduit = new Conduit("conduit") {{
|
conduit = new Conduit("conduit"){{
|
||||||
health = 45;
|
health = 45;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
pulseConduit = new Conduit("pulse-conduit") {{
|
pulseConduit = new Conduit("pulse-conduit"){{
|
||||||
liquidCapacity = 16f;
|
liquidCapacity = 16f;
|
||||||
liquidFlowFactor = 4.9f;
|
liquidFlowFactor = 4.9f;
|
||||||
health = 90;
|
health = 90;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
liquidRouter = new LiquidRouter("liquid-router") {{
|
liquidRouter = new LiquidRouter("liquid-router"){{
|
||||||
liquidCapacity = 40f;
|
liquidCapacity = 40f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
liquidtank = new LiquidRouter("liquid-tank") {{
|
liquidtank = new LiquidRouter("liquid-tank"){{
|
||||||
size = 3;
|
size = 3;
|
||||||
liquidCapacity = 1500f;
|
liquidCapacity = 1500f;
|
||||||
health = 500;
|
health = 500;
|
||||||
@@ -57,12 +57,12 @@ public class LiquidBlocks extends BlockList implements ContentList{
|
|||||||
|
|
||||||
liquidJunction = new LiquidJunction("liquid-junction");
|
liquidJunction = new LiquidJunction("liquid-junction");
|
||||||
|
|
||||||
bridgeConduit = new LiquidExtendingBridge("bridge-conduit") {{
|
bridgeConduit = new LiquidExtendingBridge("bridge-conduit"){{
|
||||||
range = 3;
|
range = 3;
|
||||||
hasPower = false;
|
hasPower = false;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
phaseConduit = new LiquidBridge("phase-conduit") {{
|
phaseConduit = new LiquidBridge("phase-conduit"){{
|
||||||
range = 7;
|
range = 7;
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,18 @@ import io.anuke.mindustry.world.Block;
|
|||||||
import io.anuke.mindustry.world.blocks.Floor;
|
import io.anuke.mindustry.world.blocks.Floor;
|
||||||
import io.anuke.mindustry.world.blocks.OreBlock;
|
import io.anuke.mindustry.world.blocks.OreBlock;
|
||||||
|
|
||||||
public class OreBlocks extends BlockList {
|
public class OreBlocks extends BlockList{
|
||||||
private static final ObjectMap<Item, ObjectMap<Block, Block>> oreBlockMap = new ObjectMap<>();
|
private static final ObjectMap<Item, ObjectMap<Block, Block>> 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
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
Item[] ores = {Items.tungsten, Items.lead, Items.coal, Items.titanium, Items.thorium};
|
Item[] ores = {Items.tungsten, Items.lead, Items.coal, Items.titanium, Items.thorium};
|
||||||
|
|
||||||
for(Item item : ores){
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,19 +7,19 @@ import io.anuke.mindustry.world.Block;
|
|||||||
import io.anuke.mindustry.world.blocks.distribution.WarpGate;
|
import io.anuke.mindustry.world.blocks.distribution.WarpGate;
|
||||||
import io.anuke.mindustry.world.blocks.power.*;
|
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,
|
public static Block combustionGenerator, thermalGenerator, turbineGenerator, rtgGenerator, solarPanel, largeSolarPanel,
|
||||||
nuclearReactor, fusionReactor, battery, batteryLarge, powerNode, powerNodeLarge, warpGate;
|
nuclearReactor, fusionReactor, battery, batteryLarge, powerNode, powerNodeLarge, warpGate;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
combustionGenerator = new BurnerGenerator("combustion-generator") {{
|
combustionGenerator = new BurnerGenerator("combustion-generator"){{
|
||||||
powerOutput = 0.09f;
|
powerOutput = 0.09f;
|
||||||
powerCapacity = 40f;
|
powerCapacity = 40f;
|
||||||
itemDuration = 40f;
|
itemDuration = 40f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
thermalGenerator = new LiquidHeatGenerator("thermal-generator") {{
|
thermalGenerator = new LiquidHeatGenerator("thermal-generator"){{
|
||||||
maxLiquidGenerate = 0.5f;
|
maxLiquidGenerate = 0.5f;
|
||||||
powerPerLiquid = 0.08f;
|
powerPerLiquid = 0.08f;
|
||||||
powerCapacity = 40f;
|
powerCapacity = 40f;
|
||||||
@@ -28,7 +28,7 @@ public class PowerBlocks extends BlockList implements ContentList {
|
|||||||
size = 2;
|
size = 2;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
turbineGenerator = new TurbineGenerator("turbine-generator") {{
|
turbineGenerator = new TurbineGenerator("turbine-generator"){{
|
||||||
powerOutput = 0.28f;
|
powerOutput = 0.28f;
|
||||||
powerCapacity = 40f;
|
powerCapacity = 40f;
|
||||||
itemDuration = 30f;
|
itemDuration = 30f;
|
||||||
@@ -37,46 +37,46 @@ public class PowerBlocks extends BlockList implements ContentList {
|
|||||||
size = 2;
|
size = 2;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
rtgGenerator = new DecayGenerator("rtg-generator") {{
|
rtgGenerator = new DecayGenerator("rtg-generator"){{
|
||||||
powerCapacity = 40f;
|
powerCapacity = 40f;
|
||||||
powerOutput = 0.02f;
|
powerOutput = 0.02f;
|
||||||
itemDuration = 500f;
|
itemDuration = 500f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
solarPanel = new SolarGenerator("solar-panel") {{
|
solarPanel = new SolarGenerator("solar-panel"){{
|
||||||
generation = 0.0045f;
|
generation = 0.0045f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
largeSolarPanel = new SolarGenerator("solar-panel-large") {{
|
largeSolarPanel = new SolarGenerator("solar-panel-large"){{
|
||||||
size = 3;
|
size = 3;
|
||||||
generation = 0.055f;
|
generation = 0.055f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
nuclearReactor = new NuclearReactor("nuclear-reactor") {{
|
nuclearReactor = new NuclearReactor("nuclear-reactor"){{
|
||||||
size = 3;
|
size = 3;
|
||||||
health = 700;
|
health = 700;
|
||||||
powerMultiplier = 0.8f;
|
powerMultiplier = 0.8f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
fusionReactor = new FusionReactor("fusion-reactor") {{
|
fusionReactor = new FusionReactor("fusion-reactor"){{
|
||||||
size = 4;
|
size = 4;
|
||||||
health = 600;
|
health = 600;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
battery = new PowerDistributor("battery") {{
|
battery = new PowerDistributor("battery"){{
|
||||||
powerCapacity = 320f;
|
powerCapacity = 320f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
batteryLarge = new PowerDistributor("battery-large") {{
|
batteryLarge = new PowerDistributor("battery-large"){{
|
||||||
size = 3;
|
size = 3;
|
||||||
powerCapacity = 2000f;
|
powerCapacity = 2000f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
powerNode = new PowerNode("power-node") {{
|
powerNode = new PowerNode("power-node"){{
|
||||||
shadow = "shadow-round-1";
|
shadow = "shadow-round-1";
|
||||||
}};
|
}};
|
||||||
|
|
||||||
powerNodeLarge = new PowerNode("power-node-large") {{
|
powerNodeLarge = new PowerNode("power-node-large"){{
|
||||||
size = 2;
|
size = 2;
|
||||||
powerSpeed = 1f;
|
powerSpeed = 1f;
|
||||||
maxNodes = 5;
|
maxNodes = 5;
|
||||||
|
|||||||
@@ -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.Fracker;
|
||||||
import io.anuke.mindustry.world.blocks.production.SolidPump;
|
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;
|
public static Block tungstenDrill, carbideDrill, laserdrill, blastdrill, plasmadrill, waterextractor, oilextractor, cultivator;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
tungstenDrill = new Drill("tungsten-drill") {{
|
tungstenDrill = new Drill("tungsten-drill"){{
|
||||||
tier = 2;
|
tier = 2;
|
||||||
drillTime = 340;
|
drillTime = 340;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
carbideDrill = new Drill("carbide-drill") {{
|
carbideDrill = new Drill("carbide-drill"){{
|
||||||
tier = 3;
|
tier = 3;
|
||||||
drillTime = 280;
|
drillTime = 280;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
laserdrill = new Drill("laser-drill") {{
|
laserdrill = new Drill("laser-drill"){{
|
||||||
drillTime = 180;
|
drillTime = 180;
|
||||||
size = 2;
|
size = 2;
|
||||||
hasPower = true;
|
hasPower = true;
|
||||||
@@ -37,7 +37,7 @@ public class ProductionBlocks extends BlockList implements ContentList {
|
|||||||
consumes.power(0.2f);
|
consumes.power(0.2f);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
blastdrill = new Drill("blast-drill") {{
|
blastdrill = new Drill("blast-drill"){{
|
||||||
drillTime = 120;
|
drillTime = 120;
|
||||||
size = 3;
|
size = 3;
|
||||||
drawRim = true;
|
drawRim = true;
|
||||||
@@ -52,7 +52,7 @@ public class ProductionBlocks extends BlockList implements ContentList {
|
|||||||
consumes.power(0.5f);
|
consumes.power(0.5f);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
plasmadrill = new Drill("plasma-drill") {{
|
plasmadrill = new Drill("plasma-drill"){{
|
||||||
heatColor = Color.valueOf("ff461b");
|
heatColor = Color.valueOf("ff461b");
|
||||||
drillTime = 90;
|
drillTime = 90;
|
||||||
size = 4;
|
size = 4;
|
||||||
@@ -69,7 +69,7 @@ public class ProductionBlocks extends BlockList implements ContentList {
|
|||||||
consumes.power(0.7f);
|
consumes.power(0.7f);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
waterextractor = new SolidPump("water-extractor") {{
|
waterextractor = new SolidPump("water-extractor"){{
|
||||||
result = Liquids.water;
|
result = Liquids.water;
|
||||||
pumpAmount = 0.1f;
|
pumpAmount = 0.1f;
|
||||||
size = 2;
|
size = 2;
|
||||||
@@ -79,7 +79,7 @@ public class ProductionBlocks extends BlockList implements ContentList {
|
|||||||
consumes.power(0.2f);
|
consumes.power(0.2f);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
oilextractor = new Fracker("oil-extractor") {{
|
oilextractor = new Fracker("oil-extractor"){{
|
||||||
result = Liquids.oil;
|
result = Liquids.oil;
|
||||||
updateEffect = BlockFx.pulverize;
|
updateEffect = BlockFx.pulverize;
|
||||||
liquidCapacity = 50f;
|
liquidCapacity = 50f;
|
||||||
@@ -93,7 +93,7 @@ public class ProductionBlocks extends BlockList implements ContentList {
|
|||||||
consumes.liquid(Liquids.water, 0.3f);
|
consumes.liquid(Liquids.water, 0.3f);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
cultivator = new Cultivator("cultivator") {{
|
cultivator = new Cultivator("cultivator"){{
|
||||||
result = Items.biomatter;
|
result = Items.biomatter;
|
||||||
drillTime = 260;
|
drillTime = 260;
|
||||||
size = 2;
|
size = 2;
|
||||||
|
|||||||
@@ -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.Unloader;
|
||||||
import io.anuke.mindustry.world.blocks.storage.Vault;
|
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;
|
public static Block core, vault, unloader, sortedunloader;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
core = new CoreBlock("core") {{
|
core = new CoreBlock("core"){{
|
||||||
health = 800;
|
health = 800;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
vault = new Vault("vault") {{
|
vault = new Vault("vault"){{
|
||||||
size = 3;
|
size = 3;
|
||||||
health = 600;
|
health = 600;
|
||||||
itemCapacity = 2000;
|
itemCapacity = 2000;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
unloader = new Unloader("unloader") {{
|
unloader = new Unloader("unloader"){{
|
||||||
speed = 5;
|
speed = 5;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
sortedunloader = new SortedUnloader("sortedunloader") {{
|
sortedunloader = new SortedUnloader("sortedunloader"){{
|
||||||
speed = 5;
|
speed = 5;
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,12 +12,13 @@ import io.anuke.ucore.util.Angles;
|
|||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
import io.anuke.ucore.util.Strings;
|
import io.anuke.ucore.util.Strings;
|
||||||
|
|
||||||
public class TurretBlocks extends BlockList implements ContentList {
|
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 static Block duo, /*scatter,*/
|
||||||
|
scorch, hail, wave, lancer, arc, swarmer, salvo, fuse, ripple, cyclone, spectre, meltdown;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
duo = new DoubleTurret("duo") {{
|
duo = new DoubleTurret("duo"){{
|
||||||
ammoTypes = new AmmoType[]{AmmoTypes.bulletTungsten, AmmoTypes.bulletLead, AmmoTypes.bulletCarbide, AmmoTypes.bulletPyratite, AmmoTypes.bulletSilicon};
|
ammoTypes = new AmmoType[]{AmmoTypes.bulletTungsten, AmmoTypes.bulletLead, AmmoTypes.bulletCarbide, AmmoTypes.bulletPyratite, AmmoTypes.bulletSilicon};
|
||||||
reload = 25f;
|
reload = 25f;
|
||||||
restitution = 0.03f;
|
restitution = 0.03f;
|
||||||
@@ -41,7 +42,7 @@ public class TurretBlocks extends BlockList implements ContentList {
|
|||||||
ammoUseEffect = ShootFx.shellEjectSmall;
|
ammoUseEffect = ShootFx.shellEjectSmall;
|
||||||
}};*/
|
}};*/
|
||||||
|
|
||||||
hail = new ArtilleryTurret("hail") {{
|
hail = new ArtilleryTurret("hail"){{
|
||||||
ammoTypes = new AmmoType[]{AmmoTypes.artilleryCarbide, AmmoTypes.artilleryHoming, AmmoTypes.artilleryIncindiary};
|
ammoTypes = new AmmoType[]{AmmoTypes.artilleryCarbide, AmmoTypes.artilleryHoming, AmmoTypes.artilleryIncindiary};
|
||||||
reload = 100f;
|
reload = 100f;
|
||||||
recoil = 2f;
|
recoil = 2f;
|
||||||
@@ -50,7 +51,7 @@ public class TurretBlocks extends BlockList implements ContentList {
|
|||||||
health = 120;
|
health = 120;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
scorch = new LiquidTurret("scorch") {{
|
scorch = new LiquidTurret("scorch"){{
|
||||||
ammoTypes = new AmmoType[]{AmmoTypes.basicFlame};
|
ammoTypes = new AmmoType[]{AmmoTypes.basicFlame};
|
||||||
recoil = 0f;
|
recoil = 0f;
|
||||||
reload = 4f;
|
reload = 4f;
|
||||||
@@ -61,7 +62,7 @@ public class TurretBlocks extends BlockList implements ContentList {
|
|||||||
drawer = (tile, entity) -> Draw.rect(entity.target != null ? name + "-shoot" : name, tile.drawx() + tr2.x, tile.drawy() + tr2.y, entity.rotation - 90);
|
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") {{
|
wave = new LiquidTurret("wave"){{
|
||||||
ammoTypes = new AmmoType[]{AmmoTypes.water, AmmoTypes.lava, AmmoTypes.cryofluid, AmmoTypes.oil};
|
ammoTypes = new AmmoType[]{AmmoTypes.water, AmmoTypes.lava, AmmoTypes.cryofluid, AmmoTypes.oil};
|
||||||
size = 2;
|
size = 2;
|
||||||
recoil = 0f;
|
recoil = 0f;
|
||||||
@@ -82,7 +83,7 @@ public class TurretBlocks extends BlockList implements ContentList {
|
|||||||
};
|
};
|
||||||
}};
|
}};
|
||||||
|
|
||||||
lancer = new LaserTurret("lancer") {{
|
lancer = new LaserTurret("lancer"){{
|
||||||
range = 90f;
|
range = 90f;
|
||||||
chargeTime = 60f;
|
chargeTime = 60f;
|
||||||
chargeMaxDelay = 30f;
|
chargeMaxDelay = 30f;
|
||||||
@@ -103,7 +104,7 @@ public class TurretBlocks extends BlockList implements ContentList {
|
|||||||
health = 320;
|
health = 320;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
arc = new LaserTurret("arc") {{
|
arc = new LaserTurret("arc"){{
|
||||||
shootType = AmmoTypes.lightning;
|
shootType = AmmoTypes.lightning;
|
||||||
reload = 100f;
|
reload = 100f;
|
||||||
chargeTime = 70f;
|
chargeTime = 70f;
|
||||||
@@ -118,7 +119,7 @@ public class TurretBlocks extends BlockList implements ContentList {
|
|||||||
size = 2;
|
size = 2;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
swarmer = new BurstTurret("swarmer") {{
|
swarmer = new BurstTurret("swarmer"){{
|
||||||
ammoTypes = new AmmoType[]{AmmoTypes.missileExplosive, AmmoTypes.missileIncindiary/*, AmmoTypes.missileSurge*/};
|
ammoTypes = new AmmoType[]{AmmoTypes.missileExplosive, AmmoTypes.missileIncindiary/*, AmmoTypes.missileSurge*/};
|
||||||
reload = 60f;
|
reload = 60f;
|
||||||
shots = 4;
|
shots = 4;
|
||||||
@@ -130,7 +131,7 @@ public class TurretBlocks extends BlockList implements ContentList {
|
|||||||
health = 380;
|
health = 380;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
salvo = new BurstTurret("salvo") {{
|
salvo = new BurstTurret("salvo"){{
|
||||||
size = 2;
|
size = 2;
|
||||||
range = 120f;
|
range = 120f;
|
||||||
ammoTypes = new AmmoType[]{AmmoTypes.bulletTungsten, AmmoTypes.bulletCarbide, AmmoTypes.bulletPyratite, AmmoTypes.bulletThorium, AmmoTypes.bulletSilicon};
|
ammoTypes = new AmmoType[]{AmmoTypes.bulletTungsten, AmmoTypes.bulletCarbide, AmmoTypes.bulletPyratite, AmmoTypes.bulletThorium, AmmoTypes.bulletSilicon};
|
||||||
@@ -149,7 +150,7 @@ public class TurretBlocks extends BlockList implements ContentList {
|
|||||||
float offsetx = (int) (Mathf.abscurve(Mathf.curve(entity.reload / reload, 0.3f, 0.2f)) * 3f);
|
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);
|
float offsety = -(int) (Mathf.abscurve(Mathf.curve(entity.reload / reload, 0.3f, 0.2f)) * 2f);
|
||||||
|
|
||||||
for (int i : Mathf.signs) {
|
for(int i : Mathf.signs){
|
||||||
float rot = entity.rotation + 90 * i;
|
float rot = entity.rotation + 90 * i;
|
||||||
Draw.rect(name + "-panel-" + Strings.dir(i),
|
Draw.rect(name + "-panel-" + Strings.dir(i),
|
||||||
tile.drawx() + tr2.x + Angles.trnsx(rot, offsetx, offsety),
|
tile.drawx() + tr2.x + Angles.trnsx(rot, offsetx, offsety),
|
||||||
@@ -160,7 +161,7 @@ public class TurretBlocks extends BlockList implements ContentList {
|
|||||||
health = 360;
|
health = 360;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
ripple = new ArtilleryTurret("ripple") {{
|
ripple = new ArtilleryTurret("ripple"){{
|
||||||
ammoTypes = new AmmoType[]{AmmoTypes.artilleryCarbide, AmmoTypes.artilleryHoming, AmmoTypes.artilleryIncindiary, AmmoTypes.artilleryExplosive, AmmoTypes.artilleryPlastic};
|
ammoTypes = new AmmoType[]{AmmoTypes.artilleryCarbide, AmmoTypes.artilleryHoming, AmmoTypes.artilleryIncindiary, AmmoTypes.artilleryExplosive, AmmoTypes.artilleryPlastic};
|
||||||
size = 3;
|
size = 3;
|
||||||
shots = 4;
|
shots = 4;
|
||||||
@@ -178,18 +179,18 @@ public class TurretBlocks extends BlockList implements ContentList {
|
|||||||
health = 550;
|
health = 550;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
cyclone = new ItemTurret("cyclone") {{
|
cyclone = new ItemTurret("cyclone"){{
|
||||||
ammoTypes = new AmmoType[]{AmmoTypes.flakLead, AmmoTypes.flakExplosive, AmmoTypes.flakPlastic, AmmoTypes.flakSurge};
|
ammoTypes = new AmmoType[]{AmmoTypes.flakLead, AmmoTypes.flakExplosive, AmmoTypes.flakPlastic, AmmoTypes.flakSurge};
|
||||||
size = 3;
|
size = 3;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
fuse = new ItemTurret("fuse") {{
|
fuse = new ItemTurret("fuse"){{
|
||||||
//TODO make it use power
|
//TODO make it use power
|
||||||
ammoTypes = new AmmoType[]{AmmoTypes.fuseShotgun};
|
ammoTypes = new AmmoType[]{AmmoTypes.fuseShotgun};
|
||||||
size = 3;
|
size = 3;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
spectre = new ItemTurret("spectre") {{
|
spectre = new ItemTurret("spectre"){{
|
||||||
ammoTypes = new AmmoType[]{AmmoTypes.bulletTungsten, AmmoTypes.bulletLead, AmmoTypes.bulletCarbide, AmmoTypes.bulletPyratite, AmmoTypes.bulletThorium, AmmoTypes.bulletSilicon};
|
ammoTypes = new AmmoType[]{AmmoTypes.bulletTungsten, AmmoTypes.bulletLead, AmmoTypes.bulletCarbide, AmmoTypes.bulletPyratite, AmmoTypes.bulletThorium, AmmoTypes.bulletSilicon};
|
||||||
reload = 25f;
|
reload = 25f;
|
||||||
restitution = 0.03f;
|
restitution = 0.03f;
|
||||||
@@ -197,7 +198,7 @@ public class TurretBlocks extends BlockList implements ContentList {
|
|||||||
size = 4;
|
size = 4;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
meltdown = new PowerTurret("meltdown") {{
|
meltdown = new PowerTurret("meltdown"){{
|
||||||
shootType = AmmoTypes.meltdownLaser;
|
shootType = AmmoTypes.meltdownLaser;
|
||||||
size = 4;
|
size = 4;
|
||||||
}};
|
}};
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ import io.anuke.mindustry.type.ItemStack;
|
|||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.Block;
|
||||||
import io.anuke.mindustry.world.blocks.units.*;
|
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;
|
public static Block resupplyPoint, repairPoint, droneFactory, fabricatorFactory, dropPoint, reconstructor, overdriveProjector, shieldProjector;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
droneFactory = new UnitFactory("drone-factory") {{
|
droneFactory = new UnitFactory("drone-factory"){{
|
||||||
type = UnitTypes.drone;
|
type = UnitTypes.drone;
|
||||||
produceTime = 800;
|
produceTime = 800;
|
||||||
size = 2;
|
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)});
|
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;
|
type = UnitTypes.fabricator;
|
||||||
produceTime = 1600;
|
produceTime = 1600;
|
||||||
size = 2;
|
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)});
|
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";
|
shadow = "shadow-round-1";
|
||||||
itemCapacity = 30;
|
itemCapacity = 30;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
dropPoint = new DropPoint("drop-point") {{
|
dropPoint = new DropPoint("drop-point"){{
|
||||||
shadow = "shadow-round-1";
|
shadow = "shadow-round-1";
|
||||||
itemCapacity = 40;
|
itemCapacity = 40;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
repairPoint = new RepairPoint("repair-point") {{
|
repairPoint = new RepairPoint("repair-point"){{
|
||||||
shadow = "shadow-round-1";
|
shadow = "shadow-round-1";
|
||||||
repairSpeed = 0.1f;
|
repairSpeed = 0.1f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
reconstructor = new Reconstructor("reconstructor") {{
|
reconstructor = new Reconstructor("reconstructor"){{
|
||||||
size = 2;
|
size = 2;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
overdriveProjector = new OverdriveProjector("overdrive-projector") {{
|
overdriveProjector = new OverdriveProjector("overdrive-projector"){{
|
||||||
size = 2;
|
size = 2;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
shieldProjector = new ShieldProjector("shieldprojector") {{
|
shieldProjector = new ShieldProjector("shieldprojector"){{
|
||||||
size = 2;
|
size = 2;
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import io.anuke.mindustry.content.Mechs;
|
|||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.Block;
|
||||||
import io.anuke.mindustry.world.blocks.units.MechFactory;
|
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;
|
public static Block deltaFactory, tauFactory, omegaFactory, dartFactory, javelinFactory, tridentFactory, halberdFactory;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
deltaFactory = new MechFactory("delta-mech-factory"){{
|
deltaFactory = new MechFactory("delta-mech-factory"){{
|
||||||
mech = Mechs.delta;
|
mech = Mechs.delta;
|
||||||
size = 2;
|
size = 2;
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ public class ArtilleryBullets extends BulletList implements ContentList{
|
|||||||
public static BulletType carbide, plastic, plasticFrag, homing, incindiary, explosive, surge;
|
public static BulletType carbide, plastic, plasticFrag, homing, incindiary, explosive, surge;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
|
|
||||||
carbide = new ArtilleryBulletType(3f, 0, "shell") {
|
carbide = new ArtilleryBulletType(3f, 0, "shell"){
|
||||||
{
|
{
|
||||||
hiteffect = BulletFx.flakExplosion;
|
hiteffect = BulletFx.flakExplosion;
|
||||||
knockback = 0.8f;
|
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;
|
bulletWidth = 10f;
|
||||||
bulletHeight = 12f;
|
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;
|
hiteffect = BulletFx.plasticExplosion;
|
||||||
knockback = 1f;
|
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;
|
hiteffect = BulletFx.flakExplosion;
|
||||||
knockback = 0.8f;
|
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;
|
hiteffect = BulletFx.blastExplosion;
|
||||||
knockback = 0.8f;
|
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;
|
hiteffect = BulletFx.blastExplosion;
|
||||||
knockback = 0.8f;
|
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
|
//TODO
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ import io.anuke.mindustry.entities.bullet.BulletType;
|
|||||||
import io.anuke.mindustry.game.Content;
|
import io.anuke.mindustry.game.Content;
|
||||||
import io.anuke.mindustry.type.ContentList;
|
import io.anuke.mindustry.type.ContentList;
|
||||||
|
|
||||||
public abstract class BulletList implements ContentList {
|
public abstract class BulletList implements ContentList{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Array<? extends Content> getAll() {
|
public Array<? extends Content> getAll(){
|
||||||
return BulletType.all();
|
return BulletType.all();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,34 +4,34 @@ import io.anuke.mindustry.entities.bullet.BasicBulletType;
|
|||||||
import io.anuke.mindustry.entities.bullet.BulletType;
|
import io.anuke.mindustry.entities.bullet.BulletType;
|
||||||
import io.anuke.mindustry.type.ContentList;
|
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;
|
public static BulletType lead, plastic, explosive, surge;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
|
|
||||||
lead = new BasicBulletType(3f, 5, "bullet") {
|
lead = new BasicBulletType(3f, 5, "bullet"){
|
||||||
{
|
{
|
||||||
bulletWidth = 7f;
|
bulletWidth = 7f;
|
||||||
bulletHeight = 9f;
|
bulletHeight = 9f;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
plastic = new BasicBulletType(3f, 5, "bullet") {
|
plastic = new BasicBulletType(3f, 5, "bullet"){
|
||||||
{
|
{
|
||||||
bulletWidth = 7f;
|
bulletWidth = 7f;
|
||||||
bulletHeight = 9f;
|
bulletHeight = 9f;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
explosive = new BasicBulletType(3f, 5, "bullet") {
|
explosive = new BasicBulletType(3f, 5, "bullet"){
|
||||||
{
|
{
|
||||||
bulletWidth = 7f;
|
bulletWidth = 7f;
|
||||||
bulletHeight = 9f;
|
bulletHeight = 9f;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
surge = new BasicBulletType(3f, 5, "bullet") {
|
surge = new BasicBulletType(3f, 5, "bullet"){
|
||||||
{
|
{
|
||||||
bulletWidth = 7f;
|
bulletWidth = 7f;
|
||||||
bulletHeight = 9f;
|
bulletHeight = 9f;
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ import io.anuke.mindustry.entities.bullet.MissileBulletType;
|
|||||||
import io.anuke.mindustry.graphics.Palette;
|
import io.anuke.mindustry.graphics.Palette;
|
||||||
import io.anuke.mindustry.type.ContentList;
|
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;
|
public static BulletType explosive, incindiary, surge, javelin;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
|
|
||||||
explosive = new MissileBulletType(1.8f, 10, "missile") {
|
explosive = new MissileBulletType(1.8f, 10, "missile"){
|
||||||
{
|
{
|
||||||
bulletWidth = 8f;
|
bulletWidth = 8f;
|
||||||
bulletHeight = 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;
|
frontColor = Palette.lightishOrange;
|
||||||
backColor = Palette.lightOrange;
|
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;
|
bulletWidth = 7f;
|
||||||
bulletHeight = 9f;
|
bulletHeight = 9f;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
javelin = new MissileBulletType(2.5f, 10, "missile") {
|
javelin = new MissileBulletType(2.5f, 10, "missile"){
|
||||||
{
|
{
|
||||||
bulletWidth = 8f;
|
bulletWidth = 8f;
|
||||||
bulletHeight = 8f;
|
bulletHeight = 8f;
|
||||||
|
|||||||
@@ -5,27 +5,27 @@ import io.anuke.mindustry.entities.bullet.BulletType;
|
|||||||
import io.anuke.mindustry.graphics.Palette;
|
import io.anuke.mindustry.graphics.Palette;
|
||||||
import io.anuke.mindustry.type.ContentList;
|
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;
|
public static BulletType tungsten, lead, carbide, thorium, homing, tracer;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
|
|
||||||
tungsten = new BasicBulletType(3.2f, 10, "bullet") {
|
tungsten = new BasicBulletType(3.2f, 10, "bullet"){
|
||||||
{
|
{
|
||||||
bulletWidth = 9f;
|
bulletWidth = 9f;
|
||||||
bulletHeight = 11f;
|
bulletHeight = 11f;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
lead = new BasicBulletType(2.5f, 5, "bullet") {
|
lead = new BasicBulletType(2.5f, 5, "bullet"){
|
||||||
{
|
{
|
||||||
bulletWidth = 7f;
|
bulletWidth = 7f;
|
||||||
bulletHeight = 9f;
|
bulletHeight = 9f;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
carbide = new BasicBulletType(3.5f, 18, "bullet") {
|
carbide = new BasicBulletType(3.5f, 18, "bullet"){
|
||||||
{
|
{
|
||||||
bulletWidth = 9f;
|
bulletWidth = 9f;
|
||||||
bulletHeight = 12f;
|
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;
|
bulletWidth = 10f;
|
||||||
bulletHeight = 13f;
|
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;
|
bulletWidth = 7f;
|
||||||
bulletHeight = 9f;
|
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;
|
bulletWidth = 10f;
|
||||||
bulletHeight = 12f;
|
bulletHeight = 12f;
|
||||||
|
|||||||
@@ -29,13 +29,13 @@ import io.anuke.ucore.util.Mathf;
|
|||||||
|
|
||||||
import static io.anuke.mindustry.Vars.world;
|
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;
|
public static BulletType fireball, basicFlame, lancerLaser, fuseShot, waterShot, cryoShot, lavaShot, oilShot, lightning, driverBolt;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
|
|
||||||
fireball = new BulletType(1f, 4) {
|
fireball = new BulletType(1f, 4){
|
||||||
{
|
{
|
||||||
pierce = true;
|
pierce = true;
|
||||||
hitTiles = false;
|
hitTiles = false;
|
||||||
@@ -45,12 +45,12 @@ public class TurretBullets extends BulletList implements ContentList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(Bullet b) {
|
public void init(Bullet b){
|
||||||
b.getVelocity().setLength(0.6f + Mathf.random(2f));
|
b.getVelocity().setLength(0.6f + Mathf.random(2f));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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
|
//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());
|
Draw.color(Palette.lightFlame, Palette.darkFlame, Color.GRAY, b.fin());
|
||||||
Fill.circle(b.x, b.y, 3f * b.fout());
|
Fill.circle(b.x, b.y, 3f * b.fout());
|
||||||
@@ -58,25 +58,25 @@ public class TurretBullets extends BulletList implements ContentList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Bullet b) {
|
public void update(Bullet b){
|
||||||
if (Mathf.chance(0.04 * Timers.delta())) {
|
if(Mathf.chance(0.04 * Timers.delta())){
|
||||||
Tile tile = world.tileWorld(b.x, b.y);
|
Tile tile = world.tileWorld(b.x, b.y);
|
||||||
if (tile != null) {
|
if(tile != null){
|
||||||
Fire.create(tile);
|
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);
|
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);
|
Effects.effect(EnvironmentFx.ballfire, b.x, b.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
basicFlame = new BulletType(2f, 5) {
|
basicFlame = new BulletType(2f, 5){
|
||||||
{
|
{
|
||||||
hitsize = 7f;
|
hitsize = 7f;
|
||||||
lifetime = 30f;
|
lifetime = 30f;
|
||||||
@@ -88,11 +88,11 @@ public class TurretBullets extends BulletList implements ContentList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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};
|
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[] tscales = {1f, 0.7f, 0.5f, 0.2f};
|
||||||
float[] lenscales = {1f, 1.1f, 1.13f, 1.14f};
|
float[] lenscales = {1f, 1.1f, 1.13f, 1.14f};
|
||||||
@@ -107,19 +107,19 @@ public class TurretBullets extends BulletList implements ContentList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(Bullet b) {
|
public void init(Bullet b){
|
||||||
Damage.collideLine(b, b.getTeam(), hiteffect, b.x, b.y, b.angle(), length);
|
Damage.collideLine(b, b.getTeam(), hiteffect, b.x, b.y, b.angle(), length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(Bullet b) {
|
public void draw(Bullet b){
|
||||||
float f = Mathf.curve(b.fin(), 0f, 0.2f);
|
float f = Mathf.curve(b.fin(), 0f, 0.2f);
|
||||||
float baseLen = length * f;
|
float baseLen = length * f;
|
||||||
|
|
||||||
Lines.lineAngle(b.x, b.y, b.angle(), baseLen);
|
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]);
|
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.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]);
|
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
|
//TODO
|
||||||
};
|
};
|
||||||
|
|
||||||
waterShot = new LiquidBulletType(Liquids.water) {
|
waterShot = new LiquidBulletType(Liquids.water){
|
||||||
{
|
{
|
||||||
status = StatusEffects.wet;
|
status = StatusEffects.wet;
|
||||||
statusIntensity = 0.5f;
|
statusIntensity = 0.5f;
|
||||||
knockback = 0.65f;
|
knockback = 0.65f;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
cryoShot = new LiquidBulletType(Liquids.cryofluid) {
|
cryoShot = new LiquidBulletType(Liquids.cryofluid){
|
||||||
{
|
{
|
||||||
status = StatusEffects.freezing;
|
status = StatusEffects.freezing;
|
||||||
statusIntensity = 0.5f;
|
statusIntensity = 0.5f;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
lavaShot = new LiquidBulletType(Liquids.lava) {
|
lavaShot = new LiquidBulletType(Liquids.lava){
|
||||||
{
|
{
|
||||||
damage = 4;
|
damage = 4;
|
||||||
speed = 1.9f;
|
speed = 1.9f;
|
||||||
@@ -154,7 +154,7 @@ public class TurretBullets extends BulletList implements ContentList {
|
|||||||
statusIntensity = 0.5f;
|
statusIntensity = 0.5f;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
oilShot = new LiquidBulletType(Liquids.oil) {
|
oilShot = new LiquidBulletType(Liquids.oil){
|
||||||
{
|
{
|
||||||
speed = 2f;
|
speed = 2f;
|
||||||
drag = 0.03f;
|
drag = 0.03f;
|
||||||
@@ -162,7 +162,7 @@ public class TurretBullets extends BulletList implements ContentList {
|
|||||||
statusIntensity = 0.5f;
|
statusIntensity = 0.5f;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
lightning = new BulletType(0.001f, 10) {
|
lightning = new BulletType(0.001f, 10){
|
||||||
{
|
{
|
||||||
lifetime = 1;
|
lifetime = 1;
|
||||||
despawneffect = Fx.none;
|
despawneffect = Fx.none;
|
||||||
@@ -170,16 +170,16 @@ public class TurretBullets extends BulletList implements ContentList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(Bullet b) {
|
public void draw(Bullet b){
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
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;
|
collidesTiles = false;
|
||||||
lifetime = 200f;
|
lifetime = 200f;
|
||||||
@@ -189,7 +189,7 @@ public class TurretBullets extends BulletList implements ContentList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(Bullet b) {
|
public void draw(Bullet b){
|
||||||
Draw.color(Color.LIGHT_GRAY);
|
Draw.color(Color.LIGHT_GRAY);
|
||||||
Fill.square(b.x, b.y, 3f, b.angle());
|
Fill.square(b.x, b.y, 3f, b.angle());
|
||||||
|
|
||||||
@@ -199,7 +199,7 @@ public class TurretBullets extends BulletList implements ContentList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Bullet b) {
|
public void update(Bullet b){
|
||||||
//data MUST be an instance of DriverBulletData
|
//data MUST be an instance of DriverBulletData
|
||||||
if(!(b.getData() instanceof DriverBulletData)){
|
if(!(b.getData() instanceof DriverBulletData)){
|
||||||
hit(b);
|
hit(b);
|
||||||
@@ -208,7 +208,7 @@ public class TurretBullets extends BulletList implements ContentList {
|
|||||||
|
|
||||||
float hitDst = 7f;
|
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 the target is dead, just keep flying until the bullet explodes
|
||||||
if(data.to.isDead()){
|
if(data.to.isDead()){
|
||||||
@@ -245,15 +245,15 @@ public class TurretBullets extends BulletList implements ContentList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void despawned(Bullet b) {
|
public void despawned(Bullet b){
|
||||||
super.despawned(b);
|
super.despawned(b);
|
||||||
|
|
||||||
if(!(b.getData() instanceof DriverBulletData)) return;
|
if(!(b.getData() instanceof DriverBulletData)) return;
|
||||||
|
|
||||||
DriverBulletData data = (DriverBulletData)b.getData();
|
DriverBulletData data = (DriverBulletData) b.getData();
|
||||||
data.to.isRecieving = false;
|
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]);
|
int amountDropped = Mathf.random(0, data.items[i]);
|
||||||
if(amountDropped > 0){
|
if(amountDropped > 0){
|
||||||
float angle = b.angle() + Mathf.range(100f);
|
float angle = b.angle() + Mathf.range(100f);
|
||||||
@@ -264,7 +264,7 @@ public class TurretBullets extends BulletList implements ContentList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void hit(Bullet b, float hitx, float hity) {
|
public void hit(Bullet b, float hitx, float hity){
|
||||||
super.hit(b, hitx, hity);
|
super.hit(b, hitx, hity);
|
||||||
despawned(b);
|
despawned(b);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,12 +16,12 @@ import io.anuke.ucore.util.Mathf;
|
|||||||
|
|
||||||
import static io.anuke.mindustry.Vars.world;
|
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;
|
public static BulletType tungstenShotgun, bombExplosive, bombIncendiary, bombOil, shellCarbide;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
tungstenShotgun = new BasicBulletType(5f, 8, "bullet") {
|
tungstenShotgun = new BasicBulletType(5f, 8, "bullet"){
|
||||||
{
|
{
|
||||||
bulletWidth = 8f;
|
bulletWidth = 8f;
|
||||||
bulletHeight = 9f;
|
bulletHeight = 9f;
|
||||||
@@ -49,10 +49,10 @@ public class WeaponBullets extends BulletList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void hit(Bullet b, float x, float y) {
|
public void hit(Bullet b, float x, float y){
|
||||||
super.hit(b, x, 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 cx = x + Mathf.range(10f);
|
||||||
float cy = y + Mathf.range(10f);
|
float cy = y + Mathf.range(10f);
|
||||||
Tile tile = world.tileWorld(cx, cy);
|
Tile tile = world.tileWorld(cx, cy);
|
||||||
@@ -73,17 +73,17 @@ public class WeaponBullets extends BulletList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void hit(Bullet b, float x, float y) {
|
public void hit(Bullet b, float x, float y){
|
||||||
super.hit(b, x, 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));
|
Tile tile = world.tileWorld(x + Mathf.range(8f), y + Mathf.range(8f));
|
||||||
Puddle.deposit(tile, Liquids.oil, 5f);
|
Puddle.deposit(tile, Liquids.oil, 5f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
shellCarbide = new BasicBulletType(3.4f, 20, "bullet") {
|
shellCarbide = new BasicBulletType(3.4f, 20, "bullet"){
|
||||||
{
|
{
|
||||||
bulletWidth = 10f;
|
bulletWidth = 10f;
|
||||||
bulletHeight = 12f;
|
bulletHeight = 12f;
|
||||||
|
|||||||
@@ -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;
|
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
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
|
|
||||||
reactorsmoke = new Effect(17, e -> {
|
reactorsmoke = new Effect(17, e -> {
|
||||||
Angles.randLenVectors(e.id, 4, e.fin() * 8f, (x, y) -> {
|
Angles.randLenVectors(e.id, 4, e.fin() * 8f, (x, y) -> {
|
||||||
|
|||||||
@@ -10,12 +10,12 @@ import io.anuke.ucore.graphics.Lines;
|
|||||||
import io.anuke.ucore.util.Angles;
|
import io.anuke.ucore.util.Angles;
|
||||||
import io.anuke.ucore.util.Mathf;
|
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,
|
public static Effect hitBulletSmall, hitBulletBig, hitFlameSmall, hitLiquid, hitLancer, despawn, flakExplosion, blastExplosion, plasticExplosion,
|
||||||
artilleryTrail, incendTrail, missileTrail;
|
artilleryTrail, incendTrail, missileTrail;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
|
|
||||||
hitBulletSmall = new Effect(14, e -> {
|
hitBulletSmall = new Effect(14, e -> {
|
||||||
Draw.color(Color.WHITE, Palette.lightOrange, e.fin());
|
Draw.color(Color.WHITE, Palette.lightOrange, e.fin());
|
||||||
|
|||||||
@@ -10,11 +10,11 @@ import io.anuke.ucore.graphics.Fill;
|
|||||||
import io.anuke.ucore.util.Angles;
|
import io.anuke.ucore.util.Angles;
|
||||||
import io.anuke.ucore.util.Mathf;
|
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;
|
public static Effect burning, fire, smoke, steam, fireballsmoke, ballfire, freezing, melting, wet, oily;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
|
|
||||||
burning = new Effect(35f, e -> {
|
burning = new Effect(35f, e -> {
|
||||||
Draw.color(Palette.lightFlame, Palette.darkFlame, e.fin());
|
Draw.color(Palette.lightFlame, Palette.darkFlame, e.fin());
|
||||||
|
|||||||
@@ -10,11 +10,11 @@ import io.anuke.ucore.graphics.Lines;
|
|||||||
import io.anuke.ucore.util.Angles;
|
import io.anuke.ucore.util.Angles;
|
||||||
import io.anuke.ucore.util.Mathf;
|
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;
|
public static Effect shockwave, bigShockwave, nuclearShockwave, explosion, blockExplosion, blockExplosionSmoke;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
|
|
||||||
shockwave = new Effect(10f, 80f, e -> {
|
shockwave = new Effect(10f, 80f, e -> {
|
||||||
Draw.color(Color.WHITE, Color.LIGHT_GRAY, e.fin());
|
Draw.color(Color.WHITE, Color.LIGHT_GRAY, e.fin());
|
||||||
|
|||||||
@@ -11,11 +11,11 @@ import io.anuke.ucore.util.Angles;
|
|||||||
|
|
||||||
import static io.anuke.mindustry.Vars.tilesize;
|
import static io.anuke.mindustry.Vars.tilesize;
|
||||||
|
|
||||||
public class Fx extends FxList implements ContentList {
|
public class Fx extends FxList implements ContentList{
|
||||||
public static Effect none, placeBlock, breakBlock, smoke, spawn, tapBlock, select;
|
public static Effect none, placeBlock, breakBlock, smoke, spawn, tapBlock, select;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
|
|
||||||
none = new Effect(0, 0f, e -> {
|
none = new Effect(0, 0f, e -> {
|
||||||
});
|
});
|
||||||
@@ -30,7 +30,7 @@ public class Fx extends FxList implements ContentList {
|
|||||||
tapBlock = new Effect(12, e -> {
|
tapBlock = new Effect(12, e -> {
|
||||||
Draw.color(Palette.accent);
|
Draw.color(Palette.accent);
|
||||||
Lines.stroke(3f - e.fin() * 2f);
|
Lines.stroke(3f - e.fin() * 2f);
|
||||||
Lines.circle(e.x, e.y, 4f + (tilesize/1.5f * e.rotation) * e.fin());
|
Lines.circle(e.x, e.y, 4f + (tilesize / 1.5f * e.rotation) * e.fin());
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import io.anuke.mindustry.type.ContentList;
|
|||||||
public abstract class FxList implements ContentList{
|
public abstract class FxList implements ContentList{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Array<? extends Content> getAll() {
|
public Array<? extends Content> getAll(){
|
||||||
return Array.with();
|
return Array.with();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,11 +12,11 @@ import io.anuke.ucore.graphics.Shapes;
|
|||||||
import io.anuke.ucore.util.Angles;
|
import io.anuke.ucore.util.Angles;
|
||||||
import io.anuke.ucore.util.Mathf;
|
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;
|
public static Effect shootSmall, shootSmallSmoke, shootBig, shootBig2, shootBigSmoke, shootBigSmoke2, shootSmallFlame, shootLiquid, shellEjectSmall, shellEjectMedium, shellEjectBig, lancerLaserShoot, lancerLaserShootSmoke, lancerLaserCharge, lancerLaserChargeBegin, lightningCharge, lightningShoot;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
|
|
||||||
shootSmall = new Effect(8, e -> {
|
shootSmall = new Effect(8, e -> {
|
||||||
Draw.color(Palette.lighterOrange, Palette.lightOrange, e.fin());
|
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 -> {
|
shellEjectMedium = new GroundEffect(34f, 400f, e -> {
|
||||||
Draw.color(Palette.lightOrange, Color.LIGHT_GRAY, Palette.lightishGray, e.fin());
|
Draw.color(Palette.lightOrange, Color.LIGHT_GRAY, Palette.lightishGray, e.fin());
|
||||||
float rot = e.rotation + 90f;
|
float rot = e.rotation + 90f;
|
||||||
for (int i : Mathf.signs) {
|
for(int i : Mathf.signs){
|
||||||
float len = (2f + e.finpow() * 10f) * i;
|
float len = (2f + e.finpow() * 10f) * i;
|
||||||
float lr = rot + e.fin() * 20f * i;
|
float lr = rot + e.fin() * 20f * i;
|
||||||
Draw.rect("casing",
|
Draw.rect("casing",
|
||||||
@@ -122,7 +122,7 @@ public class ShootFx extends FxList implements ContentList {
|
|||||||
|
|
||||||
Draw.color(Color.LIGHT_GRAY, Color.GRAY, e.fin());
|
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) -> {
|
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);
|
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 -> {
|
shellEjectBig = new GroundEffect(22f, 400f, e -> {
|
||||||
Draw.color(Palette.lightOrange, Color.LIGHT_GRAY, Palette.lightishGray, e.fin());
|
Draw.color(Palette.lightOrange, Color.LIGHT_GRAY, Palette.lightishGray, e.fin());
|
||||||
float rot = e.rotation + 90f;
|
float rot = e.rotation + 90f;
|
||||||
for (int i : Mathf.signs) {
|
for(int i : Mathf.signs){
|
||||||
float len = (4f + e.finpow() * 8f) * i;
|
float len = (4f + e.finpow() * 8f) * i;
|
||||||
float lr = rot + Mathf.randomSeedRange(e.id + i + 6, 20f * e.fin()) * i;
|
float lr = rot + Mathf.randomSeedRange(e.id + i + 6, 20f * e.fin()) * i;
|
||||||
Draw.rect("casing",
|
Draw.rect("casing",
|
||||||
@@ -146,7 +146,7 @@ public class ShootFx extends FxList implements ContentList {
|
|||||||
|
|
||||||
Draw.color(Color.LIGHT_GRAY);
|
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) -> {
|
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);
|
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 -> {
|
lancerLaserShoot = new Effect(21f, e -> {
|
||||||
Draw.color(Palette.lancerLaser);
|
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);
|
Shapes.tri(e.x, e.y, 4f * e.fout(), 29f, e.rotation + 90f * i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,11 +10,11 @@ import io.anuke.ucore.graphics.Lines;
|
|||||||
import io.anuke.ucore.util.Angles;
|
import io.anuke.ucore.util.Angles;
|
||||||
import io.anuke.ucore.util.Mathf;
|
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;
|
public static Effect vtolHover, unitDrop, unitPickup, pickup;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
|
|
||||||
vtolHover = new Effect(40f, e -> {
|
vtolHover = new Effect(40f, e -> {
|
||||||
float len = e.finpow() * 10f;
|
float len = e.finpow() * 10f;
|
||||||
|
|||||||
@@ -25,9 +25,11 @@ import io.anuke.ucore.core.Effects;
|
|||||||
import io.anuke.ucore.function.Consumer;
|
import io.anuke.ucore.function.Consumer;
|
||||||
import io.anuke.ucore.util.Log;
|
import io.anuke.ucore.util.Log;
|
||||||
|
|
||||||
/**Loads all game content.
|
/**
|
||||||
* Call load() before doing anything with content.*/
|
* Loads all game content.
|
||||||
public class ContentLoader {
|
* Call load() before doing anything with content.
|
||||||
|
*/
|
||||||
|
public class ContentLoader{
|
||||||
private static boolean loaded = false;
|
private static boolean loaded = false;
|
||||||
private static ObjectSet<Array<? extends Content>> contentSet = new OrderedSet<>();
|
private static ObjectSet<Array<? extends Content>> contentSet = new OrderedSet<>();
|
||||||
private static OrderedMap<String, Array<Content>> contentMap = new OrderedMap<>();
|
private static OrderedMap<String, Array<Content>> contentMap = new OrderedMap<>();
|
||||||
@@ -94,7 +96,9 @@ public class ContentLoader {
|
|||||||
new Recipes(),
|
new Recipes(),
|
||||||
};
|
};
|
||||||
|
|
||||||
/**Creates all content types.*/
|
/**
|
||||||
|
* Creates all content types.
|
||||||
|
*/
|
||||||
public static void load(){
|
public static void load(){
|
||||||
if(loaded){
|
if(loaded){
|
||||||
Log.info("Content already loaded, skipping.");
|
Log.info("Content already loaded, skipping.");
|
||||||
@@ -103,11 +107,11 @@ public class ContentLoader {
|
|||||||
|
|
||||||
registerTypes();
|
registerTypes();
|
||||||
|
|
||||||
for (ContentList list : content){
|
for(ContentList list : content){
|
||||||
list.load();
|
list.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ContentList list : content){
|
for(ContentList list : content){
|
||||||
if(list.getAll().size != 0){
|
if(list.getAll().size != 0){
|
||||||
String type = list.getAll().first().getContentTypeName();
|
String type = list.getAll().first().getContentTypeName();
|
||||||
|
|
||||||
@@ -134,7 +138,9 @@ public class ContentLoader {
|
|||||||
loaded = true;
|
loaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Initializes all content with the specified function.*/
|
/**
|
||||||
|
* Initializes all content with the specified function.
|
||||||
|
*/
|
||||||
public static void initialize(Consumer<Content> callable){
|
public static void initialize(Consumer<Content> callable){
|
||||||
if(initialization.contains(callable)) return;
|
if(initialization.contains(callable)) return;
|
||||||
|
|
||||||
@@ -155,8 +161,10 @@ public class ContentLoader {
|
|||||||
return contentMap;
|
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(){
|
private static void registerTypes(){
|
||||||
TypeTrait.registerType(Player.class, Player::new);
|
TypeTrait.registerType(Player.class, Player::new);
|
||||||
TypeTrait.registerType(ItemDrop.class, ItemDrop::new);
|
TypeTrait.registerType(ItemDrop.class, ItemDrop::new);
|
||||||
|
|||||||
@@ -30,12 +30,16 @@ import io.anuke.ucore.util.Atlas;
|
|||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
/**Control module.
|
/**
|
||||||
|
* Control module.
|
||||||
* Handles all input, saving, keybinds and keybinds.
|
* Handles all input, saving, keybinds and keybinds.
|
||||||
* Should <i>not</i> handle any logic-critical state.
|
* Should <i>not</i> 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{
|
public class Control extends Module{
|
||||||
/**Minimum period of time between the same sound being played.*/
|
/**
|
||||||
|
* Minimum period of time between the same sound being played.
|
||||||
|
*/
|
||||||
private static final long minSoundPeriod = 100;
|
private static final long minSoundPeriod = 100;
|
||||||
|
|
||||||
private boolean hiscore = false;
|
private boolean hiscore = false;
|
||||||
@@ -90,7 +94,7 @@ public class Control extends Module{
|
|||||||
|
|
||||||
Settings.defaultList(
|
Settings.defaultList(
|
||||||
"ip", "localhost",
|
"ip", "localhost",
|
||||||
"port", port+"",
|
"port", port + "",
|
||||||
"color-0", Color.rgba8888(playerColors[8]),
|
"color-0", Color.rgba8888(playerColors[8]),
|
||||||
"color-1", Color.rgba8888(playerColors[11]),
|
"color-1", Color.rgba8888(playerColors[11]),
|
||||||
"color-2", Color.rgba8888(playerColors[13]),
|
"color-2", Color.rgba8888(playerColors[13]),
|
||||||
@@ -205,8 +209,8 @@ public class Control extends Module{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void removePlayer(){
|
public void removePlayer(){
|
||||||
players[players.length-1].remove();
|
players[players.length - 1].remove();
|
||||||
inputs[inputs.length-1].remove();
|
inputs[inputs.length - 1].remove();
|
||||||
|
|
||||||
Player[] old = players;
|
Player[] old = players;
|
||||||
players = new Player[players.length - 1];
|
players = new Player[players.length - 1];
|
||||||
@@ -217,7 +221,7 @@ public class Control extends Module{
|
|||||||
System.arraycopy(oldi, 0, inputs, 0, inputs.length);
|
System.arraycopy(oldi, 0, inputs, 0, inputs.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContentDatabase database() {
|
public ContentDatabase database(){
|
||||||
return db;
|
return db;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,7 +273,7 @@ public class Control extends Module{
|
|||||||
control.database().unlockContent(players[0].inventory.getItem().item);
|
control.database().unlockContent(players[0].inventory.getItem().item);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0 ; i < Recipe.all().size; i ++){
|
for(int i = 0; i < Recipe.all().size; i++){
|
||||||
Recipe recipe = Recipe.all().get(i);
|
Recipe recipe = Recipe.all().get(i);
|
||||||
if(!recipe.debugOnly && entity.items.has(recipe.requirements, 1.4f)){
|
if(!recipe.debugOnly && entity.items.has(recipe.requirements, 1.4f)){
|
||||||
if(control.database().unlockContent(recipe)){
|
if(control.database().unlockContent(recipe)){
|
||||||
@@ -335,9 +339,9 @@ public class Control extends Module{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Called from main logic thread.*/
|
/** Called from main logic thread.*/
|
||||||
public void runUpdateLogic(){
|
public void runUpdateLogic(){
|
||||||
if(!state.is(State.menu)) {
|
if(!state.is(State.menu)){
|
||||||
renderer.minimap().updateUnitArray();
|
renderer.minimap().updateUnitArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -384,8 +388,8 @@ public class Control extends Module{
|
|||||||
if(state.is(State.paused)){
|
if(state.is(State.paused)){
|
||||||
ui.paused.hide();
|
ui.paused.hide();
|
||||||
state.set(State.playing);
|
state.set(State.playing);
|
||||||
}else if (!ui.restart.isShown()){
|
}else if(!ui.restart.isShown()){
|
||||||
if(ui.chatfrag.chatOpen()) {
|
if(ui.chatfrag.chatOpen()){
|
||||||
ui.chatfrag.hide();
|
ui.chatfrag.hide();
|
||||||
}else{
|
}else{
|
||||||
ui.paused.show();
|
ui.paused.show();
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ import io.anuke.mindustry.game.TeamInfo;
|
|||||||
import io.anuke.ucore.core.Events;
|
import io.anuke.ucore.core.Events;
|
||||||
|
|
||||||
public class GameState{
|
public class GameState{
|
||||||
private State state = State.menu;
|
|
||||||
|
|
||||||
public int wave = 1;
|
public int wave = 1;
|
||||||
public float wavetime;
|
public float wavetime;
|
||||||
public boolean gameOver = false;
|
public boolean gameOver = false;
|
||||||
@@ -18,6 +16,7 @@ public class GameState{
|
|||||||
public boolean friendlyFire;
|
public boolean friendlyFire;
|
||||||
public WaveSpawner spawner = new WaveSpawner();
|
public WaveSpawner spawner = new WaveSpawner();
|
||||||
public TeamInfo teams = new TeamInfo();
|
public TeamInfo teams = new TeamInfo();
|
||||||
|
private State state = State.menu;
|
||||||
|
|
||||||
public void set(State astate){
|
public void set(State astate){
|
||||||
Events.fire(StateChangeEvent.class, state, astate);
|
Events.fire(StateChangeEvent.class, state, astate);
|
||||||
|
|||||||
@@ -24,13 +24,15 @@ import io.anuke.ucore.modules.Module;
|
|||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
/**Logic module.
|
/**
|
||||||
|
* Logic module.
|
||||||
* Handles all logic for entities and waves.
|
* Handles all logic for entities and waves.
|
||||||
* Handles game state events.
|
* Handles game state events.
|
||||||
* Does not store any game state itself.
|
* Does not store any game state itself.
|
||||||
*
|
* <p>
|
||||||
* This class should <i>not</i> call any outside methods to change state of modules, but instead fire events.*/
|
* This class should <i>not</i> call any outside methods to change state of modules, but instead fire events.
|
||||||
public class Logic extends Module {
|
*/
|
||||||
|
public class Logic extends Module{
|
||||||
public boolean doUpdate = true;
|
public boolean doUpdate = true;
|
||||||
|
|
||||||
public Logic(){
|
public Logic(){
|
||||||
@@ -49,11 +51,11 @@ public class Logic extends Module {
|
|||||||
|
|
||||||
//fill inventory with items for debugging
|
//fill inventory with items for debugging
|
||||||
|
|
||||||
for (TeamData team : state.teams.getTeams()) {
|
for(TeamData team : state.teams.getTeams()){
|
||||||
for (Tile tile : team.cores) {
|
for(Tile tile : team.cores){
|
||||||
if(debug) {
|
if(debug){
|
||||||
for (Item item : Item.all()) {
|
for(Item item : Item.all()){
|
||||||
if (item.type == ItemType.material) {
|
if(item.type == ItemType.material){
|
||||||
tile.entity.items.add(item, 1000);
|
tile.entity.items.add(item, 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -85,7 +87,7 @@ public class Logic extends Module {
|
|||||||
|
|
||||||
public void runWave(){
|
public void runWave(){
|
||||||
state.spawner.spawnEnemies();
|
state.spawner.spawnEnemies();
|
||||||
state.wave ++;
|
state.wave++;
|
||||||
state.wavetime = wavespace * state.difficulty.timeScaling;
|
state.wavetime = wavespace * state.difficulty.timeScaling;
|
||||||
|
|
||||||
Events.fire(WaveEvent.class);
|
Events.fire(WaveEvent.class);
|
||||||
@@ -137,7 +139,8 @@ public class Logic extends Module {
|
|||||||
runWave();
|
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);
|
Entities.update(bulletGroup);
|
||||||
for(EntityGroup group : unitGroups){
|
for(EntityGroup group : unitGroups){
|
||||||
|
|||||||
@@ -36,38 +36,64 @@ import java.util.Random;
|
|||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
public class NetClient extends Module {
|
public class NetClient extends Module{
|
||||||
private final static float dataTimeout = 60*18;
|
private final static float dataTimeout = 60 * 18;
|
||||||
private final static float playerSyncTime = 2;
|
private final static float playerSyncTime = 2;
|
||||||
|
|
||||||
private Timer timer = new Timer(5);
|
private Timer timer = new Timer(5);
|
||||||
/**Whether the client is currently connecting.*/
|
/**
|
||||||
|
* Whether the client is currently connecting.
|
||||||
|
*/
|
||||||
private boolean connecting = false;
|
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;
|
private boolean quiet = false;
|
||||||
/**Counter for data timeout.*/
|
/**
|
||||||
|
* Counter for data timeout.
|
||||||
|
*/
|
||||||
private float timeoutTime = 0f;
|
private float timeoutTime = 0f;
|
||||||
/**Last sent client snapshot ID.*/
|
/**
|
||||||
|
* Last sent client snapshot ID.
|
||||||
|
*/
|
||||||
private int lastSent;
|
private int lastSent;
|
||||||
|
|
||||||
/**Last snapshot ID recieved.*/
|
/**
|
||||||
|
* Last snapshot ID recieved.
|
||||||
|
*/
|
||||||
private int lastSnapshotBaseID = -1;
|
private int lastSnapshotBaseID = -1;
|
||||||
/**Last snapshot recieved.*/
|
/**
|
||||||
|
* Last snapshot recieved.
|
||||||
|
*/
|
||||||
private byte[] lastSnapshotBase;
|
private byte[] lastSnapshotBase;
|
||||||
/**Current snapshot that is being built from chinks.*/
|
/**
|
||||||
|
* Current snapshot that is being built from chinks.
|
||||||
|
*/
|
||||||
private byte[] currentSnapshot;
|
private byte[] currentSnapshot;
|
||||||
/**Array of recieved chunk statuses.*/
|
/**
|
||||||
|
* Array of recieved chunk statuses.
|
||||||
|
*/
|
||||||
private boolean[] recievedChunks;
|
private boolean[] recievedChunks;
|
||||||
/**Counter of how many chunks have been recieved.*/
|
/**
|
||||||
|
* Counter of how many chunks have been recieved.
|
||||||
|
*/
|
||||||
private int recievedChunkCounter;
|
private int recievedChunkCounter;
|
||||||
/**ID of snapshot that is currently being constructed.*/
|
/**
|
||||||
|
* ID of snapshot that is currently being constructed.
|
||||||
|
*/
|
||||||
private int currentSnapshotID = -1;
|
private int currentSnapshotID = -1;
|
||||||
|
|
||||||
/**Decoder for uncompressing snapshots.*/
|
/**
|
||||||
|
* Decoder for uncompressing snapshots.
|
||||||
|
*/
|
||||||
private DEZDecoder decoder = new DEZDecoder();
|
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();
|
private IntSet removed = new IntSet();
|
||||||
/**Byte stream for reading in snapshots.*/
|
/**
|
||||||
|
* Byte stream for reading in snapshots.
|
||||||
|
*/
|
||||||
private ReusableByteArrayInputStream byteStream = new ReusableByteArrayInputStream();
|
private ReusableByteArrayInputStream byteStream = new ReusableByteArrayInputStream();
|
||||||
private DataInputStream dataStream = new DataInputStream(byteStream);
|
private DataInputStream dataStream = new DataInputStream(byteStream);
|
||||||
|
|
||||||
@@ -120,7 +146,7 @@ public class NetClient extends Module {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Net.handleClient(Disconnect.class, packet -> {
|
Net.handleClient(Disconnect.class, packet -> {
|
||||||
if (quiet) return;
|
if(quiet) return;
|
||||||
|
|
||||||
Timers.runTask(3f, ui.loadfrag::hide);
|
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
|
@Override
|
||||||
public void update(){
|
public void update(){
|
||||||
if(!Net.client()) return;
|
if(!Net.client()) return;
|
||||||
@@ -224,161 +410,4 @@ public class NetClient extends Module {
|
|||||||
return result;
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -45,20 +45,30 @@ public class NetServer extends Module{
|
|||||||
private final static byte[] reusableSnapArray = new byte[maxSnapshotSize];
|
private final static byte[] reusableSnapArray = new byte[maxSnapshotSize];
|
||||||
private final static float serverSyncTime = 4, kickDuration = 30 * 1000;
|
private final static float serverSyncTime = 4, kickDuration = 30 * 1000;
|
||||||
private final static Vector2 vector = new Vector2();
|
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;
|
private final static float correctDist = 16f;
|
||||||
|
|
||||||
public final Administration admins = new Administration();
|
public final Administration admins = new Administration();
|
||||||
|
|
||||||
/**Maps connection IDs to players.*/
|
/**
|
||||||
|
* Maps connection IDs to players.
|
||||||
|
*/
|
||||||
private IntMap<Player> connections = new IntMap<>();
|
private IntMap<Player> connections = new IntMap<>();
|
||||||
private boolean closing = false;
|
private boolean closing = false;
|
||||||
|
|
||||||
/**Stream for writing player sync data to.*/
|
/**
|
||||||
|
* Stream for writing player sync data to.
|
||||||
|
*/
|
||||||
private CountableByteArrayOutputStream syncStream = new CountableByteArrayOutputStream();
|
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);
|
private DataOutputStream dataStream = new DataOutputStream(syncStream);
|
||||||
/**Encoder for computing snapshot deltas.*/
|
/**
|
||||||
|
* Encoder for computing snapshot deltas.
|
||||||
|
*/
|
||||||
private DEZEncoder encoder = new DEZEncoder();
|
private DEZEncoder encoder = new DEZEncoder();
|
||||||
|
|
||||||
public NetServer(){
|
public NetServer(){
|
||||||
@@ -105,14 +115,14 @@ public class NetServer extends Module{
|
|||||||
|
|
||||||
boolean preventDuplicates = headless;
|
boolean preventDuplicates = headless;
|
||||||
|
|
||||||
if(preventDuplicates) {
|
if(preventDuplicates){
|
||||||
for (Player player : playerGroup.all()) {
|
for(Player player : playerGroup.all()){
|
||||||
if (player.name.equalsIgnoreCase(packet.name)) {
|
if(player.name.equalsIgnoreCase(packet.name)){
|
||||||
kick(id, KickReason.nameInUse);
|
kick(id, KickReason.nameInUse);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player.uuid.equals(packet.uuid)) {
|
if(player.uuid.equals(packet.uuid)){
|
||||||
kick(id, KickReason.idInUse);
|
kick(id, KickReason.idInUse);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -181,7 +191,7 @@ public class NetServer extends Module{
|
|||||||
|
|
||||||
long elapsed = TimeUtils.timeSinceMillis(connection.lastRecievedClientTime);
|
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
|
//extra 1.1x multiplicaton is added just in case
|
||||||
float maxMove = elapsed / 1000f * 60f * maxSpeed * 1.1f;
|
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(){
|
public void update(){
|
||||||
if(!headless && !closing && Net.server() && state.is(State.menu)){
|
if(!headless && !closing && Net.server() && state.is(State.menu)){
|
||||||
closing = true;
|
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){
|
if((reason == KickReason.kick || reason == KickReason.banned) && admins.getTraceByID(getUUID(con.id)).uuid != null){
|
||||||
PlayerInfo info = admins.getInfo(admins.getTraceByID(getUUID(con.id)).uuid);
|
PlayerInfo info = admins.getInfo(admins.getTraceByID(getUUID(con.id)).uuid);
|
||||||
info.timesKicked ++;
|
info.timesKicked++;
|
||||||
info.lastKicked = TimeUtils.millis();
|
info.lastKicked = TimeUtils.millis();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,7 +378,7 @@ public class NetServer extends Module{
|
|||||||
|
|
||||||
String fixName(String name){
|
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) != '[')){
|
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 prev = name.substring(0, i);
|
||||||
String next = name.substring(i);
|
String next = name.substring(i);
|
||||||
@@ -303,7 +393,7 @@ public class NetServer extends Module{
|
|||||||
|
|
||||||
String checkColor(String str){
|
String checkColor(String str){
|
||||||
|
|
||||||
for(int i = 1; i < str.length(); i ++){
|
for(int i = 1; i < str.length(); i++){
|
||||||
if(str.charAt(i) == ']'){
|
if(str.charAt(i) == ']'){
|
||||||
String color = str.substring(1, i);
|
String color = str.substring(1, i);
|
||||||
|
|
||||||
@@ -318,7 +408,7 @@ public class NetServer extends Module{
|
|||||||
if(result.a <= 0.8f){
|
if(result.a <= 0.8f){
|
||||||
return str.substring(i + 1);
|
return str.substring(i + 1);
|
||||||
}
|
}
|
||||||
}catch (Exception e){
|
}catch(Exception e){
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -328,10 +418,10 @@ public class NetServer extends Module{
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sync(){
|
void sync(){
|
||||||
try {
|
try{
|
||||||
|
|
||||||
//iterate through each player
|
//iterate through each player
|
||||||
for (Player player : connections.values()) {
|
for(Player player : connections.values()){
|
||||||
NetConnection connection = player.con;
|
NetConnection connection = player.con;
|
||||||
|
|
||||||
if(!connection.isConnected()){
|
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 the player hasn't acknowledged that it has recieved the packet, send the same thing again
|
||||||
if(connection.currentBaseID < connection.lastSentSnapshotID){
|
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);
|
sendSplitSnapshot(connection.id, connection.lastSentSnapshot, connection.lastSentSnapshotID, connection.lastSentBase);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -371,17 +462,17 @@ public class NetServer extends Module{
|
|||||||
|
|
||||||
int totalGroups = 0;
|
int totalGroups = 0;
|
||||||
|
|
||||||
for (EntityGroup<?> group : Entities.getAllGroups()) {
|
for(EntityGroup<?> group : Entities.getAllGroups()){
|
||||||
if (!group.isEmpty() && (group.all().get(0) instanceof SyncTrait)) totalGroups ++;
|
if(!group.isEmpty() && (group.all().get(0) instanceof SyncTrait)) totalGroups++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//write total amount of serializable groups
|
//write total amount of serializable groups
|
||||||
dataStream.writeByte(totalGroups);
|
dataStream.writeByte(totalGroups);
|
||||||
|
|
||||||
//check for syncable groups
|
//check for syncable groups
|
||||||
for (EntityGroup<?> group : Entities.getAllGroups()) {
|
for(EntityGroup<?> group : Entities.getAllGroups()){
|
||||||
//TODO range-check sync positions to optimize?
|
//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
|
//make sure mapping is enabled for this group
|
||||||
if(!group.mappingEnabled()){
|
if(!group.mappingEnabled()){
|
||||||
@@ -391,8 +482,8 @@ public class NetServer extends Module{
|
|||||||
int amount = 0;
|
int amount = 0;
|
||||||
|
|
||||||
for(Entity entity : group.all()){
|
for(Entity entity : group.all()){
|
||||||
if(((SyncTrait)entity).isSyncing()){
|
if(((SyncTrait) entity).isSyncing()){
|
||||||
amount ++;
|
amount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -401,15 +492,16 @@ public class NetServer extends Module{
|
|||||||
dataStream.writeShort(amount);
|
dataStream.writeShort(amount);
|
||||||
|
|
||||||
for(Entity entity : group.all()){
|
for(Entity entity : group.all()){
|
||||||
if(!((SyncTrait)entity).isSyncing()) continue;
|
if(!((SyncTrait) entity).isSyncing()) continue;
|
||||||
|
|
||||||
int position = syncStream.position();
|
int position = syncStream.position();
|
||||||
//write all entities now
|
//write all entities now
|
||||||
dataStream.writeInt(entity.getID()); //write id
|
dataStream.writeInt(entity.getID()); //write id
|
||||||
dataStream.writeByte(((SyncTrait)entity).getTypeID()); //write type ID
|
dataStream.writeByte(((SyncTrait) entity).getTypeID()); //write type ID
|
||||||
((SyncTrait)entity).write(dataStream); //write entity
|
((SyncTrait) entity).write(dataStream); //write entity
|
||||||
int length = syncStream.position() - position; //length must always be less than 127 bytes
|
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);
|
dataStream.writeByte(length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -433,7 +525,8 @@ public class NetServer extends Module{
|
|||||||
|
|
||||||
//send diff, otherwise
|
//send diff, otherwise
|
||||||
byte[] diff = ByteDeltaEncoder.toDiff(new ByteMatcherHash(connection.currentBaseSnapshot, bytes), encoder);
|
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);
|
sendSplitSnapshot(connection.id, diff, connection.currentBaseID + 1, connection.currentBaseID);
|
||||||
connection.lastSentSnapshot = diff;
|
connection.lastSentSnapshot = diff;
|
||||||
connection.lastSentSnapshotID = connection.currentBaseID + 1;
|
connection.lastSentSnapshotID = connection.currentBaseID + 1;
|
||||||
@@ -441,86 +534,8 @@ public class NetServer extends Module{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}catch (IOException e){
|
}catch(IOException e){
|
||||||
e.printStackTrace();
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,45 +11,102 @@ import java.util.Date;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
public abstract class Platform {
|
public abstract class Platform{
|
||||||
/**Each separate game platform should set this instance to their own implementation.*/
|
/**
|
||||||
public static Platform instance = new 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 the date using the default date formatter.
|
||||||
/**Format a number by adding in commas or periods where needed.*/
|
*/
|
||||||
public String format(int number){return "invalid";}
|
public String format(Date date){
|
||||||
/**Show a native error dialog.*/
|
return "invalid";
|
||||||
public void showError(String text){}
|
}
|
||||||
/**Add a text input dialog that should show up after the field is tapped.*/
|
|
||||||
|
/**
|
||||||
|
* 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){
|
public void addDialog(TextField field){
|
||||||
addDialog(field, 16);
|
addDialog(field, 16);
|
||||||
}
|
}
|
||||||
/**See addDialog().*/
|
|
||||||
public void addDialog(TextField field, int maxLength){}
|
/**
|
||||||
/**Update discord RPC.*/
|
* See addDialog().
|
||||||
public void updateRPC(){}
|
*/
|
||||||
/**Called when the game is exited.*/
|
public void addDialog(TextField field, int maxLength){
|
||||||
public void onGameExit(){}
|
}
|
||||||
/**Open donation dialog. Currently android only.*/
|
|
||||||
public void openDonations(){}
|
/**
|
||||||
/**Whether donating is supported.*/
|
* 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(){
|
public boolean canDonate(){
|
||||||
return false;
|
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().*/
|
* 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){
|
public String getLocaleName(Locale locale){
|
||||||
return locale.toString();
|
return locale.toString();
|
||||||
}
|
}
|
||||||
/**Whether joining games is supported.*/
|
|
||||||
|
/**
|
||||||
|
* Whether joining games is supported.
|
||||||
|
*/
|
||||||
public boolean canJoinGame(){
|
public boolean canJoinGame(){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
/**Whether debug mode is enabled.*/
|
|
||||||
public boolean isDebug(){return false;}
|
/**
|
||||||
/**Must be a base64 string 8 bytes in length.*/
|
* Whether debug mode is enabled.
|
||||||
|
*/
|
||||||
|
public boolean isDebug(){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Must be a base64 string 8 bytes in length.
|
||||||
|
*/
|
||||||
public String getUUID(){
|
public String getUUID(){
|
||||||
String uuid = Settings.getString("uuid", "");
|
String uuid = Settings.getString("uuid", "");
|
||||||
if(uuid.isEmpty()){
|
if(uuid.isEmpty()){
|
||||||
@@ -62,12 +119,21 @@ public abstract class Platform {
|
|||||||
}
|
}
|
||||||
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.
|
/**
|
||||||
|
* 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 text File chooser title text
|
||||||
* @param content Description of the type of files to be loaded
|
* @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 open Whether to open or save files
|
||||||
* @param filetype File extension to filter
|
* @param filetype File extension to filter
|
||||||
*/
|
*/
|
||||||
public void showFileChooser(String text, String content, Consumer<FileHandle> cons, boolean open, String filetype){}
|
public void showFileChooser(String text, String content, Consumer<FileHandle> cons, boolean open, String filetype){
|
||||||
/**Use the default thread provider from the kryonet module for this.*/
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use the default thread provider from the kryonet module for this.
|
||||||
|
*/
|
||||||
public ThreadProvider getThreadProvider(){
|
public ThreadProvider getThreadProvider(){
|
||||||
return new ThreadProvider() {
|
return new ThreadProvider(){
|
||||||
@Override public boolean isOnThread() {return true;}
|
@Override
|
||||||
@Override public void sleep(long ms) {}
|
public boolean isOnThread(){
|
||||||
@Override public void start(Runnable run) {}
|
return true;
|
||||||
@Override public void stop() {}
|
}
|
||||||
@Override public void notify(Object object) {}
|
|
||||||
@Override public void wait(Object object) {}
|
@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
|
//TODO iOS implementation
|
||||||
/**Forces the app into landscape mode. Currently Android only.*/
|
|
||||||
public void beginForceLandscape(){}
|
/**
|
||||||
|
* Forces the app into landscape mode. Currently Android only.
|
||||||
|
*/
|
||||||
|
public void beginForceLandscape(){
|
||||||
|
}
|
||||||
|
|
||||||
//TODO iOS implementation
|
//TODO iOS implementation
|
||||||
/**Stops forcing the app into landscape orientation. Currently Android only.*/
|
|
||||||
public void endForceLandscape(){}
|
/**
|
||||||
|
* Stops forcing the app into landscape orientation. Currently Android only.
|
||||||
|
*/
|
||||||
|
public void endForceLandscape(){
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ public class Renderer extends RendererModule{
|
|||||||
private OverlayRenderer overlays = new OverlayRenderer();
|
private OverlayRenderer overlays = new OverlayRenderer();
|
||||||
private FogRenderer fog = new FogRenderer();
|
private FogRenderer fog = new FogRenderer();
|
||||||
|
|
||||||
public Renderer() {
|
public Renderer(){
|
||||||
pixelate = true;
|
pixelate = true;
|
||||||
Lines.setCircleVertices(14);
|
Lines.setCircleVertices(14);
|
||||||
|
|
||||||
@@ -78,16 +78,16 @@ public class Renderer extends RendererModule{
|
|||||||
|
|
||||||
if(view.overlaps(pos)){
|
if(view.overlaps(pos)){
|
||||||
|
|
||||||
if(!(effect instanceof GroundEffect)) {
|
if(!(effect instanceof GroundEffect)){
|
||||||
EffectEntity entity = Pooling.obtain(EffectEntity.class);
|
EffectEntity entity = Pooling.obtain(EffectEntity.class);
|
||||||
entity.effect = effect;
|
entity.effect = effect;
|
||||||
entity.color = color;
|
entity.color = color;
|
||||||
entity.rotation = rotation;
|
entity.rotation = rotation;
|
||||||
entity.data = data;
|
entity.data = data;
|
||||||
entity.id ++;
|
entity.id++;
|
||||||
entity.set(x, y);
|
entity.set(x, y);
|
||||||
if(data instanceof BaseEntity){
|
if(data instanceof BaseEntity){
|
||||||
entity.setParent((BaseEntity)data);
|
entity.setParent((BaseEntity) data);
|
||||||
}
|
}
|
||||||
threads.runGraphics(() -> effectGroup.add(entity));
|
threads.runGraphics(() -> effectGroup.add(entity));
|
||||||
}else{
|
}else{
|
||||||
@@ -95,7 +95,7 @@ public class Renderer extends RendererModule{
|
|||||||
entity.effect = effect;
|
entity.effect = effect;
|
||||||
entity.color = color;
|
entity.color = color;
|
||||||
entity.rotation = rotation;
|
entity.rotation = rotation;
|
||||||
entity.id ++;
|
entity.id++;
|
||||||
entity.data = data;
|
entity.data = data;
|
||||||
entity.set(x, y);
|
entity.set(x, y);
|
||||||
threads.runGraphics(() -> groundEffectGroup.add(entity));
|
threads.runGraphics(() -> groundEffectGroup.add(entity));
|
||||||
@@ -137,7 +137,7 @@ public class Renderer extends RendererModule{
|
|||||||
if(Mathf.in(camera.zoom, targetzoom, 0.005f)){
|
if(Mathf.in(camera.zoom, targetzoom, 0.005f)){
|
||||||
camera.zoom = 1f;
|
camera.zoom = 1f;
|
||||||
Graphics.setCameraScale(targetscale);
|
Graphics.setCameraScale(targetscale);
|
||||||
for(Player player : players) {
|
for(Player player : players){
|
||||||
control.input(player.playerIndex).resetCursor();
|
control.input(player.playerIndex).resetCursor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -179,7 +179,7 @@ public class Renderer extends RendererModule{
|
|||||||
camera.position.set(lastx - deltax, lasty - deltay, 0);
|
camera.position.set(lastx - deltax, lasty - deltay, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(debug && !ui.chatfrag.chatOpen()) {
|
if(debug && !ui.chatfrag.chatOpen()){
|
||||||
renderer.record(); //this only does something if GdxGifRecorder is on the class path, which it usually isn't
|
renderer.record(); //this only does something if GdxGifRecorder is on the class path, which it usually isn't
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -320,7 +320,7 @@ public class Renderer extends RendererModule{
|
|||||||
float lastx = t.getX(), lasty = t.getY(), lastrot = 0f;
|
float lastx = t.getX(), lasty = t.getY(), lastrot = 0f;
|
||||||
|
|
||||||
if(threads.doInterpolate() && threads.isEnabled() && t instanceof SolidTrait){
|
if(threads.doInterpolate() && threads.isEnabled() && t instanceof SolidTrait){
|
||||||
SolidTrait s = (SolidTrait)t;
|
SolidTrait s = (SolidTrait) t;
|
||||||
|
|
||||||
lastrot = s.getRotation();
|
lastrot = s.getRotation();
|
||||||
|
|
||||||
@@ -348,9 +348,9 @@ public class Renderer extends RendererModule{
|
|||||||
t.setX(lastx);
|
t.setX(lastx);
|
||||||
t.setY(lasty);
|
t.setY(lasty);
|
||||||
|
|
||||||
if(threads.doInterpolate() && threads.isEnabled()) {
|
if(threads.doInterpolate() && threads.isEnabled()){
|
||||||
|
|
||||||
if (t instanceof SolidTrait) {
|
if(t instanceof SolidTrait){
|
||||||
((SolidTrait) t).setRotation(lastrot);
|
((SolidTrait) t).setRotation(lastrot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -360,14 +360,14 @@ public class Renderer extends RendererModule{
|
|||||||
@Override
|
@Override
|
||||||
public void resize(int width, int height){
|
public void resize(int width, int height){
|
||||||
super.resize(width, height);
|
super.resize(width, height);
|
||||||
for(Player player : players) {
|
for(Player player : players){
|
||||||
control.input(player.playerIndex).resetCursor();
|
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
|
@Override
|
||||||
public void dispose() {
|
public void dispose(){
|
||||||
background.dispose();
|
background.dispose();
|
||||||
fog.dispose();
|
fog.dispose();
|
||||||
}
|
}
|
||||||
@@ -383,11 +383,11 @@ public class Renderer extends RendererModule{
|
|||||||
return avgPosition;
|
return avgPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FogRenderer fog() {
|
public FogRenderer fog(){
|
||||||
return fog;
|
return fog;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MinimapRenderer minimap() {
|
public MinimapRenderer minimap(){
|
||||||
return minimap;
|
return minimap;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -397,17 +397,17 @@ public class Renderer extends RendererModule{
|
|||||||
float ch = camera.viewportHeight * camera.zoom;
|
float ch = camera.viewportHeight * camera.zoom;
|
||||||
if(vw < cw){
|
if(vw < cw){
|
||||||
batch.draw(background,
|
batch.draw(background,
|
||||||
camera.position.x + vw/2,
|
camera.position.x + vw / 2,
|
||||||
Mathf.round(camera.position.y - ch/2, tilesize),
|
Mathf.round(camera.position.y - ch / 2, tilesize),
|
||||||
(cw - vw) /2,
|
(cw - vw) / 2,
|
||||||
ch + tilesize,
|
ch + tilesize,
|
||||||
0, 0,
|
0, 0,
|
||||||
((cw - vw) / 2 / tilesize), -ch / tilesize + 1);
|
((cw - vw) / 2 / tilesize), -ch / tilesize + 1);
|
||||||
|
|
||||||
batch.draw(background,
|
batch.draw(background,
|
||||||
camera.position.x - vw/2,
|
camera.position.x - vw / 2,
|
||||||
Mathf.round(camera.position.y - ch/2, tilesize),
|
Mathf.round(camera.position.y - ch / 2, tilesize),
|
||||||
-(cw - vw) /2,
|
-(cw - vw) / 2,
|
||||||
ch + tilesize,
|
ch + tilesize,
|
||||||
0, 0,
|
0, 0,
|
||||||
-((cw - vw) / 2 / tilesize), -ch / tilesize + 1);
|
-((cw - vw) / 2 / tilesize), -ch / tilesize + 1);
|
||||||
@@ -415,10 +415,10 @@ public class Renderer extends RendererModule{
|
|||||||
}
|
}
|
||||||
|
|
||||||
void drawDebug(){
|
void drawDebug(){
|
||||||
int rangex = (int)(Core.camera.viewportWidth/tilesize/2), rangey = (int)(Core.camera.viewportHeight/tilesize/2);
|
int rangex = (int) (Core.camera.viewportWidth / tilesize / 2), rangey = (int) (Core.camera.viewportHeight / tilesize / 2);
|
||||||
|
|
||||||
for(int x = -rangex; x <= rangex; x++) {
|
for(int x = -rangex; x <= rangex; x++){
|
||||||
for (int y = -rangey; y <= rangey; y++) {
|
for(int y = -rangey; y <= rangey; y++){
|
||||||
int worldx = Mathf.scl(camera.position.x, tilesize) + x;
|
int worldx = Mathf.scl(camera.position.x, tilesize) + x;
|
||||||
int worldy = Mathf.scl(camera.position.y, tilesize) + y;
|
int worldy = Mathf.scl(camera.position.y, tilesize) + y;
|
||||||
|
|
||||||
@@ -427,7 +427,7 @@ public class Renderer extends RendererModule{
|
|||||||
float value = world.pathfinder().getDebugValue(worldx, worldy);
|
float value = world.pathfinder().getDebugValue(worldx, worldy);
|
||||||
Draw.color(Color.PURPLE);
|
Draw.color(Color.PURPLE);
|
||||||
Draw.alpha((value % 10f) / 10f);
|
Draw.alpha((value % 10f) / 10f);
|
||||||
Lines.square(worldx * tilesize, worldy*tilesize, 4f);
|
Lines.square(worldx * tilesize, worldy * tilesize, 4f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -440,8 +440,8 @@ public class Renderer extends RendererModule{
|
|||||||
for(Tile tile : world.indexer().getEnemy(Team.blue, flag)){
|
for(Tile tile : world.indexer().getEnemy(Team.blue, flag)){
|
||||||
int index = seen.getAndIncrement(tile, 0, 1);
|
int index = seen.getAndIncrement(tile, 0, 1);
|
||||||
Draw.tscl(0.125f);
|
Draw.tscl(0.125f);
|
||||||
Draw.text(flag.name(), tile.drawx(), tile.drawy() + tile.block().size * tilesize/2f + 4 + index * 3);
|
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);
|
Lines.square(tile.drawx(), tile.drawy(), tile.block().size * tilesize / 2f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Draw.tscl(fontScale);
|
Draw.tscl(fontScale);
|
||||||
@@ -450,7 +450,7 @@ public class Renderer extends RendererModule{
|
|||||||
Draw.color();
|
Draw.color();
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockRenderer getBlocks() {
|
public BlockRenderer getBlocks(){
|
||||||
return blocks;
|
return blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -469,7 +469,7 @@ public class Renderer extends RendererModule{
|
|||||||
|
|
||||||
public void clampScale(){
|
public void clampScale(){
|
||||||
float s = io.anuke.ucore.scene.ui.layout.Unit.dp.scl(1f);
|
float s = io.anuke.ucore.scene.ui.layout.Unit.dp.scl(1f);
|
||||||
targetscale = Mathf.clamp(targetscale, Math.round(s*2), Math.round(s*5));
|
targetscale = Mathf.clamp(targetscale, Math.round(s * 2), Math.round(s * 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,30 +9,29 @@ import io.anuke.ucore.util.Log;
|
|||||||
import static io.anuke.mindustry.Vars.control;
|
import static io.anuke.mindustry.Vars.control;
|
||||||
import static io.anuke.mindustry.Vars.logic;
|
import static io.anuke.mindustry.Vars.logic;
|
||||||
|
|
||||||
public class ThreadHandler {
|
public class ThreadHandler{
|
||||||
private final Queue<Runnable> toRun = new Queue<>();
|
private final Queue<Runnable> toRun = new Queue<>();
|
||||||
private final ThreadProvider impl;
|
private final ThreadProvider impl;
|
||||||
|
private final Object updateLock = new Object();
|
||||||
private float delta = 1f;
|
private float delta = 1f;
|
||||||
private float smoothDelta = 1f;
|
private float smoothDelta = 1f;
|
||||||
private long frame = 0, lastDeltaUpdate;
|
private long frame = 0, lastDeltaUpdate;
|
||||||
private float framesSinceUpdate;
|
private float framesSinceUpdate;
|
||||||
private boolean enabled;
|
private boolean enabled;
|
||||||
|
|
||||||
private final Object updateLock = new Object();
|
|
||||||
private boolean rendered = true;
|
private boolean rendered = true;
|
||||||
|
|
||||||
public ThreadHandler(ThreadProvider impl){
|
public ThreadHandler(ThreadProvider impl){
|
||||||
this.impl = impl;
|
this.impl = impl;
|
||||||
|
|
||||||
Timers.setDeltaProvider(() -> {
|
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);
|
return Math.min(Float.isNaN(result) ? 1f : result, 15f);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run(Runnable r){
|
public void run(Runnable r){
|
||||||
if(enabled) {
|
if(enabled){
|
||||||
synchronized (toRun) {
|
synchronized(toRun){
|
||||||
toRun.addLast(r);
|
toRun.addLast(r);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
@@ -41,7 +40,7 @@ public class ThreadHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void runGraphics(Runnable r){
|
public void runGraphics(Runnable r){
|
||||||
if(enabled) {
|
if(enabled){
|
||||||
Gdx.app.postRunnable(r);
|
Gdx.app.postRunnable(r);
|
||||||
}else{
|
}else{
|
||||||
r.run();
|
r.run();
|
||||||
@@ -49,8 +48,8 @@ public class ThreadHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void runDelay(Runnable r){
|
public void runDelay(Runnable r){
|
||||||
if(enabled) {
|
if(enabled){
|
||||||
synchronized (toRun) {
|
synchronized(toRun){
|
||||||
toRun.addLast(r);
|
toRun.addLast(r);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
@@ -59,7 +58,7 @@ public class ThreadHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getTPS(){
|
public int getTPS(){
|
||||||
return (int)(60/smoothDelta);
|
return (int) (60 / smoothDelta);
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getFrameID(){
|
public long getFrameID(){
|
||||||
@@ -76,12 +75,16 @@ public class ThreadHandler {
|
|||||||
|
|
||||||
framesSinceUpdate += Timers.delta();
|
framesSinceUpdate += Timers.delta();
|
||||||
|
|
||||||
synchronized (updateLock) {
|
synchronized(updateLock){
|
||||||
rendered = true;
|
rendered = true;
|
||||||
impl.notify(updateLock);
|
impl.notify(updateLock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isEnabled(){
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
public void setEnabled(boolean enabled){
|
public void setEnabled(boolean enabled){
|
||||||
if(enabled){
|
if(enabled){
|
||||||
logic.doUpdate = false;
|
logic.doUpdate = false;
|
||||||
@@ -98,10 +101,6 @@ public class ThreadHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEnabled(){
|
|
||||||
return enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean doInterpolate(){
|
public boolean doInterpolate(){
|
||||||
return enabled && Gdx.graphics.getFramesPerSecond() - getTPS() > 20 && getTPS() < 30;
|
return enabled && Gdx.graphics.getFramesPerSecond() - getTPS() > 20 && getTPS() < 30;
|
||||||
}
|
}
|
||||||
@@ -111,13 +110,13 @@ public class ThreadHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void runLogic(){
|
private void runLogic(){
|
||||||
try {
|
try{
|
||||||
while (true) {
|
while(true){
|
||||||
long time = TimeUtils.nanoTime();
|
long time = TimeUtils.nanoTime();
|
||||||
|
|
||||||
while(true){
|
while(true){
|
||||||
Runnable r;
|
Runnable r;
|
||||||
synchronized (toRun){
|
synchronized(toRun){
|
||||||
if(toRun.size > 0){
|
if(toRun.size > 0){
|
||||||
r = toRun.removeFirst();
|
r = toRun.removeFirst();
|
||||||
}else{
|
}else{
|
||||||
@@ -135,12 +134,12 @@ public class ThreadHandler {
|
|||||||
long elapsed = TimeUtils.nanosToMillis(TimeUtils.timeSinceNanos(time));
|
long elapsed = TimeUtils.nanosToMillis(TimeUtils.timeSinceNanos(time));
|
||||||
long target = (long) ((1000) / 60f);
|
long target = (long) ((1000) / 60f);
|
||||||
|
|
||||||
if (elapsed < target) {
|
if(elapsed < target){
|
||||||
impl.sleep(target - elapsed);
|
impl.sleep(target - elapsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized(updateLock) {
|
synchronized(updateLock){
|
||||||
while(!rendered) {
|
while(!rendered){
|
||||||
impl.wait(updateLock);
|
impl.wait(updateLock);
|
||||||
}
|
}
|
||||||
rendered = false;
|
rendered = false;
|
||||||
@@ -154,22 +153,27 @@ public class ThreadHandler {
|
|||||||
smoothDelta = delta;
|
smoothDelta = delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
frame ++;
|
frame++;
|
||||||
framesSinceUpdate = 0;
|
framesSinceUpdate = 0;
|
||||||
}
|
}
|
||||||
} catch (InterruptedException ex) {
|
}catch(InterruptedException ex){
|
||||||
Log.info("Stopping logic thread.");
|
Log.info("Stopping logic thread.");
|
||||||
} catch (Throwable ex) {
|
}catch(Throwable ex){
|
||||||
control.setError(ex);
|
control.setError(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface ThreadProvider {
|
public interface ThreadProvider{
|
||||||
boolean isOnThread();
|
boolean isOnThread();
|
||||||
|
|
||||||
void sleep(long ms) throws InterruptedException;
|
void sleep(long ms) throws InterruptedException;
|
||||||
|
|
||||||
void start(Runnable run);
|
void start(Runnable run);
|
||||||
|
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
void wait(Object object) throws InterruptedException;
|
void wait(Object object) throws InterruptedException;
|
||||||
|
|
||||||
void notify(Object object);
|
void notify(Object object);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,14 @@ import static io.anuke.mindustry.Vars.players;
|
|||||||
import static io.anuke.ucore.scene.actions.Actions.*;
|
import static io.anuke.ucore.scene.actions.Actions.*;
|
||||||
|
|
||||||
public class UI extends SceneModule{
|
public class UI extends SceneModule{
|
||||||
|
public final MenuFragment menufrag = new MenuFragment();
|
||||||
|
public final HudFragment hudfrag = new HudFragment();
|
||||||
|
public final ChatFragment chatfrag = new ChatFragment();
|
||||||
|
public final PlayerListFragment listfrag = new PlayerListFragment();
|
||||||
|
public final BackgroundFragment backfrag = new BackgroundFragment();
|
||||||
|
public final LoadingFragment loadfrag = new LoadingFragment();
|
||||||
|
public final DebugFragment debugfrag = new DebugFragment();
|
||||||
|
|
||||||
public AboutDialog about;
|
public AboutDialog about;
|
||||||
public RestartDialog restart;
|
public RestartDialog restart;
|
||||||
public LevelDialog levels;
|
public LevelDialog levels;
|
||||||
@@ -59,21 +67,13 @@ public class UI extends SceneModule{
|
|||||||
public UnlocksDialog unlocks;
|
public UnlocksDialog unlocks;
|
||||||
public ContentInfoDialog content;
|
public ContentInfoDialog content;
|
||||||
|
|
||||||
public final MenuFragment menufrag = new MenuFragment();
|
|
||||||
public final HudFragment hudfrag = new HudFragment();
|
|
||||||
public final ChatFragment chatfrag = new ChatFragment();
|
|
||||||
public final PlayerListFragment listfrag = new PlayerListFragment();
|
|
||||||
public final BackgroundFragment backfrag = new BackgroundFragment();
|
|
||||||
public final LoadingFragment loadfrag = new LoadingFragment();
|
|
||||||
public final DebugFragment debugfrag = new DebugFragment();
|
|
||||||
|
|
||||||
private Locale lastLocale;
|
private Locale lastLocale;
|
||||||
|
|
||||||
public UI() {
|
public UI(){
|
||||||
Dialog.setShowAction(()-> sequence(
|
Dialog.setShowAction(() -> sequence(
|
||||||
alpha(0f),
|
alpha(0f),
|
||||||
originCenter(),
|
originCenter(),
|
||||||
moveToAligned(Gdx.graphics.getWidth()/2, Gdx.graphics.getHeight()/2, Align.center),
|
moveToAligned(Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() / 2, Align.center),
|
||||||
scaleTo(0.0f, 1f),
|
scaleTo(0.0f, 1f),
|
||||||
parallel(
|
parallel(
|
||||||
scaleTo(1f, 1f, 0.1f, Interpolation.fade),
|
scaleTo(1f, 1f, 0.1f, Interpolation.fade),
|
||||||
@@ -81,7 +81,7 @@ public class UI extends SceneModule{
|
|||||||
)
|
)
|
||||||
));
|
));
|
||||||
|
|
||||||
Dialog.setHideAction(()-> sequence(
|
Dialog.setHideAction(() -> sequence(
|
||||||
parallel(
|
parallel(
|
||||||
scaleTo(0.01f, 0.01f, 0.1f, Interpolation.fade),
|
scaleTo(0.01f, 0.01f, 0.1f, Interpolation.fade),
|
||||||
fadeOut(0.1f, Interpolation.fade)
|
fadeOut(0.1f, Interpolation.fade)
|
||||||
@@ -90,7 +90,7 @@ public class UI extends SceneModule{
|
|||||||
|
|
||||||
TooltipManager.getInstance().animations = false;
|
TooltipManager.getInstance().animations = false;
|
||||||
|
|
||||||
Settings.setErrorHandler(()-> Timers.run(1f, ()-> showError("[crimson]Failed to access local storage.\nSettings will not be saved.")));
|
Settings.setErrorHandler(() -> Timers.run(1f, () -> showError("[crimson]Failed to access local storage.\nSettings will not be saved.")));
|
||||||
|
|
||||||
Dialog.closePadR = -1;
|
Dialog.closePadR = -1;
|
||||||
Dialog.closePadT = 5;
|
Dialog.closePadT = 5;
|
||||||
@@ -134,15 +134,15 @@ public class UI extends SceneModule{
|
|||||||
|
|
||||||
Graphics.begin();
|
Graphics.begin();
|
||||||
|
|
||||||
for(int i = 0; i < players.length; i ++){
|
for(int i = 0; i < players.length; i++){
|
||||||
InputHandler input = control.input(i);
|
InputHandler input = control.input(i);
|
||||||
|
|
||||||
if(input.isCursorVisible()) {
|
if(input.isCursorVisible()){
|
||||||
Draw.color();
|
Draw.color();
|
||||||
|
|
||||||
float scl = Unit.dp.scl(3f);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,12 +190,12 @@ public class UI extends SceneModule{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasMouse() {
|
public boolean hasMouse(){
|
||||||
return super.hasMouse();
|
return super.hasMouse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resize(int width, int height) {
|
public void resize(int width, int height){
|
||||||
super.resize(width, height);
|
super.resize(width, height);
|
||||||
|
|
||||||
Events.fire(ResizeEvent.class);
|
Events.fire(ResizeEvent.class);
|
||||||
@@ -234,7 +234,8 @@ public class UI extends SceneModule{
|
|||||||
public void showTextInput(String title, String text, String def, TextFieldFilter filter, Consumer<String> confirmed){
|
public void showTextInput(String title, String text, String def, TextFieldFilter filter, Consumer<String> confirmed){
|
||||||
new Dialog(title, "dialog"){{
|
new Dialog(title, "dialog"){{
|
||||||
content().margin(30).add(text).padRight(6f);
|
content().margin(30).add(text).padRight(6f);
|
||||||
TextField field = content().addField(def, t->{}).size(170f, 50f).get();
|
TextField field = content().addField(def, t -> {
|
||||||
|
}).size(170f, 50f).get();
|
||||||
field.setTextFieldFilter((f, c) -> field.getText().length() < 12 && filter.acceptChar(f, c));
|
field.setTextFieldFilter((f, c) -> field.getText().length() < 12 && filter.acceptChar(f, c));
|
||||||
Platform.instance.addDialog(field);
|
Platform.instance.addDialog(field);
|
||||||
buttons().defaults().size(120, 54).pad(4);
|
buttons().defaults().size(120, 54).pad(4);
|
||||||
@@ -286,20 +287,4 @@ public class UI extends SceneModule{
|
|||||||
dialog.keyDown(Keys.BACK, dialog::hide);
|
dialog.keyDown(Keys.BACK, dialog::hide);
|
||||||
dialog.show();
|
dialog.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showConfirmListen(String title, String text, Consumer<Boolean> 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,10 @@ import io.anuke.mindustry.core.GameState.State;
|
|||||||
import io.anuke.mindustry.game.EventType.TileChangeEvent;
|
import io.anuke.mindustry.game.EventType.TileChangeEvent;
|
||||||
import io.anuke.mindustry.game.EventType.WorldLoadEvent;
|
import io.anuke.mindustry.game.EventType.WorldLoadEvent;
|
||||||
import io.anuke.mindustry.game.Team;
|
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.Block;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
import io.anuke.mindustry.world.mapgen.WorldGenerator;
|
import io.anuke.mindustry.world.mapgen.WorldGenerator;
|
||||||
@@ -51,7 +54,7 @@ public class World extends Module{
|
|||||||
return maps;
|
return maps;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockIndexer indexer() {
|
public BlockIndexer indexer(){
|
||||||
return indexer;
|
return indexer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,7 +62,7 @@ public class World extends Module{
|
|||||||
return pathfinder;
|
return pathfinder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInvalidMap() {
|
public boolean isInvalidMap(){
|
||||||
return invalidMap;
|
return invalidMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,7 +84,7 @@ public class World extends Module{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAccessible(int x, int y){
|
public boolean isAccessible(int x, int y){
|
||||||
return !wallSolid(x, y-1) || !wallSolid(x, y+1) || !wallSolid(x-1, y) ||!wallSolid(x+1, 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){
|
public boolean floorBlends(int x, int y, Block block){
|
||||||
@@ -93,6 +96,10 @@ public class World extends Module{
|
|||||||
return currentMap;
|
return currentMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setMap(Map map){
|
||||||
|
this.currentMap = map;
|
||||||
|
}
|
||||||
|
|
||||||
public int width(){
|
public int width(){
|
||||||
return tiles == null ? 0 : tiles.length;
|
return tiles == null ? 0 : tiles.length;
|
||||||
}
|
}
|
||||||
@@ -102,7 +109,7 @@ public class World extends Module{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int toPacked(int x, int y){
|
public int toPacked(int x, int y){
|
||||||
return x + y *width();
|
return x + y * width();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tile tile(int packed){
|
public Tile tile(int packed){
|
||||||
@@ -134,8 +141,8 @@ public class World extends Module{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void clearTileEntities(){
|
private void clearTileEntities(){
|
||||||
for(int x = 0; x < tiles.length; x ++){
|
for(int x = 0; x < tiles.length; x++){
|
||||||
for(int y = 0; y < tiles[0].length; y ++){
|
for(int y = 0; y < tiles[0].length; y++){
|
||||||
if(tiles[x][y] != null && tiles[x][y].entity != null){
|
if(tiles[x][y] != null && tiles[x][y].entity != null){
|
||||||
tiles[x][y].entity.remove();
|
tiles[x][y].entity.remove();
|
||||||
}
|
}
|
||||||
@@ -143,8 +150,10 @@ public class World extends Module{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Resizes the tile array to the specified size and returns the resulting tile array.
|
/**
|
||||||
* Only use for loading saves!*/
|
* 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){
|
public Tile[][] createTiles(int width, int height){
|
||||||
if(tiles != null){
|
if(tiles != null){
|
||||||
clearTileEntities();
|
clearTileEntities();
|
||||||
@@ -159,17 +168,21 @@ public class World extends Module{
|
|||||||
return tiles;
|
return tiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Call to signify the beginning of map loading.
|
/**
|
||||||
* TileChangeEvents will not be fired until endMapLoad().*/
|
* Call to signify the beginning of map loading.
|
||||||
|
* TileChangeEvents will not be fired until endMapLoad().
|
||||||
|
*/
|
||||||
public void beginMapLoad(){
|
public void beginMapLoad(){
|
||||||
generating = true;
|
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.*/
|
* 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(){
|
public void endMapLoad(){
|
||||||
for(int x = 0; x < tiles.length; x ++) {
|
for(int x = 0; x < tiles.length; x++){
|
||||||
for (int y = 0; y < tiles[0].length; y++) {
|
for(int y = 0; y < tiles[0].length; y++){
|
||||||
tiles[x][y].updateOcclusion();
|
tiles[x][y].updateOcclusion();
|
||||||
|
|
||||||
if(tiles[x][y].entity != null){
|
if(tiles[x][y].entity != null){
|
||||||
@@ -184,7 +197,9 @@ public class World extends Module{
|
|||||||
Events.fire(WorldLoadEvent.class);
|
Events.fire(WorldLoadEvent.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Loads up a procedural map. This does not call play(), but calls reset().*/
|
/**
|
||||||
|
* Loads up a procedural map. This does not call play(), but calls reset().
|
||||||
|
*/
|
||||||
public void loadProceduralMap(){
|
public void loadProceduralMap(){
|
||||||
Timers.mark();
|
Timers.mark();
|
||||||
Timers.mark();
|
Timers.mark();
|
||||||
@@ -213,10 +228,6 @@ public class World extends Module{
|
|||||||
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){
|
public void loadMap(Map map){
|
||||||
loadMap(map, MathUtils.random(0, 999999));
|
loadMap(map, MathUtils.random(0, 999999));
|
||||||
}
|
}
|
||||||
@@ -270,17 +281,17 @@ public class World extends Module{
|
|||||||
|
|
||||||
public void setBlock(Tile tile, Block block, Team team){
|
public void setBlock(Tile tile, Block block, Team team){
|
||||||
tile.setBlock(block);
|
tile.setBlock(block);
|
||||||
if (block.isMultiblock()) {
|
if(block.isMultiblock()){
|
||||||
int offsetx = -(block.size - 1) / 2;
|
int offsetx = -(block.size - 1) / 2;
|
||||||
int offsety = -(block.size - 1) / 2;
|
int offsety = -(block.size - 1) / 2;
|
||||||
|
|
||||||
for (int dx = 0; dx < block.size; dx++) {
|
for(int dx = 0; dx < block.size; dx++){
|
||||||
for (int dy = 0; dy < block.size; dy++) {
|
for(int dy = 0; dy < block.size; dy++){
|
||||||
int worldx = dx + offsetx + tile.x;
|
int worldx = dx + offsetx + tile.x;
|
||||||
int worldy = dy + offsety + tile.y;
|
int worldy = dy + offsety + tile.y;
|
||||||
if (!(worldx == tile.x && worldy == tile.y)) {
|
if(!(worldx == tile.x && worldy == tile.y)){
|
||||||
Tile toplace = world.tile(worldx, worldy);
|
Tile toplace = world.tile(worldx, worldy);
|
||||||
if (toplace != null) {
|
if(toplace != null){
|
||||||
toplace.setLinked((byte) (dx + offsetx), (byte) (dy + offsety));
|
toplace.setLinked((byte) (dx + offsetx), (byte) (dy + offsety));
|
||||||
toplace.setTeam(team);
|
toplace.setTeam(team);
|
||||||
}
|
}
|
||||||
@@ -290,14 +301,19 @@ public class World extends Module{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Raycast, but with world coordinates.*/
|
/**
|
||||||
|
* Raycast, but with world coordinates.
|
||||||
|
*/
|
||||||
public GridPoint2 raycastWorld(float x, float y, float x2, float y2){
|
public GridPoint2 raycastWorld(float x, float y, float x2, float y2){
|
||||||
return raycast(Mathf.scl2(x, tilesize), Mathf.scl2(y, tilesize),
|
return raycast(Mathf.scl2(x, tilesize), Mathf.scl2(y, tilesize),
|
||||||
Mathf.scl2(x2, tilesize), Mathf.scl2(y2, 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.*/
|
* 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){
|
public GridPoint2 raycast(int x0f, int y0f, int x1, int y1){
|
||||||
int x0 = x0f;
|
int x0 = x0f;
|
||||||
int y0 = y0f;
|
int y0 = y0f;
|
||||||
|
|||||||
@@ -7,11 +7,17 @@ import io.anuke.mindustry.io.MapTileData.TileDataMarker;
|
|||||||
import io.anuke.ucore.util.Bits;
|
import io.anuke.ucore.util.Bits;
|
||||||
|
|
||||||
public class DrawOperation{
|
public class DrawOperation{
|
||||||
/**Data to apply operation to.*/
|
/**
|
||||||
|
* Data to apply operation to.
|
||||||
|
*/
|
||||||
private MapTileData data;
|
private MapTileData data;
|
||||||
/**List of per-tile operations that occurred.*/
|
/**
|
||||||
|
* List of per-tile operations that occurred.
|
||||||
|
*/
|
||||||
private Array<TileOperation> operations = new Array<>();
|
private Array<TileOperation> operations = new Array<>();
|
||||||
/**Checks for duplicate operations, useful for brushes.*/
|
/**
|
||||||
|
* Checks for duplicate operations, useful for brushes.
|
||||||
|
*/
|
||||||
private IntSet checks = new IntSet();
|
private IntSet checks = new IntSet();
|
||||||
|
|
||||||
public DrawOperation(MapTileData data){
|
public DrawOperation(MapTileData data){
|
||||||
@@ -34,8 +40,8 @@ public class DrawOperation{
|
|||||||
operations.add(op);
|
operations.add(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void undo(MapEditor editor) {
|
public void undo(MapEditor editor){
|
||||||
for(int i = operations.size - 1; i >= 0; i --){
|
for(int i = operations.size - 1; i >= 0; i--){
|
||||||
TileOperation op = operations.get(i);
|
TileOperation op = operations.get(i);
|
||||||
data.position(op.x, op.y);
|
data.position(op.x, op.y);
|
||||||
data.write(op.from);
|
data.write(op.from);
|
||||||
@@ -43,7 +49,7 @@ public class DrawOperation{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void redo(MapEditor editor) {
|
public void redo(MapEditor editor){
|
||||||
for(TileOperation op : operations){
|
for(TileOperation op : operations){
|
||||||
data.position(op.x, op.y);
|
data.position(op.x, op.y);
|
||||||
data.write(op.to);
|
data.write(op.to);
|
||||||
@@ -56,7 +62,7 @@ public class DrawOperation{
|
|||||||
public TileDataMarker from;
|
public TileDataMarker from;
|
||||||
public TileDataMarker to;
|
public TileDataMarker to;
|
||||||
|
|
||||||
public TileOperation(short x, short y, TileDataMarker from, TileDataMarker to) {
|
public TileOperation(short x, short y, TileDataMarker from, TileDataMarker to){
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
this.from = from;
|
this.from = from;
|
||||||
|
|||||||
@@ -85,10 +85,10 @@ public enum EditorTool{
|
|||||||
byte bf = editor.getMap().read(x, y, DataPosition.floor);
|
byte bf = editor.getMap().read(x, y, DataPosition.floor);
|
||||||
byte bw = editor.getMap().read(x, y, DataPosition.wall);
|
byte bw = editor.getMap().read(x, y, DataPosition.wall);
|
||||||
boolean synth = editor.getDrawBlock().synthetic();
|
boolean synth = editor.getDrawBlock().synthetic();
|
||||||
byte brt = Bits.packByte((byte)editor.getDrawRotation(), (byte)editor.getDrawTeam().ordinal());
|
byte brt = Bits.packByte((byte) editor.getDrawRotation(), (byte) editor.getDrawTeam().ordinal());
|
||||||
|
|
||||||
byte dest = floor ? bf: bw;
|
byte dest = floor ? bf : bw;
|
||||||
byte draw = (byte)editor.getDrawBlock().id;
|
byte draw = (byte) editor.getDrawBlock().id;
|
||||||
|
|
||||||
int width = editor.getMap().width();
|
int width = editor.getMap().width();
|
||||||
int height = editor.getMap().height();
|
int height = editor.getMap().height();
|
||||||
@@ -109,9 +109,9 @@ public enum EditorTool{
|
|||||||
if((floor ? nbf : nbw) == dest){
|
if((floor ? nbf : nbw) == dest){
|
||||||
TileDataMarker prev = editor.getPrev(px, py, false);
|
TileDataMarker prev = editor.getPrev(px, py, false);
|
||||||
|
|
||||||
if(floor) {
|
if(floor){
|
||||||
editor.getMap().write(px, py, DataPosition.floor, draw);
|
editor.getMap().write(px, py, DataPosition.floor, draw);
|
||||||
}else {
|
}else{
|
||||||
editor.getMap().write(px, py, DataPosition.wall, draw);
|
editor.getMap().write(px, py, DataPosition.wall, draw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,7 +130,7 @@ public enum EditorTool{
|
|||||||
}
|
}
|
||||||
|
|
||||||
int asInt(int x, int y, int width){
|
int asInt(int x, int y, int width){
|
||||||
return x+y*width;
|
return x + y * width;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
zoom;
|
zoom;
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class MapEditor{
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObjectMap<String, String> getTags() {
|
public ObjectMap<String, String> getTags(){
|
||||||
return tags;
|
return tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,9 +44,9 @@ public class MapEditor{
|
|||||||
this.brushSize = 1;
|
this.brushSize = 1;
|
||||||
this.tags = tags;
|
this.tags = tags;
|
||||||
|
|
||||||
if(clear) {
|
if(clear){
|
||||||
for (int x = 0; x < map.width(); x++) {
|
for(int x = 0; x < map.width(); x++){
|
||||||
for (int y = 0; y < map.height(); y++) {
|
for(int y = 0; y < map.height(); y++){
|
||||||
map.write(x, y, DataPosition.floor, (byte) Blocks.stone.id);
|
map.write(x, y, DataPosition.floor, (byte) Blocks.stone.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -56,14 +56,14 @@ public class MapEditor{
|
|||||||
renderer.resize(map.width(), map.height());
|
renderer.resize(map.width(), map.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDrawElevation(int elevation){
|
|
||||||
this.elevation = (byte)elevation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte getDrawElevation(){
|
public byte getDrawElevation(){
|
||||||
return elevation;
|
return elevation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setDrawElevation(int elevation){
|
||||||
|
this.elevation = (byte) elevation;
|
||||||
|
}
|
||||||
|
|
||||||
public int getDrawRotation(){
|
public int getDrawRotation(){
|
||||||
return rotation;
|
return rotation;
|
||||||
}
|
}
|
||||||
@@ -72,12 +72,12 @@ public class MapEditor{
|
|||||||
this.rotation = rotation;
|
this.rotation = rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDrawTeam(Team team){
|
public Team getDrawTeam(){
|
||||||
this.drawTeam = team;
|
return drawTeam;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Team getDrawTeam() {
|
public void setDrawTeam(Team team){
|
||||||
return drawTeam;
|
this.drawTeam = team;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Block getDrawBlock(){
|
public Block getDrawBlock(){
|
||||||
@@ -88,12 +88,12 @@ public class MapEditor{
|
|||||||
this.drawBlock = block;
|
this.drawBlock = block;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBrushSize(int size){
|
public int getBrushSize(){
|
||||||
this.brushSize = size;
|
return brushSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getBrushSize() {
|
public void setBrushSize(int size){
|
||||||
return brushSize;
|
this.brushSize = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void draw(int x, int y){
|
public void draw(int x, int y){
|
||||||
@@ -105,27 +105,27 @@ public class MapEditor{
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte writeID = (byte)drawBlock.id;
|
byte writeID = (byte) drawBlock.id;
|
||||||
byte partID = (byte)Blocks.blockpart.id;
|
byte partID = (byte) Blocks.blockpart.id;
|
||||||
byte rotationTeam = Bits.packByte(drawBlock.rotate ? (byte)rotation : 0, drawBlock.synthetic() ? (byte)drawTeam.ordinal() : 0);
|
byte rotationTeam = Bits.packByte(drawBlock.rotate ? (byte) rotation : 0, drawBlock.synthetic() ? (byte) drawTeam.ordinal() : 0);
|
||||||
|
|
||||||
boolean isfloor = drawBlock instanceof Floor && drawBlock != Blocks.air;
|
boolean isfloor = drawBlock instanceof Floor && drawBlock != Blocks.air;
|
||||||
|
|
||||||
if(drawBlock.isMultiblock()) {
|
if(drawBlock.isMultiblock()){
|
||||||
|
|
||||||
int offsetx = -(drawBlock.size - 1) / 2;
|
int offsetx = -(drawBlock.size - 1) / 2;
|
||||||
int offsety = -(drawBlock.size - 1) / 2;
|
int offsety = -(drawBlock.size - 1) / 2;
|
||||||
|
|
||||||
for(int i = 0; i < 2; i ++){
|
for(int i = 0; i < 2; i++){
|
||||||
for (int dx = 0; dx < drawBlock.size; dx++) {
|
for(int dx = 0; dx < drawBlock.size; dx++){
|
||||||
for (int dy = 0; dy < drawBlock.size; dy++) {
|
for(int dy = 0; dy < drawBlock.size; dy++){
|
||||||
int worldx = dx + offsetx + x;
|
int worldx = dx + offsetx + x;
|
||||||
int worldy = dy + offsety + y;
|
int worldy = dy + offsety + y;
|
||||||
|
|
||||||
if (Mathf.inBounds(worldx, worldy, map.width(), map.height())) {
|
if(Mathf.inBounds(worldx, worldy, map.width(), map.height())){
|
||||||
TileDataMarker prev = getPrev(worldx, worldy, false);
|
TileDataMarker prev = getPrev(worldx, worldy, false);
|
||||||
|
|
||||||
if(i == 1) {
|
if(i == 1){
|
||||||
map.write(worldx, worldy, DataPosition.wall, partID);
|
map.write(worldx, worldy, DataPosition.wall, partID);
|
||||||
map.write(worldx, worldy, DataPosition.rotationTeam, rotationTeam);
|
map.write(worldx, worldy, DataPosition.rotationTeam, rotationTeam);
|
||||||
map.write(worldx, worldy, DataPosition.link, Bits.packByte((byte) (dx + offsetx + 8), (byte) (dy + offsety + 8)));
|
map.write(worldx, worldy, DataPosition.link, Bits.packByte((byte) (dx + offsetx + 8), (byte) (dy + offsety + 8)));
|
||||||
@@ -133,7 +133,7 @@ public class MapEditor{
|
|||||||
byte link = map.read(worldx, worldy, DataPosition.link);
|
byte link = map.read(worldx, worldy, DataPosition.link);
|
||||||
byte block = map.read(worldx, worldy, DataPosition.wall);
|
byte block = map.read(worldx, worldy, DataPosition.wall);
|
||||||
|
|
||||||
if (link != 0) {
|
if(link != 0){
|
||||||
removeLinked(worldx - (Bits.getLeftByte(link) - 8), worldy - (Bits.getRightByte(link) - 8));
|
removeLinked(worldx - (Bits.getLeftByte(link) - 8), worldy - (Bits.getRightByte(link) - 8));
|
||||||
}else if(Block.getByID(block).isMultiblock()){
|
}else if(Block.getByID(block).isMultiblock()){
|
||||||
removeLinked(worldx, worldy);
|
removeLinked(worldx, worldy);
|
||||||
@@ -149,27 +149,27 @@ public class MapEditor{
|
|||||||
TileDataMarker prev = getPrev(x, y, false);
|
TileDataMarker prev = getPrev(x, y, false);
|
||||||
|
|
||||||
map.write(x, y, DataPosition.wall, writeID);
|
map.write(x, y, DataPosition.wall, writeID);
|
||||||
map.write(x, y, DataPosition.link, (byte)0);
|
map.write(x, y, DataPosition.link, (byte) 0);
|
||||||
map.write(x, y, DataPosition.rotationTeam, rotationTeam);
|
map.write(x, y, DataPosition.rotationTeam, rotationTeam);
|
||||||
|
|
||||||
onWrite(x, y, prev);
|
onWrite(x, y, prev);
|
||||||
}else{
|
}else{
|
||||||
|
|
||||||
for (int rx = -brushSize; rx <= brushSize; rx++) {
|
for(int rx = -brushSize; rx <= brushSize; rx++){
|
||||||
for (int ry = -brushSize; ry <= brushSize; ry++) {
|
for(int ry = -brushSize; ry <= brushSize; ry++){
|
||||||
if (Mathf.dst(rx, ry) <= brushSize - 0.5f) {
|
if(Mathf.dst(rx, ry) <= brushSize - 0.5f){
|
||||||
int wx = x + rx, wy = y + ry;
|
int wx = x + rx, wy = y + ry;
|
||||||
|
|
||||||
if (wx < 0 || wy < 0 || wx >= map.width() || wy >= map.height()) {
|
if(wx < 0 || wy < 0 || wx >= map.width() || wy >= map.height()){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
TileDataMarker prev = getPrev(wx, wy, true);
|
TileDataMarker prev = getPrev(wx, wy, true);
|
||||||
|
|
||||||
if(!isfloor) {
|
if(!isfloor){
|
||||||
byte link = map.read(wx, wy, DataPosition.link);
|
byte link = map.read(wx, wy, DataPosition.link);
|
||||||
|
|
||||||
if (link != 0) {
|
if(link != 0){
|
||||||
removeLinked(wx - (Bits.getLeftByte(link) - 8), wy - (Bits.getRightByte(link) - 8));
|
removeLinked(wx - (Bits.getLeftByte(link) - 8), wy - (Bits.getRightByte(link) - 8));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -179,7 +179,7 @@ public class MapEditor{
|
|||||||
map.write(wx, wy, DataPosition.elevation, elevation);
|
map.write(wx, wy, DataPosition.elevation, elevation);
|
||||||
}else{
|
}else{
|
||||||
map.write(wx, wy, DataPosition.wall, writeID);
|
map.write(wx, wy, DataPosition.wall, writeID);
|
||||||
map.write(wx, wy, DataPosition.link, (byte)0);
|
map.write(wx, wy, DataPosition.link, (byte) 0);
|
||||||
map.write(wx, wy, DataPosition.rotationTeam, rotationTeam);
|
map.write(wx, wy, DataPosition.rotationTeam, rotationTeam);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,12 +195,12 @@ public class MapEditor{
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int rx = -brushSize; rx <= brushSize; rx++) {
|
for(int rx = -brushSize; rx <= brushSize; rx++){
|
||||||
for (int ry = -brushSize; ry <= brushSize; ry++) {
|
for(int ry = -brushSize; ry <= brushSize; ry++){
|
||||||
if (Mathf.dst(rx, ry) <= brushSize - 0.5f) {
|
if(Mathf.dst(rx, ry) <= brushSize - 0.5f){
|
||||||
int wx = x + rx, wy = y + ry;
|
int wx = x + rx, wy = y + ry;
|
||||||
|
|
||||||
if (wx < 0 || wy < 0 || wx >= map.width() || wy >= map.height()) {
|
if(wx < 0 || wy < 0 || wx >= map.width() || wy >= map.height()){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,17 +217,17 @@ public class MapEditor{
|
|||||||
private void removeLinked(int x, int y){
|
private void removeLinked(int x, int y){
|
||||||
Block block = Block.getByID(map.read(x, y, DataPosition.wall));
|
Block block = Block.getByID(map.read(x, y, DataPosition.wall));
|
||||||
|
|
||||||
int offsetx = -(block.size-1)/2;
|
int offsetx = -(block.size - 1) / 2;
|
||||||
int offsety = -(block.size-1)/2;
|
int offsety = -(block.size - 1) / 2;
|
||||||
for(int dx = 0; dx < block.size; dx ++){
|
for(int dx = 0; dx < block.size; dx++){
|
||||||
for(int dy = 0; dy < block.size; dy ++){
|
for(int dy = 0; dy < block.size; dy++){
|
||||||
int worldx = x + dx + offsetx, worldy = y + dy + offsety;
|
int worldx = x + dx + offsetx, worldy = y + dy + offsety;
|
||||||
if(Mathf.inBounds(worldx, worldy, map.width(), map.height())){
|
if(Mathf.inBounds(worldx, worldy, map.width(), map.height())){
|
||||||
TileDataMarker prev = getPrev(worldx, worldy, false);
|
TileDataMarker prev = getPrev(worldx, worldy, false);
|
||||||
|
|
||||||
map.write(worldx, worldy, DataPosition.link, (byte)0);
|
map.write(worldx, worldy, DataPosition.link, (byte) 0);
|
||||||
map.write(worldx, worldy, DataPosition.rotationTeam, (byte)0);
|
map.write(worldx, worldy, DataPosition.rotationTeam, (byte) 0);
|
||||||
map.write(worldx, worldy, DataPosition.wall, (byte)0);
|
map.write(worldx, worldy, DataPosition.wall, (byte) 0);
|
||||||
|
|
||||||
onWrite(worldx, worldy, prev);
|
onWrite(worldx, worldy, prev);
|
||||||
}
|
}
|
||||||
@@ -264,15 +264,15 @@ public class MapEditor{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapRenderer renderer() {
|
public MapRenderer renderer(){
|
||||||
return renderer;
|
return renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resize(int width, int height){
|
public void resize(int width, int height){
|
||||||
map = new MapTileData(width, height);
|
map = new MapTileData(width, height);
|
||||||
for (int x = 0; x < map.width(); x++) {
|
for(int x = 0; x < map.width(); x++){
|
||||||
for (int y = 0; y < map.height(); y++) {
|
for(int y = 0; y < map.height(); y++){
|
||||||
map.write(x, y, DataPosition.floor, (byte)Blocks.stone.id);
|
map.write(x, y, DataPosition.floor, (byte) Blocks.stone.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
renderer.resize(width, height);
|
renderer.resize(width, height);
|
||||||
|
|||||||
@@ -71,13 +71,13 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
menu = new FloatingDialog("$text.menu");
|
menu = new FloatingDialog("$text.menu");
|
||||||
menu.addCloseButton();
|
menu.addCloseButton();
|
||||||
|
|
||||||
float isize = 16*2f;
|
float isize = 16 * 2f;
|
||||||
float swidth = 180f;
|
float swidth = 180f;
|
||||||
|
|
||||||
menu.content().table(t -> {
|
menu.content().table(t -> {
|
||||||
t.defaults().size(swidth, 60f).padBottom(5).padRight(5).padLeft(5);
|
t.defaults().size(swidth, 60f).padBottom(5).padRight(5).padLeft(5);
|
||||||
|
|
||||||
t.addImageTextButton("$text.editor.savemap", "icon-floppy-16", isize, this::save).size(swidth*2f + 10, 60f).colspan(2);
|
t.addImageTextButton("$text.editor.savemap", "icon-floppy-16", isize, this::save).size(swidth * 2f + 10, 60f).colspan(2);
|
||||||
|
|
||||||
t.row();
|
t.row();
|
||||||
|
|
||||||
@@ -95,8 +95,8 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
|
|
||||||
t.addImageTextButton("$text.editor.import", "icon-load-map", isize, () ->
|
t.addImageTextButton("$text.editor.import", "icon-load-map", isize, () ->
|
||||||
createDialog("$text.editor.import",
|
createDialog("$text.editor.import",
|
||||||
"$text.editor.importmap", "$text.editor.importmap.description", "icon-load-map", (Listenable)loadDialog::show,
|
"$text.editor.importmap", "$text.editor.importmap.description", "icon-load-map", (Listenable) loadDialog::show,
|
||||||
"$text.editor.importfile", "$text.editor.importfile.description", "icon-file", (Listenable)() -> {
|
"$text.editor.importfile", "$text.editor.importfile.description", "icon-file", (Listenable) () -> {
|
||||||
Platform.instance.showFileChooser("$text.loadimage", "Map Files", file -> {
|
Platform.instance.showFileChooser("$text.loadimage", "Map Files", file -> {
|
||||||
ui.loadAnd(() -> {
|
ui.loadAnd(() -> {
|
||||||
try{
|
try{
|
||||||
@@ -107,7 +107,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
|
|
||||||
editor.beginEdit(data, meta.tags, false);
|
editor.beginEdit(data, meta.tags, false);
|
||||||
view.clearStack();
|
view.clearStack();
|
||||||
}catch (Exception e){
|
}catch(Exception e){
|
||||||
ui.showError(Bundles.format("text.editor.errorimageload", Strings.parseException(e, false)));
|
ui.showError(Bundles.format("text.editor.errorimageload", Strings.parseException(e, false)));
|
||||||
Log.err(e);
|
Log.err(e);
|
||||||
}
|
}
|
||||||
@@ -135,30 +135,30 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
}*/));
|
}*/));
|
||||||
|
|
||||||
t.addImageTextButton("$text.editor.export", "icon-save-map", isize, () -> createDialog("$text.editor.export",
|
t.addImageTextButton("$text.editor.export", "icon-save-map", isize, () -> createDialog("$text.editor.export",
|
||||||
"$text.editor.exportfile", "$text.editor.exportfile.description", "icon-file", (Listenable)() -> {
|
"$text.editor.exportfile", "$text.editor.exportfile.description", "icon-file", (Listenable) () -> {
|
||||||
if(!gwt) {
|
if(!gwt){
|
||||||
Platform.instance.showFileChooser("$text.saveimage", "Map Files", file -> {
|
Platform.instance.showFileChooser("$text.saveimage", "Map Files", file -> {
|
||||||
file = file.parent().child(file.nameWithoutExtension() + "." + mapExtension);
|
file = file.parent().child(file.nameWithoutExtension() + "." + mapExtension);
|
||||||
FileHandle result = file;
|
FileHandle result = file;
|
||||||
ui.loadAnd(() -> {
|
ui.loadAnd(() -> {
|
||||||
|
|
||||||
try {
|
try{
|
||||||
if (!editor.getTags().containsKey("name")) {
|
if(!editor.getTags().containsKey("name")){
|
||||||
editor.getTags().put("name", result.nameWithoutExtension());
|
editor.getTags().put("name", result.nameWithoutExtension());
|
||||||
}
|
}
|
||||||
MapIO.writeMap(result.write(false), editor.getTags(), editor.getMap());
|
MapIO.writeMap(result.write(false), editor.getTags(), editor.getMap());
|
||||||
} catch (Exception e) {
|
}catch(Exception e){
|
||||||
ui.showError(Bundles.format("text.editor.errorimagesave", Strings.parseException(e, false)));
|
ui.showError(Bundles.format("text.editor.errorimagesave", Strings.parseException(e, false)));
|
||||||
Log.err(e);
|
Log.err(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, false, mapExtension);
|
}, false, mapExtension);
|
||||||
}else{
|
}else{
|
||||||
try {
|
try{
|
||||||
ByteArrayOutputStream ba = new ByteArrayOutputStream();
|
ByteArrayOutputStream ba = new ByteArrayOutputStream();
|
||||||
MapIO.writeMap(ba, editor.getTags(), editor.getMap());
|
MapIO.writeMap(ba, editor.getTags(), editor.getMap());
|
||||||
Platform.instance.downloadFile(editor.getTags().get("name", "unknown") + "." + mapExtension, ba.toByteArray());
|
Platform.instance.downloadFile(editor.getTags().get("name", "unknown") + "." + mapExtension, ba.toByteArray());
|
||||||
}catch (IOException e){
|
}catch(IOException e){
|
||||||
ui.showError(Bundles.format("text.editor.errorimagesave", Strings.parseException(e, false)));
|
ui.showError(Bundles.format("text.editor.errorimagesave", Strings.parseException(e, false)));
|
||||||
Log.err(e);
|
Log.err(e);
|
||||||
}
|
}
|
||||||
@@ -193,7 +193,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
menu.content().addImageTextButton("$text.quit", "icon-back", isize, () -> {
|
menu.content().addImageTextButton("$text.quit", "icon-back", isize, () -> {
|
||||||
tryExit();
|
tryExit();
|
||||||
menu.hide();
|
menu.hide();
|
||||||
}).padTop(-5).size(swidth*2f + 10, 60f);
|
}).padTop(-5).size(swidth * 2f + 10, 60f);
|
||||||
|
|
||||||
resizeDialog = new MapResizeDialog(editor, (x, y) -> {
|
resizeDialog = new MapResizeDialog(editor, (x, y) -> {
|
||||||
if(!(editor.getMap().width() == x && editor.getMap().height() == y)){
|
if(!(editor.getMap().width() == x && editor.getMap().height() == y)){
|
||||||
@@ -207,13 +207,13 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
loadDialog = new MapLoadDialog(map -> {
|
loadDialog = new MapLoadDialog(map -> {
|
||||||
|
|
||||||
ui.loadAnd(() -> {
|
ui.loadAnd(() -> {
|
||||||
try (DataInputStream stream = new DataInputStream(map.stream.get())){
|
try(DataInputStream stream = new DataInputStream(map.stream.get())){
|
||||||
MapMeta meta = MapIO.readMapMeta(stream);
|
MapMeta meta = MapIO.readMapMeta(stream);
|
||||||
MapTileData data = MapIO.readTileData(stream, meta, false);
|
MapTileData data = MapIO.readTileData(stream, meta, false);
|
||||||
|
|
||||||
editor.beginEdit(data, meta.tags, false);
|
editor.beginEdit(data, meta.tags, false);
|
||||||
view.clearStack();
|
view.clearStack();
|
||||||
}catch (IOException e){
|
}catch(IOException e){
|
||||||
ui.showError(Bundles.format("text.editor.errormapload", Strings.parseException(e, false)));
|
ui.showError(Bundles.format("text.editor.errormapload", Strings.parseException(e, false)));
|
||||||
Log.err(e);
|
Log.err(e);
|
||||||
}
|
}
|
||||||
@@ -229,7 +229,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
build.end();
|
build.end();
|
||||||
|
|
||||||
update(() -> {
|
update(() -> {
|
||||||
if(Core.scene.getKeyboardFocus() instanceof Dialog && Core.scene.getKeyboardFocus() != this) {
|
if(Core.scene.getKeyboardFocus() instanceof Dialog && Core.scene.getKeyboardFocus() != this){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,11 +284,13 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
saved = true;
|
saved = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Argument format:
|
/**
|
||||||
|
* Argument format:
|
||||||
* 0) button name
|
* 0) button name
|
||||||
* 1) description
|
* 1) description
|
||||||
* 2) icon name
|
* 2) icon name
|
||||||
* 3) listener */
|
* 3) listener
|
||||||
|
*/
|
||||||
private FloatingDialog createDialog(String title, Object... arguments){
|
private FloatingDialog createDialog(String title, Object... arguments){
|
||||||
FloatingDialog dialog = new FloatingDialog(title);
|
FloatingDialog dialog = new FloatingDialog(title);
|
||||||
|
|
||||||
@@ -297,10 +299,10 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
dialog.content().defaults().size(360f, h).padBottom(5).padRight(5).padLeft(5);
|
dialog.content().defaults().size(360f, h).padBottom(5).padRight(5).padLeft(5);
|
||||||
|
|
||||||
for(int i = 0; i < arguments.length; i += 4){
|
for(int i = 0; i < arguments.length; i += 4){
|
||||||
String name = (String)arguments[i];
|
String name = (String) arguments[i];
|
||||||
String description = (String)arguments[i + 1];
|
String description = (String) arguments[i + 1];
|
||||||
String iconname = (String)arguments[i + 2];
|
String iconname = (String) arguments[i + 2];
|
||||||
Listenable listenable = (Listenable)arguments[i + 3];
|
Listenable listenable = (Listenable) arguments[i + 3];
|
||||||
|
|
||||||
TextButton button = dialog.content().addButton(name, () -> {
|
TextButton button = dialog.content().addButton(name, () -> {
|
||||||
listenable.listen();
|
listenable.listen();
|
||||||
@@ -310,7 +312,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
|
|
||||||
button.clearChildren();
|
button.clearChildren();
|
||||||
button.table("button", t -> {
|
button.table("button", t -> {
|
||||||
t.addImage(iconname).size(16*3);
|
t.addImage(iconname).size(16 * 3);
|
||||||
t.update(() -> t.background(button.getClickListener().isOver() ? "button-over" : "button"));
|
t.update(() -> t.background(button.getClickListener().isOver() ? "button-over" : "button"));
|
||||||
}).padLeft(-10).padBottom(-3).size(h);
|
}).padLeft(-10).padBottom(-3).size(h);
|
||||||
button.table(t -> {
|
button.table(t -> {
|
||||||
@@ -342,21 +344,21 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
|
|
||||||
public void beginEditMap(InputStream is){
|
public void beginEditMap(InputStream is){
|
||||||
ui.loadAnd(() -> {
|
ui.loadAnd(() -> {
|
||||||
try {
|
try{
|
||||||
shownWithMap = true;
|
shownWithMap = true;
|
||||||
DataInputStream stream = new DataInputStream(is);
|
DataInputStream stream = new DataInputStream(is);
|
||||||
MapMeta meta = MapIO.readMapMeta(stream);
|
MapMeta meta = MapIO.readMapMeta(stream);
|
||||||
editor.beginEdit(MapIO.readTileData(stream, meta, false), meta.tags, false);
|
editor.beginEdit(MapIO.readTileData(stream, meta, false), meta.tags, false);
|
||||||
is.close();
|
is.close();
|
||||||
show();
|
show();
|
||||||
}catch (Exception e){
|
}catch(Exception e){
|
||||||
Log.err(e);
|
Log.err(e);
|
||||||
ui.showError(Bundles.format("text.editor.errorimageload", Strings.parseException(e, false)));
|
ui.showError(Bundles.format("text.editor.errorimageload", Strings.parseException(e, false)));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapView getView() {
|
public MapView getView(){
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,7 +368,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
|
|
||||||
public void updateSelectedBlock(){
|
public void updateSelectedBlock(){
|
||||||
Block block = editor.getDrawBlock();
|
Block block = editor.getDrawBlock();
|
||||||
for(int j = 0; j < Block.all().size; j ++){
|
for(int j = 0; j < Block.all().size; j++){
|
||||||
if(block.id == j && j < blockgroup.getButtons().size){
|
if(block.id == j && j < blockgroup.getButtons().size){
|
||||||
blockgroup.getButtons().get(j).setChecked(true);
|
blockgroup.getButtons().get(j).setChecked(true);
|
||||||
break;
|
break;
|
||||||
@@ -381,7 +383,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
public void build(){
|
public void build(){
|
||||||
float amount = 10f, baseSize = 60f;
|
float amount = 10f, baseSize = 60f;
|
||||||
|
|
||||||
float size = mobile ? (int)(Math.min(Gdx.graphics.getHeight(), Gdx.graphics.getWidth()) / amount / Unit.dp.scl(1f)) :
|
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);
|
Math.min(Gdx.graphics.getDisplayMode().height / amount, baseSize);
|
||||||
|
|
||||||
new table(){{
|
new table(){{
|
||||||
@@ -398,10 +400,10 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
Consumer<EditorTool> addTool = tool -> {
|
Consumer<EditorTool> addTool = tool -> {
|
||||||
ImageButton button = new ImageButton("icon-" + tool.name(), "toggle");
|
ImageButton button = new ImageButton("icon-" + tool.name(), "toggle");
|
||||||
button.clicked(() -> view.setTool(tool));
|
button.clicked(() -> view.setTool(tool));
|
||||||
button.resizeImage(16*2f);
|
button.resizeImage(16 * 2f);
|
||||||
button.update(() -> button.setChecked(view.getTool() == tool));
|
button.update(() -> button.setChecked(view.getTool() == tool));
|
||||||
group.add(button);
|
group.add(button);
|
||||||
if (tool == EditorTool.pencil)
|
if(tool == EditorTool.pencil)
|
||||||
button.setChecked(true);
|
button.setChecked(true);
|
||||||
|
|
||||||
tools.add(button).padBottom(-5.1f);
|
tools.add(button).padBottom(-5.1f);
|
||||||
@@ -411,16 +413,16 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
|
|
||||||
//tools.addImageButton("icon-back", 16*2, () -> tryExit());
|
//tools.addImageButton("icon-back", 16*2, () -> tryExit());
|
||||||
|
|
||||||
tools.addImageButton("icon-menu-large", 16*2f, menu::show);
|
tools.addImageButton("icon-menu-large", 16 * 2f, menu::show);
|
||||||
|
|
||||||
ImageButton grid = tools.addImageButton("icon-grid", "toggle", 16*2f, () -> view.setGrid(!view.isGrid())).get();
|
ImageButton grid = tools.addImageButton("icon-grid", "toggle", 16 * 2f, () -> view.setGrid(!view.isGrid())).get();
|
||||||
|
|
||||||
addTool.accept(EditorTool.zoom);
|
addTool.accept(EditorTool.zoom);
|
||||||
|
|
||||||
tools.row();
|
tools.row();
|
||||||
|
|
||||||
ImageButton undo = tools.addImageButton("icon-undo", 16*2f, () -> view.undo()).get();
|
ImageButton undo = tools.addImageButton("icon-undo", 16 * 2f, () -> view.undo()).get();
|
||||||
ImageButton redo = tools.addImageButton("icon-redo", 16*2f, () -> view.redo()).get();
|
ImageButton redo = tools.addImageButton("icon-redo", 16 * 2f, () -> view.redo()).get();
|
||||||
|
|
||||||
addTool.accept(EditorTool.pick);
|
addTool.accept(EditorTool.pick);
|
||||||
|
|
||||||
@@ -442,8 +444,8 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
addTool.accept(EditorTool.fill);
|
addTool.accept(EditorTool.fill);
|
||||||
addTool.accept(EditorTool.elevation);
|
addTool.accept(EditorTool.elevation);
|
||||||
|
|
||||||
ImageButton rotate = tools.addImageButton("icon-arrow-16", 16*2f, () -> editor.setDrawRotation((editor.getDrawRotation() + 1)%4)).get();
|
ImageButton rotate = tools.addImageButton("icon-arrow-16", 16 * 2f, () -> editor.setDrawRotation((editor.getDrawRotation() + 1) % 4)).get();
|
||||||
rotate.getImage().update(() ->{
|
rotate.getImage().update(() -> {
|
||||||
rotate.getImage().setRotation(editor.getDrawRotation() * 90);
|
rotate.getImage().setRotation(editor.getDrawRotation() * 90);
|
||||||
rotate.getImage().setOrigin(Align.center);
|
rotate.getImage().setOrigin(Align.center);
|
||||||
});
|
});
|
||||||
@@ -452,7 +454,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
|
|
||||||
tools.table("button", t -> {
|
tools.table("button", t -> {
|
||||||
t.add("$text.editor.teams");
|
t.add("$text.editor.teams");
|
||||||
}).colspan(3).height(40).width(size*3f);
|
}).colspan(3).height(40).width(size * 3f);
|
||||||
|
|
||||||
tools.row();
|
tools.row();
|
||||||
|
|
||||||
@@ -479,32 +481,32 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
|
|
||||||
new table("button"){{
|
new table("button"){{
|
||||||
atop();
|
atop();
|
||||||
Slider slider = new Slider(0, MapEditor.brushSizes.length-1, 1, false);
|
Slider slider = new Slider(0, MapEditor.brushSizes.length - 1, 1, false);
|
||||||
slider.moved(f -> editor.setBrushSize(MapEditor.brushSizes[(int)(float)f]));
|
slider.moved(f -> editor.setBrushSize(MapEditor.brushSizes[(int) (float) f]));
|
||||||
new label("brush");
|
new label("brush");
|
||||||
row();
|
row();
|
||||||
add(slider).width(size*3f-20).padTop(4f);
|
add(slider).width(size * 3f - 20).padTop(4f);
|
||||||
}}.padTop(5).growX().growY().top().end();
|
}}.padTop(5).growX().growY().top().end();
|
||||||
|
|
||||||
row();
|
row();
|
||||||
|
|
||||||
get().table("button", t -> {
|
get().table("button", t -> {
|
||||||
t.add("$text.editor.elevation");
|
t.add("$text.editor.elevation");
|
||||||
}).colspan(3).height(40).width(size*3f);
|
}).colspan(3).height(40).width(size * 3f);
|
||||||
|
|
||||||
row();
|
row();
|
||||||
|
|
||||||
get().table("button", t -> {
|
get().table("button", t -> {
|
||||||
t.margin(0);
|
t.margin(0);
|
||||||
t.addImageButton("icon-arrow-left", 16*2f, () -> editor.setDrawElevation(editor.getDrawElevation() - 1))
|
t.addImageButton("icon-arrow-left", 16 * 2f, () -> editor.setDrawElevation(editor.getDrawElevation() - 1))
|
||||||
.disabled(b -> editor.getDrawElevation() <= -1).size(size);
|
.disabled(b -> editor.getDrawElevation() <= -1).size(size);
|
||||||
|
|
||||||
t.label(() -> editor.getDrawElevation() == -1 ? "$text.editor.slope" : (editor.getDrawElevation() + ""))
|
t.label(() -> editor.getDrawElevation() == -1 ? "$text.editor.slope" : (editor.getDrawElevation() + ""))
|
||||||
.size(size).get().setAlignment(Align.center, Align.center);
|
.size(size).get().setAlignment(Align.center, Align.center);
|
||||||
|
|
||||||
t.addImageButton("icon-arrow-right", 16*2f, () -> editor.setDrawElevation(editor.getDrawElevation() + 1))
|
t.addImageButton("icon-arrow-right", 16 * 2f, () -> editor.setDrawElevation(editor.getDrawElevation() + 1))
|
||||||
.disabled(b -> editor.getDrawElevation() >= 127).size(size);
|
.disabled(b -> editor.getDrawElevation() >= 127).size(size);
|
||||||
}).colspan(3).height(size).padTop(-5).width(size*3f);
|
}).colspan(3).height(size).padTop(-5).width(size * 3f);
|
||||||
|
|
||||||
}}.left().growY().end();
|
}}.left().growY().end();
|
||||||
|
|
||||||
@@ -529,15 +531,15 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
|
|
||||||
private void doInput(){
|
private void doInput(){
|
||||||
//tool select
|
//tool select
|
||||||
for(int i = 0; i < EditorTool.values().length; i ++){
|
for(int i = 0; i < EditorTool.values().length; i++){
|
||||||
if(Inputs.keyTap(Input.valueOf("NUM_" + (i+1)))){
|
if(Inputs.keyTap(Input.valueOf("NUM_" + (i + 1)))){
|
||||||
view.setTool(EditorTool.values()[i]);
|
view.setTool(EditorTool.values()[i]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Inputs.keyTap(Input.R)){
|
if(Inputs.keyTap(Input.R)){
|
||||||
editor.setDrawRotation((editor.getDrawRotation() + 1)%4);
|
editor.setDrawRotation((editor.getDrawRotation() + 1) % 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Inputs.keyTap(Input.E)){
|
if(Inputs.keyTap(Input.E)){
|
||||||
@@ -584,7 +586,8 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
|
|
||||||
for(Block block : Block.all()){
|
for(Block block : Block.all()){
|
||||||
TextureRegion[] regions = block.getCompactIcon();
|
TextureRegion[] regions = block.getCompactIcon();
|
||||||
if((block.synthetic() && (Recipe.getByResult(block) == null || !control.database().isUnlocked(Recipe.getByResult(block)))) && !debug && block != StorageBlocks.core) continue;
|
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;
|
if(regions.length == 0 || regions[0] == Draw.region("jjfgj")) continue;
|
||||||
|
|
||||||
@@ -596,7 +599,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
|
|
||||||
ImageButton button = new ImageButton("white", "toggle");
|
ImageButton button = new ImageButton("white", "toggle");
|
||||||
button.clicked(() -> editor.setDrawBlock(block));
|
button.clicked(() -> editor.setDrawBlock(block));
|
||||||
button.resizeImage(8*4f);
|
button.resizeImage(8 * 4f);
|
||||||
button.getImageCell().setActor(stack);
|
button.getImageCell().setActor(stack);
|
||||||
button.addChild(stack);
|
button.addChild(stack);
|
||||||
button.getImage().remove();
|
button.getImage().remove();
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import static io.anuke.mindustry.Vars.world;
|
|||||||
public class MapLoadDialog extends FloatingDialog{
|
public class MapLoadDialog extends FloatingDialog{
|
||||||
private Map selected = null;
|
private Map selected = null;
|
||||||
|
|
||||||
public MapLoadDialog(Consumer<Map> loader) {
|
public MapLoadDialog(Consumer<Map> loader){
|
||||||
super("$text.editor.loadmap");
|
super("$text.editor.loadmap");
|
||||||
|
|
||||||
shown(this::rebuild);
|
shown(this::rebuild);
|
||||||
@@ -25,7 +25,7 @@ public class MapLoadDialog extends FloatingDialog{
|
|||||||
TextButton button = new TextButton("$text.load");
|
TextButton button = new TextButton("$text.load");
|
||||||
button.setDisabled(() -> selected == null);
|
button.setDisabled(() -> selected == null);
|
||||||
button.clicked(() -> {
|
button.clicked(() -> {
|
||||||
if (selected != null) {
|
if(selected != null){
|
||||||
loader.accept(selected);
|
loader.accept(selected);
|
||||||
hide();
|
hide();
|
||||||
}
|
}
|
||||||
@@ -55,7 +55,7 @@ public class MapLoadDialog extends FloatingDialog{
|
|||||||
ScrollPane pane = new ScrollPane(table, "horizontal");
|
ScrollPane pane = new ScrollPane(table, "horizontal");
|
||||||
pane.setFadeScrollBars(false);
|
pane.setFadeScrollBars(false);
|
||||||
|
|
||||||
for (Map map : world.maps().all()) {
|
for(Map map : world.maps().all()){
|
||||||
|
|
||||||
TextButton button = new TextButton(map.getDisplayName(), "toggle");
|
TextButton button = new TextButton(map.getDisplayName(), "toggle");
|
||||||
button.add(new BorderImage(map.texture, 2f)).size(16 * 4f);
|
button.add(new BorderImage(map.texture, 2f)).size(16 * 4f);
|
||||||
@@ -64,13 +64,13 @@ public class MapLoadDialog extends FloatingDialog{
|
|||||||
button.getLabelCell().grow().left().padLeft(5f);
|
button.getLabelCell().grow().left().padLeft(5f);
|
||||||
group.add(button);
|
group.add(button);
|
||||||
table.add(button);
|
table.add(button);
|
||||||
if (++i % maxcol == 0) table.row();
|
if(++i % maxcol == 0) table.row();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(world.maps().all().size == 0){
|
if(world.maps().all().size == 0){
|
||||||
pane.setStyle(Core.skin.get("clear", ScrollPaneStyle.class));
|
pane.setStyle(Core.skin.get("clear", ScrollPaneStyle.class));
|
||||||
table.add("$text.maps.none").center();
|
table.add("$text.maps.none").center();
|
||||||
}else {
|
}else{
|
||||||
content().add("$text.editor.loadmap");
|
content().add("$text.editor.loadmap");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,18 +34,18 @@ public class MapRenderer implements Disposable{
|
|||||||
|
|
||||||
public void resize(int width, int height){
|
public void resize(int width, int height){
|
||||||
if(chunks != null){
|
if(chunks != null){
|
||||||
for(int x = 0; x < chunks.length; x ++){
|
for(int x = 0; x < chunks.length; x++){
|
||||||
for(int y = 0; y < chunks[0].length; y ++){
|
for(int y = 0; y < chunks[0].length; y++){
|
||||||
chunks[x][y].dispose();
|
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 x = 0; x < chunks.length; x++){
|
||||||
for(int y = 0; y < chunks[0].length; y ++){
|
for(int y = 0; y < chunks[0].length; y++){
|
||||||
chunks[x][y] = new IndexedRenderer(chunksize*chunksize*2);
|
chunks[x][y] = new IndexedRenderer(chunksize * chunksize * 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.width = width;
|
this.width = width;
|
||||||
@@ -69,8 +69,8 @@ public class MapRenderer implements Disposable{
|
|||||||
updates.addAll(delayedUpdates);
|
updates.addAll(delayedUpdates);
|
||||||
delayedUpdates.clear();
|
delayedUpdates.clear();
|
||||||
|
|
||||||
for(int x = 0; x < chunks.length; x ++){
|
for(int x = 0; x < chunks.length; x++){
|
||||||
for(int y = 0; y < chunks[0].length; y ++){
|
for(int y = 0; y < chunks[0].length; y++){
|
||||||
IndexedRenderer mesh = chunks[x][y];
|
IndexedRenderer mesh = chunks[x][y];
|
||||||
|
|
||||||
mesh.getTransformMatrix().setToTranslation(tx, ty, 0).scl(tw / (width * tilesize),
|
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){
|
public void updatePoint(int x, int y){
|
||||||
//TODO spread out over multiple frames?
|
//TODO spread out over multiple frames?
|
||||||
updates.add(x + y*width);
|
updates.add(x + y * width);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateAll(){
|
public void updateAll(){
|
||||||
for(int x = 0; x < width; x ++){
|
for(int x = 0; x < width; x++){
|
||||||
for(int y = 0; y < height; y ++){
|
for(int y = 0; y < height; y++){
|
||||||
render(x, y);
|
render(x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void render(int wx, int wy){
|
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];
|
IndexedRenderer mesh = chunks[x][y];
|
||||||
//TileDataMarker data = editor.getMap().readAt(wx, wy);
|
//TileDataMarker data = editor.getMap().readAt(wx, wy);
|
||||||
byte bf = editor.getMap().read(wx, wy, DataPosition.floor);
|
byte bf = editor.getMap().read(wx, wy, DataPosition.floor);
|
||||||
@@ -111,19 +111,19 @@ public class MapRenderer implements Disposable{
|
|||||||
Block floor = Block.getByID(bf);
|
Block floor = Block.getByID(bf);
|
||||||
Block wall = Block.getByID(bw);
|
Block wall = Block.getByID(bw);
|
||||||
|
|
||||||
int offsetx = -(wall.size-1)/2;
|
int offsetx = -(wall.size - 1) / 2;
|
||||||
int offsety = -(wall.size-1)/2;
|
int offsety = -(wall.size - 1) / 2;
|
||||||
|
|
||||||
TextureRegion region;
|
TextureRegion region;
|
||||||
|
|
||||||
if(bw != 0) {
|
if(bw != 0){
|
||||||
region = wall.getEditorIcon();
|
region = wall.getEditorIcon();
|
||||||
|
|
||||||
if (wall.rotate) {
|
if(wall.rotate){
|
||||||
mesh.draw((wx % chunksize) + (wy % chunksize) * chunksize, region,
|
mesh.draw((wx % chunksize) + (wy % chunksize) * chunksize, region,
|
||||||
wx * tilesize + offsetx * tilesize, wy * tilesize + offsety * tilesize,
|
wx * tilesize + offsetx * tilesize, wy * tilesize + offsety * tilesize,
|
||||||
region.getRegionWidth(), region.getRegionHeight(), rotation * 90 - 90);
|
region.getRegionWidth(), region.getRegionHeight(), rotation * 90 - 90);
|
||||||
} else {
|
}else{
|
||||||
mesh.draw((wx % chunksize) + (wy % chunksize) * chunksize, region,
|
mesh.draw((wx % chunksize) + (wy % chunksize) * chunksize, region,
|
||||||
wx * tilesize + offsetx * tilesize, wy * tilesize + offsety * tilesize,
|
wx * tilesize + offsetx * tilesize, wy * tilesize + offsety * tilesize,
|
||||||
region.getRegionWidth(), region.getRegionHeight());
|
region.getRegionWidth(), region.getRegionHeight());
|
||||||
@@ -131,16 +131,16 @@ public class MapRenderer implements Disposable{
|
|||||||
}else{
|
}else{
|
||||||
region = floor.getEditorIcon();
|
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);
|
boolean check = checkElevation(elev, wx, wy);
|
||||||
|
|
||||||
if(wall.update || wall.destructible) {
|
if(wall.update || wall.destructible){
|
||||||
mesh.setColor(team.color);
|
mesh.setColor(team.color);
|
||||||
region = Draw.region("block-border");
|
region = Draw.region("block-border");
|
||||||
}else if(elev > 0 && check){
|
}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");
|
region = Draw.region("block-elevation");
|
||||||
}else if(elev == -1){
|
}else if(elev == -1){
|
||||||
region = Draw.region("block-slope");
|
region = Draw.region("block-slope");
|
||||||
@@ -148,8 +148,8 @@ public class MapRenderer implements Disposable{
|
|||||||
region = Draw.region("clear");
|
region = Draw.region("clear");
|
||||||
}
|
}
|
||||||
|
|
||||||
mesh.draw((wx % chunksize) + (wy % chunksize)*chunksize + chunksize*chunksize, region,
|
mesh.draw((wx % chunksize) + (wy % chunksize) * chunksize + chunksize * chunksize, region,
|
||||||
wx * tilesize + offsetx*tilesize, wy * tilesize + offsety * tilesize,
|
wx * tilesize + offsetx * tilesize, wy * tilesize + offsety * tilesize,
|
||||||
region.getRegionWidth(), region.getRegionHeight());
|
region.getRegionWidth(), region.getRegionHeight());
|
||||||
mesh.setColor(Color.WHITE);
|
mesh.setColor(Color.WHITE);
|
||||||
}
|
}
|
||||||
@@ -165,19 +165,19 @@ public class MapRenderer implements Disposable{
|
|||||||
if(value < elev){
|
if(value < elev){
|
||||||
return true;
|
return true;
|
||||||
}else if(value > elev){
|
}else if(value > elev){
|
||||||
delayedUpdates.add(wx + wy*width);
|
delayedUpdates.add(wx + wy * width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose(){
|
||||||
if(chunks == null){
|
if(chunks == null){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for(int x = 0; x < chunks.length; x ++){
|
for(int x = 0; x < chunks.length; x++){
|
||||||
for(int y = 0; y < chunks[0].length; y ++){
|
for(int y = 0; y < chunks[0].length; y++){
|
||||||
if(chunks[x][y] != null){
|
if(chunks[x][y] != null){
|
||||||
chunks[x][y].dispose();
|
chunks[x][y].dispose();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,13 +25,13 @@ public class MapResizeDialog extends FloatingDialog{
|
|||||||
for(boolean w : Mathf.booleans){
|
for(boolean w : Mathf.booleans){
|
||||||
int curr = w ? data.width() : data.height();
|
int curr = w ? data.width() : data.height();
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
for(int i = 0; i < validMapSizes.length; i ++) {
|
for(int i = 0; i < validMapSizes.length; i++){
|
||||||
if (validMapSizes[i] == curr) idx = i;
|
if(validMapSizes[i] == curr) idx = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.add(w ? "$text.width": "$text.height").padRight(8f);
|
table.add(w ? "$text.width" : "$text.height").padRight(8f);
|
||||||
ButtonGroup<TextButton> group = new ButtonGroup<>();
|
ButtonGroup<TextButton> group = new ButtonGroup<>();
|
||||||
for(int i = 0; i < validMapSizes.length; i ++){
|
for(int i = 0; i < validMapSizes.length; i++){
|
||||||
int size = validMapSizes[i];
|
int size = validMapSizes[i];
|
||||||
TextButton button = new TextButton(size + "", "toggle");
|
TextButton button = new TextButton(size + "", "toggle");
|
||||||
button.clicked(() -> {
|
button.clicked(() -> {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package io.anuke.mindustry.editor;
|
package io.anuke.mindustry.editor;
|
||||||
|
|
||||||
import io.anuke.mindustry.io.Map;
|
|
||||||
import io.anuke.mindustry.core.Platform;
|
import io.anuke.mindustry.core.Platform;
|
||||||
|
import io.anuke.mindustry.io.Map;
|
||||||
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
|
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
|
||||||
import io.anuke.ucore.function.Consumer;
|
import io.anuke.ucore.function.Consumer;
|
||||||
import io.anuke.ucore.scene.ui.TextButton;
|
import io.anuke.ucore.scene.ui.TextButton;
|
||||||
@@ -23,7 +23,7 @@ public class MapSaveDialog extends FloatingDialog{
|
|||||||
|
|
||||||
shown(() -> {
|
shown(() -> {
|
||||||
content().clear();
|
content().clear();
|
||||||
content().label(() ->{
|
content().label(() -> {
|
||||||
Map map = world.maps().getByName(field.getText());
|
Map map = world.maps().getByName(field.getText());
|
||||||
if(map != null){
|
if(map != null){
|
||||||
if(map.custom){
|
if(map.custom){
|
||||||
|
|||||||
@@ -53,55 +53,10 @@ public class MapView extends Element implements GestureListener{
|
|||||||
private float mousex, mousey;
|
private float mousex, mousey;
|
||||||
private EditorTool lastTool;
|
private EditorTool lastTool;
|
||||||
|
|
||||||
public void setTool(EditorTool tool){
|
|
||||||
this.tool = tool;
|
|
||||||
}
|
|
||||||
|
|
||||||
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){
|
public MapView(MapEditor editor){
|
||||||
this.editor = 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];
|
float size = MapEditor.brushSizes[i];
|
||||||
brushPolygons[i] = Geometry.pixelCircle(size, (index, x, y) -> Vector2.dst(x, y, index, index) <= index - 0.5f);
|
brushPolygons[i] = Geometry.pixelCircle(size, (index, x, y) -> Vector2.dst(x, y, index, index) <= index - 0.5f);
|
||||||
}
|
}
|
||||||
@@ -112,7 +67,7 @@ public class MapView extends Element implements GestureListener{
|
|||||||
addListener(new InputListener(){
|
addListener(new InputListener(){
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean mouseMoved (InputEvent event, float x, float y) {
|
public boolean mouseMoved(InputEvent event, float x, float y){
|
||||||
mousex = x;
|
mousex = x;
|
||||||
mousey = y;
|
mousey = y;
|
||||||
|
|
||||||
@@ -120,7 +75,7 @@ public class MapView extends Element implements GestureListener{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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(pointer != 0){
|
if(pointer != 0){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -158,7 +113,7 @@ public class MapView extends Element implements GestureListener{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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){
|
||||||
if(!mobile && button != Buttons.LEFT && button != Buttons.MIDDLE){
|
if(!mobile && button != Buttons.LEFT && button != Buttons.MIDDLE){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -191,7 +146,7 @@ public class MapView extends Element implements GestureListener{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void touchDragged (InputEvent event, float x, float y, int pointer) {
|
public void touchDragged(InputEvent event, float x, float y, int pointer){
|
||||||
mousex = x;
|
mousex = x;
|
||||||
mousey = y;
|
mousey = y;
|
||||||
|
|
||||||
@@ -211,12 +166,57 @@ public class MapView extends Element implements GestureListener{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EditorTool getTool(){
|
||||||
|
return tool;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTool(EditorTool tool){
|
||||||
|
this.tool = tool;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
@Override
|
||||||
public void act(float delta){
|
public void act(float delta){
|
||||||
super.act(delta);
|
super.act(delta);
|
||||||
|
|
||||||
if(Core.scene.getKeyboardFocus() == null || !(Core.scene.getKeyboardFocus() instanceof TextField) &&
|
if(Core.scene.getKeyboardFocus() == null || !(Core.scene.getKeyboardFocus() instanceof TextField) &&
|
||||||
!Inputs.keyDown(io.anuke.ucore.input.Input.CONTROL_LEFT)) {
|
!Inputs.keyDown(io.anuke.ucore.input.Input.CONTROL_LEFT)){
|
||||||
float ax = Inputs.getAxis("move_x");
|
float ax = Inputs.getAxis("move_x");
|
||||||
float ay = Inputs.getAxis("move_y");
|
float ay = Inputs.getAxis("move_y");
|
||||||
offsetx -= ax * 15f / zoom;
|
offsetx -= ax * 15f / zoom;
|
||||||
@@ -225,7 +225,7 @@ public class MapView extends Element implements GestureListener{
|
|||||||
|
|
||||||
if(ui.editor.hasPane()) return;
|
if(ui.editor.hasPane()) return;
|
||||||
|
|
||||||
zoom += Inputs.scroll()/10f * zoom;
|
zoom += Inputs.scroll() / 10f * zoom;
|
||||||
clampZoom();
|
clampZoom();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,39 +234,39 @@ public class MapView extends Element implements GestureListener{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private GridPoint2 project(float x, float y){
|
private GridPoint2 project(float x, float y){
|
||||||
float ratio = 1f / ((float)editor.getMap().width() / editor.getMap().height());
|
float ratio = 1f / ((float) editor.getMap().width() / editor.getMap().height());
|
||||||
float size = Math.min(width, height);
|
float size = Math.min(width, height);
|
||||||
float sclwidth = size * zoom;
|
float sclwidth = size * zoom;
|
||||||
float sclheight = size * zoom * ratio;
|
float sclheight = size * zoom * ratio;
|
||||||
x = (x - getWidth()/2 + sclwidth/2 - offsetx*zoom) / sclwidth * editor.getMap().width();
|
x = (x - getWidth() / 2 + sclwidth / 2 - offsetx * zoom) / sclwidth * editor.getMap().width();
|
||||||
y = (y - getHeight()/2 + sclheight/2 - offsety*zoom) / sclheight * editor.getMap().height();
|
y = (y - getHeight() / 2 + sclheight / 2 - offsety * zoom) / sclheight * editor.getMap().height();
|
||||||
|
|
||||||
if(editor.getDrawBlock().size % 2 == 0 && tool != EditorTool.eraser){
|
if(editor.getDrawBlock().size % 2 == 0 && tool != EditorTool.eraser){
|
||||||
return Tmp.g1.set((int)(x - 0.5f), (int)(y - 0.5f));
|
return Tmp.g1.set((int) (x - 0.5f), (int) (y - 0.5f));
|
||||||
}else{
|
}else{
|
||||||
return Tmp.g1.set((int)x, (int)y);
|
return Tmp.g1.set((int) x, (int) y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Vector2 unproject(int x, int y){
|
private Vector2 unproject(int x, int y){
|
||||||
float ratio = 1f / ((float)editor.getMap().width() / editor.getMap().height());
|
float ratio = 1f / ((float) editor.getMap().width() / editor.getMap().height());
|
||||||
float size = Math.min(width, height);
|
float size = Math.min(width, height);
|
||||||
float sclwidth = size * zoom;
|
float sclwidth = size * zoom;
|
||||||
float sclheight = size * zoom * ratio;
|
float sclheight = size * zoom * ratio;
|
||||||
float px = ((float)x / editor.getMap().width()) * sclwidth + offsetx*zoom - sclwidth/2 + getWidth()/2;
|
float px = ((float) x / editor.getMap().width()) * sclwidth + offsetx * zoom - sclwidth / 2 + getWidth() / 2;
|
||||||
float py = ((float)(y) / editor.getMap().height()) * sclheight
|
float py = ((float) (y) / editor.getMap().height()) * sclheight
|
||||||
+ offsety*zoom - sclheight/2 + getHeight()/2;
|
+ offsety * zoom - sclheight / 2 + getHeight() / 2;
|
||||||
return vec.set(px, py);
|
return vec.set(px, py);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(Batch batch, float alpha){
|
public void draw(Batch batch, float alpha){
|
||||||
float ratio = 1f / ((float)editor.getMap().width() / editor.getMap().height());
|
float ratio = 1f / ((float) editor.getMap().width() / editor.getMap().height());
|
||||||
float size = Math.min(width, height);
|
float size = Math.min(width, height);
|
||||||
float sclwidth = size * zoom;
|
float sclwidth = size * zoom;
|
||||||
float sclheight = size * zoom * ratio;
|
float sclheight = size * zoom * ratio;
|
||||||
float centerx = x + width/2 + offsetx * zoom;
|
float centerx = x + width / 2 + offsetx * zoom;
|
||||||
float centery = y + height/2 + offsety * zoom;
|
float centery = y + height / 2 + offsety * zoom;
|
||||||
|
|
||||||
image.setImageSize(editor.getMap().width(), editor.getMap().height());
|
image.setImageSize(editor.getMap().width(), editor.getMap().height());
|
||||||
|
|
||||||
@@ -275,19 +275,19 @@ public class MapView extends Element implements GestureListener{
|
|||||||
|
|
||||||
Draw.color(Color.LIGHT_GRAY);
|
Draw.color(Color.LIGHT_GRAY);
|
||||||
Lines.stroke(-2f);
|
Lines.stroke(-2f);
|
||||||
Lines.rect(centerx - sclwidth/2 - 1, centery - sclheight/2 - 1, sclwidth + 2, sclheight + 2);
|
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);
|
editor.renderer().draw(centerx - sclwidth / 2, centery - sclheight / 2, sclwidth, sclheight);
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
|
|
||||||
if(grid){
|
if(grid){
|
||||||
Draw.color(Color.GRAY);
|
Draw.color(Color.GRAY);
|
||||||
image.setBounds(centerx - sclwidth/2, centery - sclheight/2, sclwidth, sclheight);
|
image.setBounds(centerx - sclwidth / 2, centery - sclheight / 2, sclwidth, sclheight);
|
||||||
image.draw(batch, alpha);
|
image.draw(batch, alpha);
|
||||||
Draw.color();
|
Draw.color();
|
||||||
}
|
}
|
||||||
|
|
||||||
int index = 0;
|
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]){
|
if(editor.getBrushSize() == MapEditor.brushSizes[i]){
|
||||||
index = i;
|
index = i;
|
||||||
break;
|
break;
|
||||||
@@ -300,8 +300,8 @@ public class MapView extends Element implements GestureListener{
|
|||||||
Draw.color(Palette.accent);
|
Draw.color(Palette.accent);
|
||||||
Lines.stroke(Unit.dp.scl(1f * zoom));
|
Lines.stroke(Unit.dp.scl(1f * zoom));
|
||||||
|
|
||||||
if(!editor.getDrawBlock().isMultiblock() || tool == EditorTool.eraser) {
|
if(!editor.getDrawBlock().isMultiblock() || tool == EditorTool.eraser){
|
||||||
if (tool == EditorTool.line && drawing) {
|
if(tool == EditorTool.line && drawing){
|
||||||
Vector2 v1 = unproject(startx, starty).add(x, y);
|
Vector2 v1 = unproject(startx, starty).add(x, y);
|
||||||
float sx = v1.x, sy = v1.y;
|
float sx = v1.x, sy = v1.y;
|
||||||
Vector2 v2 = unproject(lastx, lasty).add(x, y);
|
Vector2 v2 = unproject(lastx, lasty).add(x, y);
|
||||||
@@ -310,7 +310,7 @@ public class MapView extends Element implements GestureListener{
|
|||||||
Lines.poly(brushPolygons[index], v2.x, v2.y, scaling);
|
Lines.poly(brushPolygons[index], v2.x, v2.y, scaling);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tool.edit && (!mobile || drawing)) {
|
if(tool.edit && (!mobile || drawing)){
|
||||||
GridPoint2 p = project(mousex, mousey);
|
GridPoint2 p = project(mousex, mousey);
|
||||||
Vector2 v = unproject(p.x, p.y).add(x, y);
|
Vector2 v = unproject(p.x, p.y).add(x, y);
|
||||||
Lines.poly(brushPolygons[index], v.x, v.y, scaling);
|
Lines.poly(brushPolygons[index], v.x, v.y, scaling);
|
||||||
@@ -319,11 +319,11 @@ public class MapView extends Element implements GestureListener{
|
|||||||
if((tool.edit || tool == EditorTool.line) && (!mobile || drawing)){
|
if((tool.edit || tool == EditorTool.line) && (!mobile || drawing)){
|
||||||
GridPoint2 p = project(mousex, mousey);
|
GridPoint2 p = project(mousex, mousey);
|
||||||
Vector2 v = unproject(p.x, p.y).add(x, y);
|
Vector2 v = unproject(p.x, p.y).add(x, y);
|
||||||
float offset = (editor.getDrawBlock().size % 2 == 0 ? scaling/2f : 0f);
|
float offset = (editor.getDrawBlock().size % 2 == 0 ? scaling / 2f : 0f);
|
||||||
Lines.square(
|
Lines.square(
|
||||||
v.x + scaling/2f + offset,
|
v.x + scaling / 2f + offset,
|
||||||
v.y + scaling/2f + offset,
|
v.y + scaling / 2f + offset,
|
||||||
scaling * editor.getDrawBlock().size /2f);
|
scaling * editor.getDrawBlock().size / 2f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,13 +38,13 @@ public class OperationStack{
|
|||||||
if(!canUndo()) return;
|
if(!canUndo()) return;
|
||||||
|
|
||||||
stack.get(stack.size - 1 + index).undo(editor);
|
stack.get(stack.size - 1 + index).undo(editor);
|
||||||
index --;
|
index--;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void redo(MapEditor editor){
|
public void redo(MapEditor editor){
|
||||||
if(!canRedo()) return;
|
if(!canRedo()) return;
|
||||||
|
|
||||||
index ++;
|
index++;
|
||||||
stack.get(stack.size - 1 + index).redo(editor);
|
stack.get(stack.size - 1 + index).redo(editor);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,30 +24,34 @@ import io.anuke.ucore.util.Translator;
|
|||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
/**Utility class for damaging in an area.*/
|
/**
|
||||||
public class Damage {
|
* Utility class for damaging in an area.
|
||||||
|
*/
|
||||||
|
public class Damage{
|
||||||
private static Rectangle rect = new Rectangle();
|
private static Rectangle rect = new Rectangle();
|
||||||
private static Rectangle hitrect = new Rectangle();
|
private static Rectangle hitrect = new Rectangle();
|
||||||
private static Translator tr = new Translator();
|
private static Translator tr = new Translator();
|
||||||
|
|
||||||
/**Creates a dynamic explosion based on specified parameters.*/
|
/**
|
||||||
|
* 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){
|
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 ++){
|
for(int i = 0; i < Mathf.clamp(power / 20, 0, 6); i++){
|
||||||
int branches = 5 + Mathf.clamp((int)(power/30), 1, 20);
|
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,
|
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)));
|
x, y, Mathf.random(360f), branches + Mathf.range(2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < Mathf.clamp(flammability / 4, 0, 30); i ++){
|
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)));
|
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 ++){
|
for(int i = 0; i < waves; i++){
|
||||||
int f = i;
|
int f = i;
|
||||||
Timers.run(i*2f, () -> {
|
Timers.run(i * 2f, () -> {
|
||||||
Damage.damage(x, y, Mathf.clamp(radius + explosiveness, 0, 50f) * ((f + 1f)/waves), explosiveness/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));
|
Effects.effect(ExplosionFx.blockExplosionSmoke, x + Mathf.range(radius), y + Mathf.range(radius));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -60,13 +64,13 @@ public class Damage {
|
|||||||
Effects.effect(ExplosionFx.bigShockwave, x, y);
|
Effects.effect(ExplosionFx.bigShockwave, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
float shake = Math.min(explosiveness/4f + 3f, 9f);
|
float shake = Math.min(explosiveness / 4f + 3f, 9f);
|
||||||
Effects.shake(shake, shake, x, y);
|
Effects.shake(shake, shake, x, y);
|
||||||
Effects.effect(ExplosionFx.blockExplosion, x, y);
|
Effects.effect(ExplosionFx.blockExplosion, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void createIncend(float x, float y, float range, int amount){
|
public static void createIncend(float x, float y, float range, int amount){
|
||||||
for (int i = 0; i < amount; i++) {
|
for(int i = 0; i < amount; i++){
|
||||||
float cx = x + Mathf.range(range);
|
float cx = x + Mathf.range(range);
|
||||||
float cy = y + Mathf.range(range);
|
float cy = y + Mathf.range(range);
|
||||||
Tile tile = world.tileWorld(cx, cy);
|
Tile tile = world.tileWorld(cx, cy);
|
||||||
@@ -76,8 +80,10 @@ public class Damage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Damages entities in a line.
|
/**
|
||||||
* Only enemies of the specified team are damaged.*/
|
* 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){
|
public static void collideLine(SolidEntity hitter, Team team, Effect effect, float x, float y, float angle, float length){
|
||||||
tr.trns(angle, length);
|
tr.trns(angle, length);
|
||||||
rect.setPosition(x, y).setSize(tr.x, tr.y);
|
rect.setPosition(x, y).setSize(tr.x, tr.y);
|
||||||
@@ -97,8 +103,8 @@ public class Damage {
|
|||||||
|
|
||||||
rect.y -= expand;
|
rect.y -= expand;
|
||||||
rect.x -= expand;
|
rect.x -= expand;
|
||||||
rect.width += expand*2;
|
rect.width += expand * 2;
|
||||||
rect.height += expand*2;
|
rect.height += expand * 2;
|
||||||
|
|
||||||
Consumer<Unit> cons = e -> {
|
Consumer<Unit> cons = e -> {
|
||||||
e.getHitbox(hitrect);
|
e.getHitbox(hitrect);
|
||||||
@@ -110,7 +116,7 @@ public class Damage {
|
|||||||
|
|
||||||
Vector2 vec = Physics.raycastRect(x, y, x2, y2, other);
|
Vector2 vec = Physics.raycastRect(x, y, x2, y2, other);
|
||||||
|
|
||||||
if (vec != null) {
|
if(vec != null){
|
||||||
Effects.effect(effect, vec.x, vec.y);
|
Effects.effect(effect, vec.x, vec.y);
|
||||||
e.collision(hitter, vec.x, vec.y);
|
e.collision(hitter, vec.x, vec.y);
|
||||||
hitter.collision(e, vec.x, vec.y);
|
hitter.collision(e, vec.x, vec.y);
|
||||||
@@ -120,13 +126,15 @@ public class Damage {
|
|||||||
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<Unit> predicate, Consumer<Unit> acceptor) {
|
* 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<Unit> predicate, Consumer<Unit> acceptor){
|
||||||
Consumer<Unit> cons = entity -> {
|
Consumer<Unit> cons = entity -> {
|
||||||
if(!predicate.test(entity)) return;
|
if(!predicate.test(entity)) return;
|
||||||
|
|
||||||
entity.getHitbox(hitrect);
|
entity.getHitbox(hitrect);
|
||||||
if (!hitrect.overlaps(rect)) {
|
if(!hitrect.overlaps(rect)){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
entity.damage(damage);
|
entity.damage(damage);
|
||||||
@@ -134,19 +142,23 @@ public class Damage {
|
|||||||
};
|
};
|
||||||
|
|
||||||
rect.setSize(size * 2).setCenter(x, y);
|
rect.setSize(size * 2).setCenter(x, y);
|
||||||
if (team != null) {
|
if(team != null){
|
||||||
Units.getNearbyEnemies(team, rect, cons);
|
Units.getNearbyEnemies(team, rect, cons);
|
||||||
} else {
|
}else{
|
||||||
Units.getNearby(rect, cons);
|
Units.getNearby(rect, cons);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Damages everything in a radius.*/
|
/**
|
||||||
|
* Damages everything in a radius.
|
||||||
|
*/
|
||||||
public static void damage(float x, float y, float radius, float damage){
|
public static void damage(float x, float y, float radius, float damage){
|
||||||
damage(null, x, y, radius, damage);
|
damage(null, x, y, radius, damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Damages all entities and blocks in a radius that are enemies of the team.*/
|
/**
|
||||||
|
* 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){
|
public static void damage(Team team, float x, float y, float radius, float damage){
|
||||||
Consumer<Unit> cons = entity -> {
|
Consumer<Unit> cons = entity -> {
|
||||||
if(entity.team == team || entity.distanceTo(x, y) > radius){
|
if(entity.team == team || entity.distanceTo(x, y) > radius){
|
||||||
@@ -156,19 +168,19 @@ public class Damage {
|
|||||||
entity.damage(amount);
|
entity.damage(amount);
|
||||||
//TODO better velocity displacement
|
//TODO better velocity displacement
|
||||||
float dst = tr.set(entity.x - x, entity.y - y).len();
|
float dst = tr.set(entity.x - x, entity.y - y).len();
|
||||||
entity.getVelocity().add(tr.setLength((1f-dst/radius) * 2f));
|
entity.getVelocity().add(tr.setLength((1f - dst / radius) * 2f));
|
||||||
};
|
};
|
||||||
|
|
||||||
rect.setSize(radius *2).setCenter(x, y);
|
rect.setSize(radius * 2).setCenter(x, y);
|
||||||
if(team != null) {
|
if(team != null){
|
||||||
Units.getNearbyEnemies(team, rect, cons);
|
Units.getNearbyEnemies(team, rect, cons);
|
||||||
}else{
|
}else{
|
||||||
Units.getNearby(rect, cons);
|
Units.getNearby(rect, cons);
|
||||||
}
|
}
|
||||||
|
|
||||||
int trad = (int)(radius / tilesize);
|
int trad = (int) (radius / tilesize);
|
||||||
for(int dx = -trad; dx <= trad; dx ++){
|
for(int dx = -trad; dx <= trad; dx++){
|
||||||
for(int dy= -trad; dy <= trad; dy ++){
|
for(int dy = -trad; dy <= trad; dy++){
|
||||||
Tile tile = world.tile(Mathf.scl2(x, tilesize) + dx, Mathf.scl2(y, tilesize) + 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){
|
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);
|
float amount = calculateDamage(x, y, tile.worldx(), tile.worldy(), radius, damage);
|
||||||
@@ -182,7 +194,7 @@ public class Damage {
|
|||||||
private static float calculateDamage(float x, float y, float tx, float ty, float radius, float damage){
|
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 dist = Vector2.dst(x, y, tx, ty);
|
||||||
float falloff = 0.4f;
|
float falloff = 0.4f;
|
||||||
float scaled = Mathf.lerp(1f - dist/radius, 1f, falloff);
|
float scaled = Mathf.lerp(1f - dist / radius, 1f, falloff);
|
||||||
return damage * scaled;
|
return damage * scaled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,10 @@ import io.anuke.mindustry.world.Tile;
|
|||||||
import io.anuke.mindustry.world.blocks.Floor;
|
import io.anuke.mindustry.world.blocks.Floor;
|
||||||
import io.anuke.mindustry.world.blocks.storage.CoreBlock.CoreEntity;
|
import io.anuke.mindustry.world.blocks.storage.CoreBlock.CoreEntity;
|
||||||
import io.anuke.mindustry.world.blocks.units.MechFactory;
|
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.EntityGroup;
|
||||||
import io.anuke.ucore.entities.trait.SolidTrait;
|
import io.anuke.ucore.entities.trait.SolidTrait;
|
||||||
import io.anuke.ucore.graphics.Draw;
|
import io.anuke.ucore.graphics.Draw;
|
||||||
@@ -39,14 +42,12 @@ import java.io.IOException;
|
|||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTrait {
|
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 timerShootLeft = 0;
|
||||||
private static final int timerShootRight = 1;
|
private static final int timerShootRight = 1;
|
||||||
|
|
||||||
public static final int timerSync = 2;
|
|
||||||
|
|
||||||
//region instance variables, constructor
|
//region instance variables, constructor
|
||||||
|
|
||||||
public float baseRotation;
|
public float baseRotation;
|
||||||
|
|
||||||
public float pointerX, pointerY;
|
public float pointerX, pointerY;
|
||||||
@@ -82,139 +83,6 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
|
|
||||||
//region unit and event overrides, utility methods
|
//region unit and event overrides, utility methods
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Timer getTimer() {
|
|
||||||
return timer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getShootTimer(boolean left) {
|
|
||||||
return left ? timerShootLeft : timerShootRight;
|
|
||||||
}
|
|
||||||
|
|
||||||
@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){
|
|
||||||
baseRotation = interpolator.values[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
if(interpolator.target.dst(interpolator.last) > 1f){
|
|
||||||
walktime += Timers.delta();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@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 boolean isFlying(){
|
|
||||||
return mech.flying || noclip || isCarried();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float getSize() {
|
|
||||||
return 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void damage(float amount){
|
|
||||||
CallEntity.onPlayerDamage(this, calculateDamage(amount));
|
|
||||||
|
|
||||||
if(health <= 0 && !dead){
|
|
||||||
CallEntity.onPlayerDeath(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean collides(SolidTrait other) {
|
|
||||||
return super.collides(other) || other instanceof ItemDrop;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Remote(in = In.entities, targets = Loc.server, called = Loc.server)
|
@Remote(in = In.entities, targets = Loc.server, called = Loc.server)
|
||||||
public static void onPlayerDamage(Player player, float amount){
|
public static void onPlayerDamage(Player player, float amount){
|
||||||
if(player == null) return;
|
if(player == null) return;
|
||||||
@@ -234,12 +102,144 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
|
|
||||||
float explosiveness = 2f + (player.inventory.hasItem() ? player.inventory.getItem().item.explosiveness * player.inventory.getItem().amount : 0f);
|
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);
|
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);
|
Damage.dynamicExplosion(player.x, player.y, flammability, explosiveness, 0f, player.getSize() / 2f, Palette.darkFlame);
|
||||||
|
|
||||||
ScorchDecal.create(player.x, player.y);
|
ScorchDecal.create(player.x, player.y);
|
||||||
player.onDeath();
|
player.onDeath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Timer getTimer(){
|
||||||
|
return timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getShootTimer(boolean left){
|
||||||
|
return left ? timerShootLeft : timerShootRight;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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){
|
||||||
|
baseRotation = interpolator.values[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(interpolator.target.dst(interpolator.last) > 1f){
|
||||||
|
walktime += Timers.delta();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 boolean isFlying(){
|
||||||
|
return mech.flying || noclip || isCarried();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getSize(){
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void damage(float amount){
|
||||||
|
CallEntity.onPlayerDamage(this, calculateDamage(amount));
|
||||||
|
|
||||||
|
if(health <= 0 && !dead){
|
||||||
|
CallEntity.onPlayerDeath(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean collides(SolidTrait other){
|
||||||
|
return super.collides(other) || other instanceof ItemDrop;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void set(float x, float y){
|
public void set(float x, float y){
|
||||||
this.x = x;
|
this.x = x;
|
||||||
@@ -251,17 +251,17 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removed() {
|
public void removed(){
|
||||||
dropCarryLocal();
|
dropCarryLocal();
|
||||||
|
|
||||||
TileEntity core = getClosestCore();
|
TileEntity core = getClosestCore();
|
||||||
if(core != null && ((CoreEntity)core).currentUnit == this){
|
if(core != null && ((CoreEntity) core).currentUnit == this){
|
||||||
((CoreEntity)core).currentUnit = null;
|
((CoreEntity) core).currentUnit = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityGroup targetGroup() {
|
public EntityGroup targetGroup(){
|
||||||
return playerGroup;
|
return playerGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,13 +270,13 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
//region draw methods
|
//region draw methods
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float drawSize() {
|
public float drawSize(){
|
||||||
return isLocal ? Float.MAX_VALUE : 40;
|
return isLocal ? Float.MAX_VALUE : 40;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawShadow(){
|
public void drawShadow(){
|
||||||
Draw.rect(mech.iconRegion, x + elevation*elevationScale, y - elevation*elevationScale, rotation - 90);
|
Draw.rect(mech.iconRegion, x + elevation * elevationScale, y - elevation * elevationScale, rotation - 90);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -284,7 +284,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
if((debug && (!showPlayer || !showUI)) || dead) return;
|
if((debug && (!showPlayer || !showUI)) || dead) return;
|
||||||
|
|
||||||
if(!movement.isZero() && moved){
|
if(!movement.isZero() && moved){
|
||||||
walktime += Timers.delta() * movement.len()/0.7f * getFloorOn().speedMultiplier;
|
walktime += Timers.delta() * movement.len() / 0.7f * getFloorOn().speedMultiplier;
|
||||||
baseRotation = Mathf.slerpDelta(baseRotation, movement.angle(), 0.13f);
|
baseRotation = Mathf.slerpDelta(baseRotation, movement.angle(), 0.13f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,49 +292,49 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
|
|
||||||
boolean snap = snapCamera && isLocal;
|
boolean snap = snapCamera && isLocal;
|
||||||
|
|
||||||
float px = x, py =y;
|
float px = x, py = y;
|
||||||
|
|
||||||
if(snap){
|
if(snap){
|
||||||
x = (int)(x + 0.0001f);
|
x = (int) (x + 0.0001f);
|
||||||
y = (int)(y + 0.0001f);
|
y = (int) (y + 0.0001f);
|
||||||
}
|
}
|
||||||
|
|
||||||
float ft = Mathf.sin(walktime, 6f, 2f) * (1f-boostHeat);
|
float ft = Mathf.sin(walktime, 6f, 2f) * (1f - boostHeat);
|
||||||
|
|
||||||
Floor floor = getFloorOn();
|
Floor floor = getFloorOn();
|
||||||
|
|
||||||
Draw.color();
|
Draw.color();
|
||||||
Draw.alpha(hitTime / hitDuration);
|
Draw.alpha(hitTime / hitDuration);
|
||||||
|
|
||||||
if(!mech.flying) {
|
if(!mech.flying){
|
||||||
if(floor.isLiquid){
|
if(floor.isLiquid){
|
||||||
Draw.tint(Color.WHITE, floor.liquidColor, 0.5f);
|
Draw.tint(Color.WHITE, floor.liquidColor, 0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
float boostTrnsY = -boostHeat * 3f;
|
float boostTrnsY = -boostHeat * 3f;
|
||||||
float boostTrnsX = boostHeat * 3f;
|
float boostTrnsX = boostHeat * 3f;
|
||||||
float boostAng = boostHeat*40f;
|
float boostAng = boostHeat * 40f;
|
||||||
|
|
||||||
for (int i : Mathf.signs) {
|
for(int i : Mathf.signs){
|
||||||
Draw.rect(mech.legRegion,
|
Draw.rect(mech.legRegion,
|
||||||
x + Angles.trnsx(baseRotation, ft * i + boostTrnsY, -boostTrnsX*i),
|
x + Angles.trnsx(baseRotation, ft * i + boostTrnsY, -boostTrnsX * i),
|
||||||
y + Angles.trnsy(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);
|
12f * i, 12f - Mathf.clamp(ft * i, 0, 2), baseRotation - 90 + boostAng * i);
|
||||||
}
|
}
|
||||||
|
|
||||||
Draw.rect(mech.baseRegion, x, y, baseRotation- 90);
|
Draw.rect(mech.baseRegion, x, y, baseRotation - 90);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(floor.isLiquid) {
|
if(floor.isLiquid){
|
||||||
Draw.tint(Color.WHITE, floor.liquidColor, drownTime * 0.4f);
|
Draw.tint(Color.WHITE, floor.liquidColor, drownTime * 0.4f);
|
||||||
}else {
|
}else{
|
||||||
Draw.tint(Color.WHITE);
|
Draw.tint(Color.WHITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
Draw.rect(mech.region, x, y, rotation -90);
|
Draw.rect(mech.region, x, y, rotation - 90);
|
||||||
|
|
||||||
for (int i : Mathf.signs) {
|
for(int i : Mathf.signs){
|
||||||
float tra = rotation - 90, trY = - mech.weapon.getRecoil(this, i > 0) + mech.weaponOffsetY;
|
float tra = rotation - 90, trY = -mech.weapon.getRecoil(this, i > 0) + mech.weaponOffsetY;
|
||||||
float w = i > 0 ? -12 : 12;
|
float w = i > 0 ? -12 : 12;
|
||||||
Draw.rect(mech.weapon.equipRegion,
|
Draw.rect(mech.weapon.equipRegion,
|
||||||
x + Angles.trnsx(tra, mech.weaponOffsetX * i, trY),
|
x + Angles.trnsx(tra, mech.weaponOffsetX * i, trY),
|
||||||
@@ -346,7 +346,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
ItemStack stack = inventory.getItem();
|
ItemStack stack = inventory.getItem();
|
||||||
int stored = Mathf.clamp(stack.amount / 6, 1, 8);
|
int stored = Mathf.clamp(stack.amount / 6, 1, 8);
|
||||||
|
|
||||||
for(int i = 0; i < stored; i ++) {
|
for(int i = 0; i < stored; i++){
|
||||||
float angT = i == 0 ? 0 : Mathf.randomSeedRange(i + 1, 60f);
|
float angT = i == 0 ? 0 : Mathf.randomSeedRange(i + 1, 60f);
|
||||||
float lenT = i == 0 ? 0 : Mathf.randomSeedRange(i + 2, 1f) - 1f;
|
float lenT = i == 0 ? 0 : Mathf.randomSeedRange(i + 2, 1f) - 1f;
|
||||||
Draw.rect(stack.item.region,
|
Draw.rect(stack.item.region,
|
||||||
@@ -366,7 +366,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
public void drawOver(){
|
public void drawOver(){
|
||||||
if(dead) return;
|
if(dead) return;
|
||||||
|
|
||||||
if(!isShooting()) {
|
if(!isShooting()){
|
||||||
drawBuilding(this);
|
drawBuilding(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -383,10 +383,10 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
public void drawName(){
|
public void drawName(){
|
||||||
GlyphLayout layout = Pools.obtain(GlyphLayout.class);
|
GlyphLayout layout = Pools.obtain(GlyphLayout.class);
|
||||||
|
|
||||||
Draw.tscl(0.25f/2);
|
Draw.tscl(0.25f / 2);
|
||||||
layout.setText(Core.font, name);
|
layout.setText(Core.font, name);
|
||||||
Draw.color(0f, 0f, 0f, 0.3f);
|
Draw.color(0f, 0f, 0f, 0.3f);
|
||||||
Draw.rect("blank", x, y + 8 - layout.height/2, layout.width + 2, layout.height + 2);
|
Draw.rect("blank", x, y + 8 - layout.height / 2, layout.width + 2, layout.height + 2);
|
||||||
Draw.color();
|
Draw.color();
|
||||||
Draw.tcolor(color);
|
Draw.tcolor(color);
|
||||||
Draw.text(name, x, y + 8);
|
Draw.text(name, x, y + 8);
|
||||||
@@ -394,7 +394,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
if(isAdmin){
|
if(isAdmin){
|
||||||
Draw.color(color);
|
Draw.color(color);
|
||||||
float s = 3f;
|
float s = 3f;
|
||||||
Draw.rect("icon-admin-small", x + layout.width/2f + 2 + 1, y + 7f, s, s);
|
Draw.rect("icon-admin-small", x + layout.width / 2f + 2 + 1, y + 7f, s, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
@@ -402,12 +402,14 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
Draw.tscl(fontScale);
|
Draw.tscl(fontScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Draw all current build requests. Does not draw the beam effect, only the positions.*/
|
/**
|
||||||
|
* Draw all current build requests. Does not draw the beam effect, only the positions.
|
||||||
|
*/
|
||||||
public void drawBuildRequests(){
|
public void drawBuildRequests(){
|
||||||
synchronized (getPlaceQueue()) {
|
synchronized(getPlaceQueue()){
|
||||||
for (BuildRequest request : getPlaceQueue()) {
|
for(BuildRequest request : getPlaceQueue()){
|
||||||
|
|
||||||
if (request.remove) {
|
if(request.remove){
|
||||||
Block block = world.tile(request.x, request.y).target().block();
|
Block block = world.tile(request.x, request.y).target().block();
|
||||||
|
|
||||||
//draw removal request
|
//draw removal request
|
||||||
@@ -418,7 +420,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
Lines.poly(request.x * tilesize + block.offset(),
|
Lines.poly(request.x * tilesize + block.offset(),
|
||||||
request.y * tilesize + block.offset(),
|
request.y * tilesize + block.offset(),
|
||||||
4, block.size * tilesize / 2f, 45 + 15);
|
4, block.size * tilesize / 2f, 45 + 15);
|
||||||
} else {
|
}else{
|
||||||
//draw place request
|
//draw place request
|
||||||
Draw.color(Palette.accent);
|
Draw.color(Palette.accent);
|
||||||
|
|
||||||
@@ -473,11 +475,11 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
updateMech();
|
updateMech();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isLocal) {
|
if(isLocal){
|
||||||
avoidOthers(8f);
|
avoidOthers(8f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!isShooting()) {
|
if(!isShooting()){
|
||||||
updateBuilding(this);
|
updateBuilding(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -489,7 +491,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
Tile tile = world.tileWorld(x, y);
|
Tile tile = world.tileWorld(x, y);
|
||||||
|
|
||||||
//if player is in solid block
|
//if player is in solid block
|
||||||
if(!mech.flying && tile != null && tile.solid() && !noclip) {
|
if(!mech.flying && tile != null && tile.solid() && !noclip){
|
||||||
damage(health + 1); //die instantly
|
damage(health + 1); //die instantly
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,7 +501,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
//fraction of speed when at max load
|
//fraction of speed when at max load
|
||||||
float carrySlowdown = 0.7f;
|
float carrySlowdown = 0.7f;
|
||||||
|
|
||||||
speed *= ((inventory.hasItem() ? Mathf.lerp(1f, carrySlowdown, (float)inventory.getItem().amount/inventory.capacity()) : 1f));
|
speed *= ((inventory.hasItem() ? Mathf.lerp(1f, carrySlowdown, (float) inventory.getItem().amount / inventory.capacity()) : 1f));
|
||||||
|
|
||||||
if(mech.flying){
|
if(mech.flying){
|
||||||
//prevent strafing backwards, have a penalty for doing so
|
//prevent strafing backwards, have a penalty for doing so
|
||||||
@@ -510,8 +512,8 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
|
|
||||||
//drop from carrier on key press
|
//drop from carrier on key press
|
||||||
if(Inputs.keyTap("drop_unit")){
|
if(Inputs.keyTap("drop_unit")){
|
||||||
if(!mech.flying) {
|
if(!mech.flying){
|
||||||
if (getCarrier() != null) {
|
if(getCarrier() != null){
|
||||||
CallEntity.dropSelf(this);
|
CallEntity.dropSelf(this);
|
||||||
}
|
}
|
||||||
}else if(getCarry() != null){
|
}else if(getCarry() != null){
|
||||||
@@ -533,8 +535,8 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
float xa = Inputs.getAxis(section, "move_x");
|
float xa = Inputs.getAxis(section, "move_x");
|
||||||
float ya = Inputs.getAxis(section, "move_y");
|
float ya = Inputs.getAxis(section, "move_y");
|
||||||
|
|
||||||
movement.y += ya*speed;
|
movement.y += ya * speed;
|
||||||
movement.x += xa*speed;
|
movement.x += xa * speed;
|
||||||
|
|
||||||
Vector2 vec = Graphics.world(Vars.control.input(playerIndex).getMouseX(),
|
Vector2 vec = Graphics.world(Vars.control.input(playerIndex).getMouseX(),
|
||||||
Vars.control.input(playerIndex).getMouseY());
|
Vars.control.input(playerIndex).getMouseY());
|
||||||
@@ -556,7 +558,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!isShooting()){
|
if(!isShooting()){
|
||||||
if(!movement.isZero()) {
|
if(!movement.isZero()){
|
||||||
rotation = Mathf.slerpDelta(rotation, movement.angle(), 0.13f);
|
rotation = Mathf.slerpDelta(rotation, movement.angle(), 0.13f);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
@@ -610,7 +612,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
if(velocity.len() <= 0.2f){
|
if(velocity.len() <= 0.2f){
|
||||||
rotation += Mathf.sin(Timers.time() + id * 99, 10f, 1f);
|
rotation += Mathf.sin(Timers.time() + id * 99, 10f, 1f);
|
||||||
}else{
|
}else{
|
||||||
rotation = Mathf.slerpDelta(rotation, velocity.angle(), velocity.len()/10f);
|
rotation = Mathf.slerpDelta(rotation, velocity.angle(), velocity.len() / 10f);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateVelocityStatus(mech.drag, mech.maxSpeed);
|
updateVelocityStatus(mech.drag, mech.maxSpeed);
|
||||||
@@ -623,12 +625,12 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
if(!isBuilding() && inventory.hasAmmo() && getMineTile() == null){
|
if(!isBuilding() && inventory.hasAmmo() && getMineTile() == null){
|
||||||
|
|
||||||
//autofire: mobile only!
|
//autofire: mobile only!
|
||||||
if(mobile) {
|
if(mobile){
|
||||||
|
|
||||||
if (target == null) {
|
if(target == null){
|
||||||
isShooting = false;
|
isShooting = false;
|
||||||
target = Units.getClosestTarget(team, x, y, inventory.getAmmoRange());
|
target = Units.getClosestTarget(team, x, y, inventory.getAmmoRange());
|
||||||
} else if(target.isValid()){
|
}else if(target.isValid()){
|
||||||
//rotate toward and shoot the target
|
//rotate toward and shoot the target
|
||||||
rotation = Mathf.slerpDelta(rotation, angleTo(target), 0.2f);
|
rotation = Mathf.slerpDelta(rotation, angleTo(target), 0.2f);
|
||||||
|
|
||||||
@@ -661,7 +663,9 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
team = (team == Team.blue ? Team.red : Team.blue);
|
team = (team == Team.blue ? Team.red : Team.blue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Resets all values of the player.*/
|
/**
|
||||||
|
* Resets all values of the player.
|
||||||
|
*/
|
||||||
public void reset(){
|
public void reset(){
|
||||||
status.clear();
|
status.clear();
|
||||||
team = Team.blue;
|
team = Team.blue;
|
||||||
@@ -682,10 +686,10 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
|
|
||||||
public void updateRespawning(){
|
public void updateRespawning(){
|
||||||
|
|
||||||
if (spawner != -1 && world.tile(spawner) != null && world.tile(spawner).entity instanceof SpawnerTrait) {
|
if(spawner != -1 && world.tile(spawner) != null && world.tile(spawner).entity instanceof SpawnerTrait){
|
||||||
((SpawnerTrait) world.tile(spawner).entity).updateSpawning(this);
|
((SpawnerTrait) world.tile(spawner).entity).updateSpawning(this);
|
||||||
}else{
|
}else{
|
||||||
CoreEntity entity = (CoreEntity)getClosestCore();
|
CoreEntity entity = (CoreEntity) getClosestCore();
|
||||||
if(entity != null){
|
if(entity != null){
|
||||||
this.spawner = entity.tile.id();
|
this.spawner = entity.tile.id();
|
||||||
}
|
}
|
||||||
@@ -703,7 +707,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString(){
|
||||||
return "Player{" + id + ", mech=" + mech.name + ", local=" + isLocal + ", " + x + ", " + y + "}\n";
|
return "Player{" + id + ", mech=" + mech.name + ", local=" + isLocal + ", " + x + ", " + y + "}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -712,7 +716,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
//region read and write methods
|
//region read and write methods
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeSave(DataOutput stream) throws IOException {
|
public void writeSave(DataOutput stream) throws IOException{
|
||||||
stream.writeBoolean(isLocal);
|
stream.writeBoolean(isLocal);
|
||||||
|
|
||||||
if(isLocal){
|
if(isLocal){
|
||||||
@@ -723,7 +727,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readSave(DataInput stream) throws IOException {
|
public void readSave(DataInput stream) throws IOException{
|
||||||
boolean local = stream.readBoolean();
|
boolean local = stream.readBoolean();
|
||||||
|
|
||||||
if(local && !headless){
|
if(local && !headless){
|
||||||
@@ -741,14 +745,14 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readSaveSuper(DataInput stream) throws IOException {
|
private void readSaveSuper(DataInput stream) throws IOException{
|
||||||
super.readSave(stream);
|
super.readSave(stream);
|
||||||
|
|
||||||
add();
|
add();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(DataOutput buffer) throws IOException {
|
public void write(DataOutput buffer) throws IOException{
|
||||||
super.writeSave(buffer, !isLocal);
|
super.writeSave(buffer, !isLocal);
|
||||||
buffer.writeUTF(name); //TODO writing strings is very inefficient
|
buffer.writeUTF(name); //TODO writing strings is very inefficient
|
||||||
buffer.writeByte(Bits.toByte(isAdmin) | (Bits.toByte(dead) << 1) | (Bits.toByte(isBoosting) << 2));
|
buffer.writeByte(Bits.toByte(isAdmin) | (Bits.toByte(dead) << 1) | (Bits.toByte(isBoosting) << 2));
|
||||||
@@ -756,13 +760,13 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
buffer.writeByte(mech.id);
|
buffer.writeByte(mech.id);
|
||||||
buffer.writeInt(mining == null ? -1 : mining.packedPosition());
|
buffer.writeInt(mining == null ? -1 : mining.packedPosition());
|
||||||
buffer.writeInt(spawner);
|
buffer.writeInt(spawner);
|
||||||
buffer.writeShort((short)(baseRotation * 2));
|
buffer.writeShort((short) (baseRotation * 2));
|
||||||
|
|
||||||
writeBuilding(buffer);
|
writeBuilding(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(DataInput buffer, long time) throws IOException {
|
public void read(DataInput buffer, long time) throws IOException{
|
||||||
float lastx = x, lasty = y, lastrot = rotation;
|
float lastx = x, lasty = y, lastrot = rotation;
|
||||||
super.readSave(buffer);
|
super.readSave(buffer);
|
||||||
name = buffer.readUTF();
|
name = buffer.readUTF();
|
||||||
@@ -774,7 +778,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
mech = Upgrade.getByID(buffer.readByte());
|
mech = Upgrade.getByID(buffer.readByte());
|
||||||
int mine = buffer.readInt();
|
int mine = buffer.readInt();
|
||||||
spawner = buffer.readInt();
|
spawner = buffer.readInt();
|
||||||
float baseRotation = buffer.readShort()/2f;
|
float baseRotation = buffer.readShort() / 2f;
|
||||||
|
|
||||||
readBuilding(buffer, !isLocal);
|
readBuilding(buffer, !isLocal);
|
||||||
|
|
||||||
|
|||||||
@@ -4,12 +4,16 @@ import com.badlogic.gdx.math.Vector2;
|
|||||||
import io.anuke.mindustry.entities.traits.TargetTrait;
|
import io.anuke.mindustry.entities.traits.TargetTrait;
|
||||||
import io.anuke.ucore.util.Mathf;
|
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 vec = new Vector2();
|
||||||
private static Vector2 vresult = 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 srcx X of shooter
|
||||||
* @param srcy Y of shooter
|
* @param srcy Y of shooter
|
||||||
* @param dstx X of target
|
* @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 dstvx X velocity of target (subtract shooter X velocity if needed)
|
||||||
* @param dstvy Y velocity of target (subtract shooter Y velocity if needed)
|
* @param dstvy Y velocity of target (subtract shooter Y velocity if needed)
|
||||||
* @param v speed of bullet
|
* @param v speed of bullet
|
||||||
* @return the intercept location*/
|
* @return the intercept location
|
||||||
public static Vector2 intercept(float srcx, float srcy, float dstx, float dsty, float dstvx, float dstvy, float v) {
|
*/
|
||||||
|
public static Vector2 intercept(float srcx, float srcy, float dstx, float dsty, float dstvx, float dstvy, float v){
|
||||||
float tx = dstx - srcx,
|
float tx = dstx - srcx,
|
||||||
ty = dsty - srcy;
|
ty = dsty - srcy;
|
||||||
|
|
||||||
// Get quadratic equation components
|
// 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 b = 2 * (dstvx * tx + dstvy * ty);
|
||||||
float c = tx*tx + ty*ty;
|
float c = tx * tx + ty * ty;
|
||||||
|
|
||||||
// Solve quadratic
|
// Solve quadratic
|
||||||
Vector2 ts = quad(a, b, c);
|
Vector2 ts = quad(a, b, c);
|
||||||
|
|
||||||
// Find smallest positive solution
|
// Find smallest positive solution
|
||||||
Vector2 sol = vresult.set(0, 0);
|
Vector2 sol = vresult.set(0, 0);
|
||||||
if (ts != null) {
|
if(ts != null){
|
||||||
float t0 = ts.x, t1 = ts.y;
|
float t0 = ts.x, t1 = ts.y;
|
||||||
float t = Math.min(t0, t1);
|
float t = Math.min(t0, t1);
|
||||||
if (t < 0) t = Math.max(t0, t1);
|
if(t < 0) t = Math.max(t0, t1);
|
||||||
if (t > 0) {
|
if(t > 0){
|
||||||
sol.set(dstx + dstvx*t, dsty + dstvy*t);
|
sol.set(dstx + dstvx * t, dsty + dstvy * t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sol;
|
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);
|
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;
|
Vector2 sol = null;
|
||||||
if (Math.abs(a) < 1e-6) {
|
if(Math.abs(a) < 1e-6){
|
||||||
if (Math.abs(b) < 1e-6) {
|
if(Math.abs(b) < 1e-6){
|
||||||
sol = Math.abs(c) < 1e-6 ? vec.set(0,0) : null;
|
sol = Math.abs(c) < 1e-6 ? vec.set(0, 0) : null;
|
||||||
} else {
|
}else{
|
||||||
vec.set(-c/b, -c/b);
|
vec.set(-c / b, -c / b);
|
||||||
}
|
}
|
||||||
} else {
|
}else{
|
||||||
float disc = b*b - 4*a*c;
|
float disc = b * b - 4 * a * c;
|
||||||
if (disc >= 0) {
|
if(disc >= 0){
|
||||||
disc = Mathf.sqrt(disc);
|
disc = Mathf.sqrt(disc);
|
||||||
a = 2*a;
|
a = 2 * a;
|
||||||
sol = vec.set((-b-disc)/a, (-b+disc)/a);
|
sol = vec.set((-b - disc) / a, (-b + disc) / a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sol;
|
return sol;
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ import java.io.DataInput;
|
|||||||
import java.io.DataOutput;
|
import java.io.DataOutput;
|
||||||
import java.io.IOException;
|
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{
|
public class StatusController implements Saveable{
|
||||||
private static final StatusEntry globalResult = new StatusEntry();
|
private static final StatusEntry globalResult = new StatusEntry();
|
||||||
private static final Array<StatusEntry> removals = new ThreadArray<>();
|
private static final Array<StatusEntry> removals = new ThreadArray<>();
|
||||||
@@ -26,20 +28,20 @@ public class StatusController implements Saveable{
|
|||||||
public void handleApply(Unit unit, StatusEffect effect, float intensity){
|
public void handleApply(Unit unit, StatusEffect effect, float intensity){
|
||||||
if(effect == StatusEffects.none) return; //don't apply empty effects
|
if(effect == StatusEffects.none) return; //don't apply empty effects
|
||||||
|
|
||||||
float newTime = effect.baseDuration*intensity;
|
float newTime = effect.baseDuration * intensity;
|
||||||
|
|
||||||
if(statuses.size > 0){
|
if(statuses.size > 0){
|
||||||
//check for opposite effects
|
//check for opposite effects
|
||||||
for(StatusEntry entry : statuses){
|
for(StatusEntry entry : statuses){
|
||||||
//extend effect
|
//extend effect
|
||||||
if(entry.effect == effect) {
|
if(entry.effect == effect){
|
||||||
entry.time = Math.max(entry.time, newTime);
|
entry.time = Math.max(entry.time, newTime);
|
||||||
return;
|
return;
|
||||||
}else if(entry.effect.isOpposite(effect)){ //find opposite
|
}else if(entry.effect.isOpposite(effect)){ //find opposite
|
||||||
entry.effect.getTransition(unit, effect, entry.time, newTime, globalResult);
|
entry.effect.getTransition(unit, effect, entry.time, newTime, globalResult);
|
||||||
entry.time = globalResult.time;
|
entry.time = globalResult.time;
|
||||||
|
|
||||||
if (globalResult.effect != entry.effect) {
|
if(globalResult.effect != entry.effect){
|
||||||
entry.effect.onTransition(unit, globalResult.effect);
|
entry.effect.onTransition(unit, globalResult.effect);
|
||||||
entry.effect = globalResult.effect;
|
entry.effect = globalResult.effect;
|
||||||
}
|
}
|
||||||
@@ -94,7 +96,7 @@ public class StatusController implements Saveable{
|
|||||||
return damageMultiplier;
|
return damageMultiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getArmorMultiplier() {
|
public float getArmorMultiplier(){
|
||||||
return armorMultiplier;
|
return armorMultiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,24 +108,24 @@ public class StatusController implements Saveable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeSave(DataOutput stream) throws IOException {
|
public void writeSave(DataOutput stream) throws IOException{
|
||||||
stream.writeByte(statuses.size);
|
stream.writeByte(statuses.size);
|
||||||
for(StatusEntry entry : statuses){
|
for(StatusEntry entry : statuses){
|
||||||
stream.writeByte(entry.effect.id);
|
stream.writeByte(entry.effect.id);
|
||||||
stream.writeShort((short)(entry.time * 2));
|
stream.writeShort((short) (entry.time * 2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readSave(DataInput stream) throws IOException {
|
public void readSave(DataInput stream) throws IOException{
|
||||||
for (StatusEntry effect : statuses){
|
for(StatusEntry effect : statuses){
|
||||||
Pooling.free(effect);
|
Pooling.free(effect);
|
||||||
}
|
}
|
||||||
|
|
||||||
statuses.clear();
|
statuses.clear();
|
||||||
|
|
||||||
byte amount = stream.readByte();
|
byte amount = stream.readByte();
|
||||||
for (int i = 0; i < amount; i++) {
|
for(int i = 0; i < amount; i++){
|
||||||
byte id = stream.readByte();
|
byte id = stream.readByte();
|
||||||
float time = stream.readShort() / 2f;
|
float time = stream.readShort() / 2f;
|
||||||
StatusEntry entry = Pooling.obtain(StatusEntry.class);
|
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 StatusEffect effect;
|
||||||
public float time;
|
public float time;
|
||||||
|
|
||||||
|
|||||||
@@ -35,13 +35,13 @@ import java.io.IOException;
|
|||||||
import static io.anuke.mindustry.Vars.tileGroup;
|
import static io.anuke.mindustry.Vars.tileGroup;
|
||||||
import static io.anuke.mindustry.Vars.world;
|
import static io.anuke.mindustry.Vars.world;
|
||||||
|
|
||||||
public class TileEntity extends BaseEntity implements TargetTrait {
|
public class TileEntity extends BaseEntity implements TargetTrait{
|
||||||
public static final float timeToSleep = 60f*4; //4 seconds to fall asleep
|
public static final float timeToSleep = 60f * 4; //4 seconds to fall asleep
|
||||||
/**This value is only used for debugging.*/
|
|
||||||
public static int sleepingEntities = 0;
|
|
||||||
|
|
||||||
private static final ObjectSet<Tile> tmpTiles = new ObjectSet<>();
|
private static final ObjectSet<Tile> tmpTiles = new ObjectSet<>();
|
||||||
|
/**
|
||||||
|
* This value is only used for debugging.
|
||||||
|
*/
|
||||||
|
public static int sleepingEntities = 0;
|
||||||
public Tile tile;
|
public Tile tile;
|
||||||
public Timer timer;
|
public Timer timer;
|
||||||
public float health;
|
public float health;
|
||||||
@@ -51,13 +51,25 @@ public class TileEntity extends BaseEntity implements TargetTrait {
|
|||||||
public LiquidModule liquids;
|
public LiquidModule liquids;
|
||||||
public ConsumeModule cons;
|
public ConsumeModule cons;
|
||||||
|
|
||||||
//list of (cached) tiles with entities in proximity, used for outputting to
|
/**List of (cached) tiles with entities in proximity, used for outputting to*/
|
||||||
//TODO implement
|
|
||||||
private Array<Tile> proximity = new Array<>(8);
|
private Array<Tile> proximity = new Array<>(8);
|
||||||
private boolean dead = false;
|
private boolean dead = false;
|
||||||
private boolean sleeping;
|
private boolean sleeping;
|
||||||
private float sleepTime;
|
private float sleepTime;
|
||||||
|
|
||||||
|
@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();
|
||||||
|
}
|
||||||
|
|
||||||
/**Sets this tile entity data to this tile, and adds it if necessary.*/
|
/**Sets this tile entity data to this tile, and adds it if necessary.*/
|
||||||
public TileEntity init(Tile tile, boolean added){
|
public TileEntity init(Tile tile, boolean added){
|
||||||
this.tile = tile;
|
this.tile = tile;
|
||||||
@@ -75,25 +87,29 @@ public class TileEntity extends BaseEntity implements TargetTrait {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Call when nothing is happening to the entity.
|
/**
|
||||||
* This increments the internal sleep timer.*/
|
* Call when nothing is happening to the entity.
|
||||||
|
* This increments the internal sleep timer.
|
||||||
|
*/
|
||||||
public void sleep(){
|
public void sleep(){
|
||||||
sleepTime += Timers.delta();
|
sleepTime += Timers.delta();
|
||||||
if(!sleeping && sleepTime >= timeToSleep){
|
if(!sleeping && sleepTime >= timeToSleep){
|
||||||
remove();
|
remove();
|
||||||
sleeping = true;
|
sleeping = true;
|
||||||
sleepingEntities ++;
|
sleepingEntities++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Call when something just happened to the entity.
|
/**
|
||||||
* If the entity was sleeping, this enables it. This also resets the sleep timer.*/
|
* 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(){
|
public void wakeUp(){
|
||||||
sleepTime = 0f;
|
sleepTime = 0f;
|
||||||
if(sleeping){
|
if(sleeping){
|
||||||
add();
|
add();
|
||||||
sleeping = false;
|
sleeping = false;
|
||||||
sleepingEntities --;
|
sleepingEntities--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,15 +117,18 @@ public class TileEntity extends BaseEntity implements TargetTrait {
|
|||||||
return sleeping;
|
return sleeping;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDead() {
|
public boolean isDead(){
|
||||||
return dead;
|
return dead;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void write(DataOutputStream stream) throws IOException{}
|
public void write(DataOutputStream stream) throws IOException{
|
||||||
public void read(DataInputStream stream) throws IOException{}
|
}
|
||||||
|
|
||||||
|
public void read(DataInputStream stream) throws IOException{
|
||||||
|
}
|
||||||
|
|
||||||
private void onDeath(){
|
private void onDeath(){
|
||||||
if(!dead) {
|
if(!dead){
|
||||||
dead = true;
|
dead = true;
|
||||||
Block block = tile.block();
|
Block block = tile.block();
|
||||||
|
|
||||||
@@ -148,7 +167,7 @@ public class TileEntity extends BaseEntity implements TargetTrait {
|
|||||||
|
|
||||||
public void removeFromProximity(){
|
public void removeFromProximity(){
|
||||||
GridPoint2[] nearby = Edges.getEdges(tile.block().size);
|
GridPoint2[] nearby = Edges.getEdges(tile.block().size);
|
||||||
for (GridPoint2 point : nearby) {
|
for(GridPoint2 point : nearby){
|
||||||
Tile other = world.tile(tile.x + point.x, tile.y + point.y);
|
Tile other = world.tile(tile.x + point.x, tile.y + point.y);
|
||||||
//remove this tile from all nearby tile's proximities
|
//remove this tile from all nearby tile's proximities
|
||||||
if(other != null){
|
if(other != null){
|
||||||
@@ -166,7 +185,7 @@ public class TileEntity extends BaseEntity implements TargetTrait {
|
|||||||
proximity.clear();
|
proximity.clear();
|
||||||
|
|
||||||
GridPoint2[] nearby = Edges.getEdges(tile.block().size);
|
GridPoint2[] nearby = Edges.getEdges(tile.block().size);
|
||||||
for (GridPoint2 point : nearby) {
|
for(GridPoint2 point : nearby){
|
||||||
Tile other = world.tile(tile.x + point.x, tile.y + point.y);
|
Tile other = world.tile(tile.x + point.x, tile.y + point.y);
|
||||||
|
|
||||||
if(other != null){
|
if(other != null){
|
||||||
@@ -197,26 +216,26 @@ public class TileEntity extends BaseEntity implements TargetTrait {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Team getTeam() {
|
public Team getTeam(){
|
||||||
return tile.getTeam();
|
return tile.getTeam();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vector2 getVelocity() {
|
public Vector2 getVelocity(){
|
||||||
return Vector2.Zero;
|
return Vector2.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(){
|
public void update(){
|
||||||
synchronized (Tile.tileSetLock) {
|
synchronized(Tile.tileSetLock){
|
||||||
//TODO better smoke effect, this one is awful
|
//TODO better smoke effect, this one is awful
|
||||||
if (health != 0 && health < tile.block().health && !(tile.block() instanceof Wall) &&
|
if(health != 0 && health < tile.block().health && !(tile.block() instanceof Wall) &&
|
||||||
Mathf.chance(0.009f * Timers.delta() * (1f - health / tile.block().health))) {
|
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) {
|
if(health <= 0){
|
||||||
onDeath();
|
onDeath();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,20 +247,7 @@ public class TileEntity extends BaseEntity implements TargetTrait {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityGroup targetGroup() {
|
public EntityGroup targetGroup(){
|
||||||
return tileGroup;
|
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,13 +31,19 @@ import java.io.IOException;
|
|||||||
import static io.anuke.mindustry.Vars.state;
|
import static io.anuke.mindustry.Vars.state;
|
||||||
import static io.anuke.mindustry.Vars.world;
|
import static io.anuke.mindustry.Vars.world;
|
||||||
|
|
||||||
public abstract class Unit extends DestructibleEntity implements SaveTrait, TargetTrait, SyncTrait, DrawTrait, TeamTrait, CarriableTrait, InventoryTrait {
|
public abstract class Unit extends DestructibleEntity implements SaveTrait, TargetTrait, SyncTrait, DrawTrait, TeamTrait, CarriableTrait, InventoryTrait{
|
||||||
/**total duration of hit flash effect*/
|
/**
|
||||||
|
* total duration of hit flash effect
|
||||||
|
*/
|
||||||
public static final float hitDuration = 9f;
|
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;
|
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;
|
public static final float elevationScale = 4f;
|
||||||
|
|
||||||
private static final Vector2 moveVector = new Vector2();
|
private static final Vector2 moveVector = new Vector2();
|
||||||
@@ -56,28 +62,28 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
|||||||
protected float elevation;
|
protected float elevation;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UnitInventory getInventory() {
|
public UnitInventory getInventory(){
|
||||||
return inventory;
|
return inventory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getRotation() {
|
public float getRotation(){
|
||||||
return rotation;
|
return rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setRotation(float rotation) {
|
public void setRotation(float rotation){
|
||||||
this.rotation = rotation;
|
this.rotation = rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setCarrier(CarryTrait carrier) {
|
public CarryTrait getCarrier(){
|
||||||
this.carrier = carrier;
|
return carrier;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CarryTrait getCarrier() {
|
public void setCarrier(CarryTrait carrier){
|
||||||
return carrier;
|
this.carrier = carrier;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -86,7 +92,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void interpolate() {
|
public void interpolate(){
|
||||||
interpolator.update();
|
interpolator.update();
|
||||||
|
|
||||||
x = interpolator.pos.x;
|
x = interpolator.pos.x;
|
||||||
@@ -98,7 +104,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Interpolator getInterpolator() {
|
public Interpolator getInterpolator(){
|
||||||
return interpolator;
|
return interpolator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,31 +121,31 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDeath() {
|
public void onDeath(){
|
||||||
inventory.clear();
|
inventory.clear();
|
||||||
drownTime = 0f;
|
drownTime = 0f;
|
||||||
status.clear();
|
status.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vector2 getVelocity() {
|
public Vector2 getVelocity(){
|
||||||
return velocity;
|
return velocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeSave(DataOutput stream) throws IOException {
|
public void writeSave(DataOutput stream) throws IOException{
|
||||||
writeSave(stream, false);
|
writeSave(stream, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readSave(DataInput stream) throws IOException {
|
public void readSave(DataInput stream) throws IOException{
|
||||||
byte team = stream.readByte();
|
byte team = stream.readByte();
|
||||||
boolean dead = stream.readBoolean();
|
boolean dead = stream.readBoolean();
|
||||||
float x = stream.readFloat();
|
float x = stream.readFloat();
|
||||||
float y = stream.readFloat();
|
float y = stream.readFloat();
|
||||||
byte xv = stream.readByte();
|
byte xv = stream.readByte();
|
||||||
byte yv = stream.readByte();
|
byte yv = stream.readByte();
|
||||||
float rotation = stream.readShort()/2f;
|
float rotation = stream.readShort() / 2f;
|
||||||
int health = stream.readShort();
|
int health = stream.readShort();
|
||||||
|
|
||||||
this.status.readSave(stream);
|
this.status.readSave(stream);
|
||||||
@@ -153,21 +159,21 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
|||||||
this.rotation = rotation;
|
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.writeByte(team.ordinal());
|
||||||
stream.writeBoolean(isDead());
|
stream.writeBoolean(isDead());
|
||||||
stream.writeFloat(net ? interpolator.target.x : x);
|
stream.writeFloat(net ? interpolator.target.x : x);
|
||||||
stream.writeFloat(net ? interpolator.target.y : y);
|
stream.writeFloat(net ? interpolator.target.y : y);
|
||||||
stream.writeByte((byte)(Mathf.clamp(velocity.x, -maxAbsVelocity, maxAbsVelocity) * velocityPercision));
|
stream.writeByte((byte) (Mathf.clamp(velocity.x, -maxAbsVelocity, maxAbsVelocity) * velocityPercision));
|
||||||
stream.writeByte((byte)(Mathf.clamp(velocity.y, -maxAbsVelocity, maxAbsVelocity) * velocityPercision));
|
stream.writeByte((byte) (Mathf.clamp(velocity.y, -maxAbsVelocity, maxAbsVelocity) * velocityPercision));
|
||||||
stream.writeShort((short)(rotation*2));
|
stream.writeShort((short) (rotation * 2));
|
||||||
stream.writeShort((short)health);
|
stream.writeShort((short) health);
|
||||||
status.writeSave(stream);
|
status.writeSave(stream);
|
||||||
inventory.writeSave(stream);
|
inventory.writeSave(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float calculateDamage(float amount){
|
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(){
|
public float getDamageMultipler(){
|
||||||
@@ -200,15 +206,18 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
|||||||
|
|
||||||
public void avoidOthers(float avoidRange){
|
public void avoidOthers(float avoidRange){
|
||||||
|
|
||||||
EntityPhysics.getNearby(getGroup(), x, y, avoidRange*2f, t -> {
|
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;
|
if(t == this || (t instanceof Unit && (((Unit) t).isDead() || (((Unit) t).isFlying() != isFlying()) || ((Unit) t).getCarrier() == this) || getCarrier() == t))
|
||||||
|
return;
|
||||||
float dst = distanceTo(t);
|
float dst = distanceTo(t);
|
||||||
if(dst > avoidRange) return;
|
if(dst > avoidRange) return;
|
||||||
velocity.add(moveVector.set(x, y).sub(t.getX(), t.getY()).setLength(1f * (1f - (dst / avoidRange))));
|
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){
|
public void updateVelocityStatus(float drag, float maxVelocity){
|
||||||
if(isCarried()){ //carried units do not take into account velocity normally
|
if(isCarried()){ //carried units do not take into account velocity normally
|
||||||
set(carrier.getX(), carrier.getY());
|
set(carrier.getX(), carrier.getY());
|
||||||
@@ -223,7 +232,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
|||||||
|
|
||||||
velocity.limit(maxVelocity).scl(status.getSpeedMultiplier());
|
velocity.limit(maxVelocity).scl(status.getSpeedMultiplier());
|
||||||
|
|
||||||
if(isFlying()) {
|
if(isFlying()){
|
||||||
x += velocity.x / getMass() * Timers.delta();
|
x += velocity.x / getMass() * Timers.delta();
|
||||||
y += velocity.y / 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);
|
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){
|
if(onLiquid && floor.drownTime > 0){
|
||||||
drownTime += Timers.delta() * 1f/floor.drownTime;
|
drownTime += Timers.delta() * 1f / floor.drownTime;
|
||||||
if(Timers.get(this, "drowneffect", 15)){
|
if(Timers.get(this, "drowneffect", 15)){
|
||||||
Effects.effect(floor.drownUpdateEffect, floor.liquidColor, x, y);
|
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;
|
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){
|
public void applyEffect(StatusEffect effect, float intensity){
|
||||||
@@ -299,12 +308,17 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
|||||||
}
|
}
|
||||||
|
|
||||||
public float getAmmoFraction(){
|
public float getAmmoFraction(){
|
||||||
return inventory.totalAmmo() / (float)inventory.ammoCapacity();
|
return inventory.totalAmmo() / (float) inventory.ammoCapacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawUnder(){}
|
public void drawUnder(){
|
||||||
public void drawOver(){}
|
}
|
||||||
public void drawShadow(){}
|
|
||||||
|
public void drawOver(){
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawShadow(){
|
||||||
|
}
|
||||||
|
|
||||||
public void drawView(){
|
public void drawView(){
|
||||||
Fill.circle(x, y, getViewDistance());
|
Fill.circle(x, y, getViewDistance());
|
||||||
@@ -319,12 +333,20 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
|||||||
}
|
}
|
||||||
|
|
||||||
public abstract TextureRegion getIconRegion();
|
public abstract TextureRegion getIconRegion();
|
||||||
|
|
||||||
public abstract int getItemCapacity();
|
public abstract int getItemCapacity();
|
||||||
|
|
||||||
public abstract int getAmmoCapacity();
|
public abstract int getAmmoCapacity();
|
||||||
|
|
||||||
public abstract float getArmor();
|
public abstract float getArmor();
|
||||||
|
|
||||||
public abstract boolean acceptsAmmo(Item item);
|
public abstract boolean acceptsAmmo(Item item);
|
||||||
|
|
||||||
public abstract void addAmmo(Item item);
|
public abstract void addAmmo(Item item);
|
||||||
|
|
||||||
public abstract float getMass();
|
public abstract float getMass();
|
||||||
|
|
||||||
public abstract boolean isFlying();
|
public abstract boolean isFlying();
|
||||||
|
|
||||||
public abstract float getSize();
|
public abstract float getSize();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,16 +8,17 @@ import io.anuke.mindustry.type.AmmoType;
|
|||||||
import io.anuke.mindustry.type.Item;
|
import io.anuke.mindustry.type.Item;
|
||||||
import io.anuke.mindustry.type.ItemStack;
|
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{
|
public class UnitInventory implements Saveable{
|
||||||
|
private final Unit unit;
|
||||||
private Array<AmmoEntry> ammos = new Array<>();
|
private Array<AmmoEntry> ammos = new Array<>();
|
||||||
private int totalAmmo;
|
private int totalAmmo;
|
||||||
private ItemStack item = new ItemStack(Items.stone, 0);
|
private ItemStack item = new ItemStack(Items.stone, 0);
|
||||||
|
|
||||||
private final Unit unit;
|
public UnitInventory(Unit unit){
|
||||||
|
|
||||||
public UnitInventory(Unit unit) {
|
|
||||||
this.unit = unit;
|
this.unit = unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,24 +27,24 @@ public class UnitInventory implements Saveable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeSave(DataOutput stream) throws IOException {
|
public void writeSave(DataOutput stream) throws IOException{
|
||||||
stream.writeShort(item.amount);
|
stream.writeShort(item.amount);
|
||||||
stream.writeByte(item.item.id);
|
stream.writeByte(item.item.id);
|
||||||
stream.writeShort(totalAmmo);
|
stream.writeShort(totalAmmo);
|
||||||
stream.writeByte(ammos.size);
|
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.writeByte(ammos.get(i).type.id);
|
||||||
stream.writeShort(ammos.get(i).amount);
|
stream.writeShort(ammos.get(i).amount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readSave(DataInput stream) throws IOException {
|
public void readSave(DataInput stream) throws IOException{
|
||||||
short iamount = stream.readShort();
|
short iamount = stream.readShort();
|
||||||
byte iid = stream.readByte();
|
byte iid = stream.readByte();
|
||||||
this.totalAmmo = stream.readShort();
|
this.totalAmmo = stream.readShort();
|
||||||
byte ammoa = stream.readByte();
|
byte ammoa = stream.readByte();
|
||||||
for(int i = 0; i < ammoa; i ++){
|
for(int i = 0; i < ammoa; i++){
|
||||||
byte aid = stream.readByte();
|
byte aid = stream.readByte();
|
||||||
int am = stream.readShort();
|
int am = stream.readShort();
|
||||||
ammos.add(new AmmoEntry(AmmoType.getByID(aid), am));
|
ammos.add(new AmmoEntry(AmmoType.getByID(aid), am));
|
||||||
@@ -53,12 +54,14 @@ public class UnitInventory implements Saveable{
|
|||||||
item.amount = iamount;
|
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(){
|
public float getAmmoRange(){
|
||||||
return hasAmmo() ? getAmmo().getRange() : Float.MAX_VALUE;
|
return hasAmmo() ? getAmmo().getRange() : Float.MAX_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AmmoType getAmmo() {
|
public AmmoType getAmmo(){
|
||||||
return ammos.size == 0 ? null : ammos.peek().type;
|
return ammos.size == 0 ? null : ammos.peek().type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,9 +72,9 @@ public class UnitInventory implements Saveable{
|
|||||||
public void useAmmo(){
|
public void useAmmo(){
|
||||||
if(unit.isInfiniteAmmo()) return;
|
if(unit.isInfiniteAmmo()) return;
|
||||||
AmmoEntry entry = ammos.peek();
|
AmmoEntry entry = ammos.peek();
|
||||||
entry.amount --;
|
entry.amount--;
|
||||||
if(entry.amount == 0) ammos.pop();
|
if(entry.amount == 0) ammos.pop();
|
||||||
totalAmmo --;
|
totalAmmo--;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int totalAmmo(){
|
public int totalAmmo(){
|
||||||
@@ -91,19 +94,19 @@ public class UnitInventory implements Saveable{
|
|||||||
totalAmmo += type.quantityMultiplier;
|
totalAmmo += type.quantityMultiplier;
|
||||||
|
|
||||||
//find ammo entry by type
|
//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);
|
AmmoEntry entry = ammos.get(i);
|
||||||
|
|
||||||
//if found, put it to the right
|
//if found, put it to the right
|
||||||
if(entry.type == type){
|
if(entry.type == type){
|
||||||
entry.amount += type.quantityMultiplier;
|
entry.amount += type.quantityMultiplier;
|
||||||
ammos.swap(i, ammos.size-1);
|
ammos.swap(i, ammos.size - 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//must not be found
|
//must not be found
|
||||||
AmmoEntry entry = new AmmoEntry(type, (int)type.quantityMultiplier);
|
AmmoEntry entry = new AmmoEntry(type, (int) type.quantityMultiplier);
|
||||||
ammos.add(entry);
|
ammos.add(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,15 +15,19 @@ import io.anuke.ucore.function.Predicate;
|
|||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
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 rect = new Rectangle();
|
||||||
private static Rectangle hitrect = new Rectangle();
|
private static Rectangle hitrect = new Rectangle();
|
||||||
private static Unit result;
|
private static Unit result;
|
||||||
private static float cdist;
|
private static float cdist;
|
||||||
private static boolean boolResult;
|
private static boolean boolResult;
|
||||||
|
|
||||||
/**Validates a target.
|
/**
|
||||||
|
* Validates a target.
|
||||||
|
*
|
||||||
* @param target The target to validate
|
* @param target The target to validate
|
||||||
* @param team The team of the thing doing tha targeting
|
* @param team The team of the thing doing tha targeting
|
||||||
* @param x The X position of the thing doign the 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
|
* @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
|
* @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();
|
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){
|
public static boolean invalidateTarget(TargetTrait target, Team team, float x, float y){
|
||||||
return invalidateTarget(target, team, x, y, Float.MAX_VALUE);
|
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){
|
public static boolean invalidateTarget(TargetTrait target, Unit targeter){
|
||||||
return invalidateTarget(target, targeter.team, targeter.x, targeter.y, targeter.inventory.getAmmoRange());
|
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){
|
public static boolean anyEntities(Tile tile){
|
||||||
Block type = tile.block();
|
Block type = tile.block();
|
||||||
rect.setSize(type.size * tilesize, type.size * tilesize);
|
rect.setSize(type.size * tilesize, type.size * tilesize);
|
||||||
@@ -55,11 +65,11 @@ public class Units {
|
|||||||
boolResult = false;
|
boolResult = false;
|
||||||
|
|
||||||
Units.getNearby(rect, unit -> {
|
Units.getNearby(rect, unit -> {
|
||||||
if (boolResult) return;
|
if(boolResult) return;
|
||||||
if (!unit.isFlying()) {
|
if(!unit.isFlying()){
|
||||||
unit.getHitbox(hitrect);
|
unit.getHitbox(hitrect);
|
||||||
|
|
||||||
if (hitrect.overlaps(rect)) {
|
if(hitrect.overlaps(rect)){
|
||||||
boolResult = true;
|
boolResult = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -68,7 +78,9 @@ public class Units {
|
|||||||
return boolResult;
|
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<Unit> pred){
|
public static boolean anyEntities(Tile tile, float expansion, Predicate<Unit> pred){
|
||||||
Block type = tile.block();
|
Block type = tile.block();
|
||||||
rect.setSize(type.size * tilesize + expansion, type.size * tilesize + expansion);
|
rect.setSize(type.size * tilesize + expansion, type.size * tilesize + expansion);
|
||||||
@@ -81,7 +93,7 @@ public class Units {
|
|||||||
if(!unit.isFlying()){
|
if(!unit.isFlying()){
|
||||||
unit.getHitbox(hitrect);
|
unit.getHitbox(hitrect);
|
||||||
|
|
||||||
if(hitrect.overlaps(rect)) {
|
if(hitrect.overlaps(rect)){
|
||||||
value[0] = true;
|
value[0] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -90,7 +102,9 @@ public class Units {
|
|||||||
return value[0];
|
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<Tile> pred){
|
public static TileEntity findAllyTile(Team team, float x, float y, float range, Predicate<Tile> pred){
|
||||||
for(Team enemy : state.teams.alliesOf(team)){
|
for(Team enemy : state.teams.alliesOf(team)){
|
||||||
TileEntity entity = world.indexer().findTile(enemy, x, y, range, pred);
|
TileEntity entity = world.indexer().findTile(enemy, x, y, range, pred);
|
||||||
@@ -101,7 +115,9 @@ public class Units {
|
|||||||
return null;
|
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<Tile> pred){
|
public static TileEntity findEnemyTile(Team team, float x, float y, float range, Predicate<Tile> pred){
|
||||||
for(Team enemy : state.teams.enemiesOf(team)){
|
for(Team enemy : state.teams.enemiesOf(team)){
|
||||||
TileEntity entity = world.indexer().findTile(enemy, x, y, range, pred);
|
TileEntity entity = world.indexer().findTile(enemy, x, y, range, pred);
|
||||||
@@ -112,7 +128,9 @@ public class Units {
|
|||||||
return null;
|
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<Unit> cons){
|
public static void allUnits(Consumer<Unit> cons){
|
||||||
//check all unit groups first
|
//check all unit groups first
|
||||||
for(EntityGroup<BaseUnit> group : unitGroups){
|
for(EntityGroup<BaseUnit> 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){
|
public static TargetTrait getClosestTarget(Team team, float x, float y, float range){
|
||||||
Unit unit = getClosestEnemy(team, x, y, range, u -> true);
|
Unit unit = getClosestEnemy(team, x, y, range, u -> true);
|
||||||
if(unit != null){
|
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<Unit> predicate){
|
public static Unit getClosestEnemy(Team team, float x, float y, float range, Predicate<Unit> predicate){
|
||||||
result = null;
|
result = null;
|
||||||
cdist = 0f;
|
cdist = 0f;
|
||||||
|
|
||||||
rect.setSize(range*2f).setCenter(x, y);
|
rect.setSize(range * 2f).setCenter(x, y);
|
||||||
|
|
||||||
getNearbyEnemies(team, rect, e -> {
|
getNearbyEnemies(team, rect, e -> {
|
||||||
if (e.isDead() || !predicate.test(e))
|
if(e.isDead() || !predicate.test(e))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
float dist = Vector2.dst(e.x, e.y, x, y);
|
float dist = Vector2.dst(e.x, e.y, x, y);
|
||||||
if (dist < range) {
|
if(dist < range){
|
||||||
if (result == null || dist < cdist) {
|
if(result == null || dist < cdist){
|
||||||
result = e;
|
result = e;
|
||||||
cdist = dist;
|
cdist = dist;
|
||||||
}
|
}
|
||||||
@@ -162,20 +184,22 @@ public class Units {
|
|||||||
return result;
|
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<Unit> predicate){
|
public static Unit getClosest(Team team, float x, float y, float range, Predicate<Unit> predicate){
|
||||||
result = null;
|
result = null;
|
||||||
cdist = 0f;
|
cdist = 0f;
|
||||||
|
|
||||||
rect.setSize(range*2f).setCenter(x, y);
|
rect.setSize(range * 2f).setCenter(x, y);
|
||||||
|
|
||||||
getNearby(team, rect, e -> {
|
getNearby(team, rect, e -> {
|
||||||
if (!predicate.test(e))
|
if(!predicate.test(e))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
float dist = Vector2.dst(e.x, e.y, x, y);
|
float dist = Vector2.dst(e.x, e.y, x, y);
|
||||||
if (dist < range) {
|
if(dist < range){
|
||||||
if (result == null || dist < cdist) {
|
if(result == null || dist < cdist){
|
||||||
result = e;
|
result = e;
|
||||||
cdist = dist;
|
cdist = dist;
|
||||||
}
|
}
|
||||||
@@ -185,28 +209,32 @@ public class Units {
|
|||||||
return result;
|
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<Unit> cons){
|
public static void getNearby(Team team, Rectangle rect, Consumer<Unit> cons){
|
||||||
|
|
||||||
EntityGroup<BaseUnit> group = unitGroups[team.ordinal()];
|
EntityGroup<BaseUnit> group = unitGroups[team.ordinal()];
|
||||||
if(!group.isEmpty()){
|
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
|
//now check all players
|
||||||
EntityPhysics.getNearby(playerGroup, rect, player -> {
|
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<Unit> cons){
|
public static void getNearby(Team team, float x, float y, float radius, Consumer<Unit> cons){
|
||||||
rect.setSize(radius * 2).setCenter(x, y);
|
rect.setSize(radius * 2).setCenter(x, y);
|
||||||
|
|
||||||
EntityGroup<BaseUnit> group = unitGroups[team.ordinal()];
|
EntityGroup<BaseUnit> group = unitGroups[team.ordinal()];
|
||||||
if(!group.isEmpty()){
|
if(!group.isEmpty()){
|
||||||
EntityPhysics.getNearby(group, rect, entity -> {
|
EntityPhysics.getNearby(group, rect, entity -> {
|
||||||
if(entity.distanceTo(x, y) <= radius) {
|
if(entity.distanceTo(x, y) <= radius){
|
||||||
cons.accept((Unit) entity);
|
cons.accept((Unit) entity);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -214,46 +242,52 @@ public class Units {
|
|||||||
|
|
||||||
//now check all players
|
//now check all players
|
||||||
EntityPhysics.getNearby(playerGroup, rect, player -> {
|
EntityPhysics.getNearby(playerGroup, rect, player -> {
|
||||||
if(((Unit)player).team == team && player.distanceTo(x, y) <= radius){
|
if(((Unit) player).team == team && player.distanceTo(x, y) <= radius){
|
||||||
cons.accept((Unit)player);
|
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<Unit> cons){
|
public static void getNearby(Rectangle rect, Consumer<Unit> cons){
|
||||||
|
|
||||||
for(Team team : Team.all){
|
for(Team team : Team.all){
|
||||||
EntityGroup<BaseUnit> group = unitGroups[team.ordinal()];
|
EntityGroup<BaseUnit> group = unitGroups[team.ordinal()];
|
||||||
if(!group.isEmpty()){
|
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
|
//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<Unit> cons){
|
public static void getNearbyEnemies(Team team, Rectangle rect, Consumer<Unit> cons){
|
||||||
ObjectSet<Team> targets = state.teams.enemiesOf(team);
|
ObjectSet<Team> targets = state.teams.enemiesOf(team);
|
||||||
|
|
||||||
for(Team other : targets){
|
for(Team other : targets){
|
||||||
EntityGroup<BaseUnit> group = unitGroups[other.ordinal()];
|
EntityGroup<BaseUnit> group = unitGroups[other.ordinal()];
|
||||||
if(!group.isEmpty()){
|
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
|
//now check all enemy players
|
||||||
EntityPhysics.getNearby(playerGroup, rect, player -> {
|
EntityPhysics.getNearby(playerGroup, rect, player -> {
|
||||||
if(targets.contains(((Player)player).team)){
|
if(targets.contains(((Player) player).team)){
|
||||||
cons.accept((Unit)player);
|
cons.accept((Unit) player);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Iterates over all units.*/
|
/**
|
||||||
|
* Iterates over all units.
|
||||||
|
*/
|
||||||
public static void getAllUnits(Consumer<Unit> cons){
|
public static void getAllUnits(Consumer<Unit> cons){
|
||||||
|
|
||||||
for(Team team : Team.all){
|
for(Team team : Team.all){
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ import io.anuke.ucore.core.Effects.Effect;
|
|||||||
import io.anuke.ucore.graphics.Draw;
|
import io.anuke.ucore.graphics.Draw;
|
||||||
|
|
||||||
//TODO scale velocity depending on fslope()
|
//TODO scale velocity depending on fslope()
|
||||||
public class ArtilleryBulletType extends BasicBulletType {
|
public class ArtilleryBulletType extends BasicBulletType{
|
||||||
protected Effect trailEffect = BulletFx.artilleryTrail;
|
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);
|
super(speed, damage, bulletSprite);
|
||||||
collidesTiles = false;
|
collidesTiles = false;
|
||||||
collides = false;
|
collides = false;
|
||||||
@@ -17,18 +17,18 @@ public class ArtilleryBulletType extends BasicBulletType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Bullet b) {
|
public void update(Bullet b){
|
||||||
super.update(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);
|
Effects.effect(trailEffect, backColor, b.x, b.y, b.fslope() * 4f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(Bullet b) {
|
public void draw(Bullet b){
|
||||||
float baseScale = 0.7f;
|
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());
|
float height = bulletHeight * ((1f - bulletShrink) + bulletShrink * b.fout());
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,10 @@ import io.anuke.ucore.graphics.Draw;
|
|||||||
import io.anuke.ucore.util.Angles;
|
import io.anuke.ucore.util.Angles;
|
||||||
import io.anuke.ucore.util.Mathf;
|
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 Color backColor = Palette.bulletYellowBack, frontColor = Palette.bulletYellow;
|
||||||
public float bulletWidth = 5f, bulletHeight = 7f;
|
public float bulletWidth = 5f, bulletHeight = 7f;
|
||||||
public float bulletShrink = 0.5f;
|
public float bulletShrink = 0.5f;
|
||||||
@@ -23,7 +25,9 @@ public class BasicBulletType extends BulletType {
|
|||||||
public float fragVelocityMin = 0.2f, fragVelocityMax = 1f;
|
public float fragVelocityMin = 0.2f, fragVelocityMax = 1f;
|
||||||
public BulletType fragBullet = null;
|
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 splashDamageRadius = -1f;
|
||||||
public float splashDamage = 6f;
|
public float splashDamage = 6f;
|
||||||
|
|
||||||
@@ -39,19 +43,19 @@ public class BasicBulletType extends BulletType {
|
|||||||
|
|
||||||
public float hitShake = 0f;
|
public float hitShake = 0f;
|
||||||
|
|
||||||
public BasicBulletType(float speed, float damage, String bulletSprite) {
|
public BasicBulletType(float speed, float damage, String bulletSprite){
|
||||||
super(speed, damage);
|
super(speed, damage);
|
||||||
this.bulletSprite = bulletSprite;
|
this.bulletSprite = bulletSprite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load(){
|
||||||
backRegion = Draw.region(bulletSprite + "-back");
|
backRegion = Draw.region(bulletSprite + "-back");
|
||||||
frontRegion = Draw.region(bulletSprite);
|
frontRegion = Draw.region(bulletSprite);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(Bullet b) {
|
public void draw(Bullet b){
|
||||||
float height = bulletHeight * ((1f - bulletShrink) + bulletShrink * b.fout());
|
float height = bulletHeight * ((1f - bulletShrink) + bulletShrink * b.fout());
|
||||||
|
|
||||||
Draw.color(backColor);
|
Draw.color(backColor);
|
||||||
@@ -62,7 +66,7 @@ public class BasicBulletType extends BulletType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Bullet b) {
|
public void update(Bullet b){
|
||||||
super.update(b);
|
super.update(b);
|
||||||
|
|
||||||
if(homingPower > 0.0001f){
|
if(homingPower > 0.0001f){
|
||||||
@@ -74,20 +78,20 @@ public class BasicBulletType extends BulletType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void hit(Bullet b, float x, float y) {
|
public void hit(Bullet b, float x, float y){
|
||||||
super.hit(b, x, y);
|
super.hit(b, x, y);
|
||||||
|
|
||||||
Effects.shake(hitShake, hitShake, b);
|
Effects.shake(hitShake, hitShake, b);
|
||||||
|
|
||||||
if(fragBullet != null) {
|
if(fragBullet != null){
|
||||||
for (int i = 0; i < fragBullets; i++) {
|
for(int i = 0; i < fragBullets; i++){
|
||||||
float len = Mathf.random(1f, 7f);
|
float len = Mathf.random(1f, 7f);
|
||||||
float a = Mathf.random(360f);
|
float a = Mathf.random(360f);
|
||||||
Bullet.create(fragBullet, b, x + Angles.trnsx(a, len), y + Angles.trnsy(a, len), a, Mathf.random(fragVelocityMin, fragVelocityMax));
|
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);
|
Damage.createIncend(x, y, incendSpread, incendAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,7 +101,7 @@ public class BasicBulletType extends BulletType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void despawned(Bullet b) {
|
public void despawned(Bullet b){
|
||||||
if(fragBullet != null || splashDamageRadius > 0){
|
if(fragBullet != null || splashDamageRadius > 0){
|
||||||
hit(b);
|
hit(b);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package io.anuke.mindustry.entities.bullet;
|
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);
|
super(0.7f, 0, sprite);
|
||||||
splashDamageRadius = radius;
|
splashDamageRadius = radius;
|
||||||
splashDamage = damage;
|
splashDamage = damage;
|
||||||
|
|||||||
@@ -28,26 +28,30 @@ import static io.anuke.mindustry.Vars.world;
|
|||||||
|
|
||||||
public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncTrait{
|
public class Bullet extends BulletEntity<BulletType> 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 Team team;
|
||||||
private Object data;
|
private Object data;
|
||||||
private boolean supressCollision;
|
private boolean supressCollision;
|
||||||
|
|
||||||
public Timer timer = new Timer(3);
|
/**
|
||||||
|
* Internal use only!
|
||||||
|
*/
|
||||||
|
public Bullet(){
|
||||||
|
}
|
||||||
|
|
||||||
public static void create (BulletType type, TeamTrait owner, float x, float y, float angle){
|
public static void create(BulletType type, TeamTrait owner, float x, float y, float angle){
|
||||||
create(type, owner, owner.getTeam(), x, y, 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){
|
public static void create(BulletType type, Entity owner, Team team, float x, float y, float angle){
|
||||||
create(type, owner, team, x, y, angle, 1f);
|
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){
|
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);
|
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){
|
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 bullet = Pooling.obtain(Bullet.class);
|
||||||
bullet.type = type;
|
bullet.type = type;
|
||||||
bullet.owner = owner;
|
bullet.owner = owner;
|
||||||
@@ -55,7 +59,7 @@ public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncT
|
|||||||
|
|
||||||
bullet.velocity.set(0, type.speed).setAngle(angle).scl(velocityScl);
|
bullet.velocity.set(0, type.speed).setAngle(angle).scl(velocityScl);
|
||||||
if(type.keepVelocity){
|
if(type.keepVelocity){
|
||||||
bullet.velocity.add(owner instanceof VelocityTrait ? ((VelocityTrait)owner).getVelocity() : Vector2.Zero);
|
bullet.velocity.add(owner instanceof VelocityTrait ? ((VelocityTrait) owner).getVelocity() : Vector2.Zero);
|
||||||
}
|
}
|
||||||
bullet.hitbox.setSize(type.hitsize);
|
bullet.hitbox.setSize(type.hitsize);
|
||||||
|
|
||||||
@@ -65,10 +69,10 @@ public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncT
|
|||||||
//translate bullets backwards, purely for visual reasons
|
//translate bullets backwards, purely for visual reasons
|
||||||
float backDelta = Timers.delta();
|
float backDelta = Timers.delta();
|
||||||
|
|
||||||
bullet.lastPosition().set(x-bullet.velocity.x * backDelta, y-bullet.velocity.y * backDelta, bullet.angle());
|
bullet.lastPosition().set(x - bullet.velocity.x * backDelta, y - bullet.velocity.y * backDelta, bullet.angle());
|
||||||
bullet.setLastUpdated(TimeUtils.millis());
|
bullet.setLastUpdated(TimeUtils.millis());
|
||||||
bullet.setUpdateSpacing((long)((Timers.delta() / 60f) * 1000));
|
bullet.setUpdateSpacing((long) ((Timers.delta() / 60f) * 1000));
|
||||||
bullet.set(x-bullet.velocity.x * backDelta, y-bullet.velocity.y * backDelta);
|
bullet.set(x - bullet.velocity.x * backDelta, y - bullet.velocity.y * backDelta);
|
||||||
|
|
||||||
bullet.add();
|
bullet.add();
|
||||||
}
|
}
|
||||||
@@ -86,9 +90,6 @@ public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncT
|
|||||||
create(type, null, Team.none, x, y, angle);
|
create(type, null, Team.none, x, y, angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Internal use only!*/
|
|
||||||
public Bullet(){}
|
|
||||||
|
|
||||||
public boolean collidesTiles(){
|
public boolean collidesTiles(){
|
||||||
return type.collidesTiles;
|
return type.collidesTiles;
|
||||||
}
|
}
|
||||||
@@ -106,7 +107,7 @@ public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncT
|
|||||||
time += add;
|
time += add;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getData() {
|
public Object getData(){
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,7 +126,7 @@ public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncT
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(DataOutput data) throws IOException {
|
public void write(DataOutput data) throws IOException{
|
||||||
data.writeFloat(x);
|
data.writeFloat(x);
|
||||||
data.writeFloat(y);
|
data.writeFloat(y);
|
||||||
data.writeFloat(velocity.x);
|
data.writeFloat(velocity.x);
|
||||||
@@ -145,7 +146,7 @@ public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncT
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Team getTeam() {
|
public Team getTeam(){
|
||||||
return team;
|
return team;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,7 +170,7 @@ public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncT
|
|||||||
super.collision(other, x, y);
|
super.collision(other, x, y);
|
||||||
|
|
||||||
if(other instanceof Unit){
|
if(other instanceof Unit){
|
||||||
Unit unit = (Unit)other;
|
Unit unit = (Unit) other;
|
||||||
unit.getVelocity().add(vector.set(other.getX(), other.getY()).sub(x, y).setLength(type.knockback / unit.getMass()));
|
unit.getVelocity().add(vector.set(other.getX(), other.getY()).sub(x, y).setLength(type.knockback / unit.getMass()));
|
||||||
unit.applyEffect(type.status, type.statusIntensity);
|
unit.applyEffect(type.status, type.statusIntensity);
|
||||||
}
|
}
|
||||||
@@ -179,14 +180,14 @@ public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncT
|
|||||||
public void update(){
|
public void update(){
|
||||||
super.update();
|
super.update();
|
||||||
|
|
||||||
if (type.hitTiles && collidesTiles() && !supressCollision) {
|
if(type.hitTiles && collidesTiles() && !supressCollision){
|
||||||
world.raycastEach(world.toTile(lastPosition().x), world.toTile(lastPosition().y), world.toTile(x), world.toTile(y), (x, y) -> {
|
world.raycastEach(world.toTile(lastPosition().x), world.toTile(lastPosition().y), world.toTile(x), world.toTile(y), (x, y) -> {
|
||||||
|
|
||||||
Tile tile = world.tile(x, y);
|
Tile tile = world.tile(x, y);
|
||||||
if (tile == null) return false;
|
if(tile == null) return false;
|
||||||
tile = tile.target();
|
tile = tile.target();
|
||||||
|
|
||||||
if (tile.entity != null && tile.entity.collide(this) && !tile.entity.isDead() && tile.entity.tile.getTeam() != team) {
|
if(tile.entity != null && tile.entity.collide(this) && !tile.entity.isDead() && tile.entity.tile.getTeam() != team){
|
||||||
tile.entity.collision(this);
|
tile.entity.collision(this);
|
||||||
|
|
||||||
if(!supressCollision){
|
if(!supressCollision){
|
||||||
@@ -205,7 +206,7 @@ public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncT
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reset() {
|
public void reset(){
|
||||||
super.reset();
|
super.reset();
|
||||||
timer.clear();
|
timer.clear();
|
||||||
team = null;
|
team = null;
|
||||||
@@ -213,12 +214,12 @@ public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncT
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removed() {
|
public void removed(){
|
||||||
Pooling.free(this);
|
Pooling.free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityGroup targetGroup() {
|
public EntityGroup targetGroup(){
|
||||||
return bulletGroup;
|
return bulletGroup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,27 +13,45 @@ public abstract class BulletType extends BaseBulletType<Bullet> implements Conte
|
|||||||
private static Array<BulletType> types = new Array<>();
|
private static Array<BulletType> types = new Array<>();
|
||||||
|
|
||||||
public final int id;
|
public final int id;
|
||||||
/**Knockback in velocity.*/
|
/**
|
||||||
|
* Knockback in velocity.
|
||||||
|
*/
|
||||||
public float knockback;
|
public float knockback;
|
||||||
/**Whether this bullet hits tiles.*/
|
/**
|
||||||
|
* Whether this bullet hits tiles.
|
||||||
|
*/
|
||||||
public boolean hitTiles = true;
|
public boolean hitTiles = true;
|
||||||
/**Status effect applied on hit.*/
|
/**
|
||||||
|
* Status effect applied on hit.
|
||||||
|
*/
|
||||||
public StatusEffect status = StatusEffects.none;
|
public StatusEffect status = StatusEffects.none;
|
||||||
/**Intensity of applied status effect in terms of duration.*/
|
/**
|
||||||
|
* Intensity of applied status effect in terms of duration.
|
||||||
|
*/
|
||||||
public float statusIntensity = 0.5f;
|
public float statusIntensity = 0.5f;
|
||||||
/**What fraction of armor is pierced, 0-1*/
|
/**
|
||||||
|
* What fraction of armor is pierced, 0-1
|
||||||
|
*/
|
||||||
public float armorPierce = 0f;
|
public float armorPierce = 0f;
|
||||||
/**Whether to sync this bullet to clients.*/
|
/**
|
||||||
|
* Whether to sync this bullet to clients.
|
||||||
|
*/
|
||||||
public boolean syncable;
|
public boolean syncable;
|
||||||
/**Whether this bullet type collides with tiles.*/
|
/**
|
||||||
|
* Whether this bullet type collides with tiles.
|
||||||
|
*/
|
||||||
public boolean collidesTiles = true;
|
public boolean collidesTiles = true;
|
||||||
/**Whether this bullet types collides with anything at all.*/
|
/**
|
||||||
|
* Whether this bullet types collides with anything at all.
|
||||||
|
*/
|
||||||
public boolean collides = true;
|
public boolean collides = true;
|
||||||
/**Whether velocity is inherited from the shooter.*/
|
/**
|
||||||
|
* Whether velocity is inherited from the shooter.
|
||||||
|
*/
|
||||||
public boolean keepVelocity = true;
|
public boolean keepVelocity = true;
|
||||||
|
|
||||||
public BulletType(float speed, float damage){
|
public BulletType(float speed, float damage){
|
||||||
this.id = lastid ++;
|
this.id = lastid++;
|
||||||
this.speed = speed;
|
this.speed = speed;
|
||||||
this.damage = damage;
|
this.damage = damage;
|
||||||
lifetime = 40f;
|
lifetime = 40f;
|
||||||
@@ -43,6 +61,14 @@ public abstract class BulletType extends BaseBulletType<Bullet> implements Conte
|
|||||||
types.add(this);
|
types.add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static BulletType getByID(int id){
|
||||||
|
return types.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Array<BulletType> all(){
|
||||||
|
return types;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void hit(Bullet b, float hitx, float hity){
|
public void hit(Bullet b, float hitx, float hity){
|
||||||
Effects.effect(hiteffect, hitx, hity, b.angle());
|
Effects.effect(hiteffect, hitx, hity, b.angle());
|
||||||
@@ -54,20 +80,12 @@ public abstract class BulletType extends BaseBulletType<Bullet> implements Conte
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getContentTypeName() {
|
public String getContentTypeName(){
|
||||||
return "bullettype";
|
return "bullettype";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Array<? extends Content> getAll() {
|
public Array<? extends Content> getAll(){
|
||||||
return types;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BulletType getByID(int id){
|
|
||||||
return types.get(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Array<BulletType> all(){
|
|
||||||
return types;
|
return types;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,10 @@ import io.anuke.ucore.util.Mathf;
|
|||||||
import static io.anuke.mindustry.Vars.tilesize;
|
import static io.anuke.mindustry.Vars.tilesize;
|
||||||
import static io.anuke.mindustry.Vars.world;
|
import static io.anuke.mindustry.Vars.world;
|
||||||
|
|
||||||
public class LiquidBulletType extends BulletType {
|
public class LiquidBulletType extends BulletType{
|
||||||
Liquid liquid;
|
Liquid liquid;
|
||||||
|
|
||||||
public LiquidBulletType(Liquid liquid) {
|
public LiquidBulletType(Liquid liquid){
|
||||||
super(2.5f, 0);
|
super(2.5f, 0);
|
||||||
this.liquid = liquid;
|
this.liquid = liquid;
|
||||||
|
|
||||||
@@ -31,14 +31,14 @@ public class LiquidBulletType extends BulletType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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));
|
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
|
@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);
|
Effects.effect(hiteffect, liquid.color, hitx, hity);
|
||||||
Puddle.deposit(world.tileWorld(hitx, hity), liquid, 5f);
|
Puddle.deposit(world.tileWorld(hitx, hity), liquid, 5f);
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ public class LiquidBulletType extends BulletType {
|
|||||||
float intensity = 400f;
|
float intensity = 400f;
|
||||||
Fire.extinguish(world.tileWorld(hitx, hity), intensity);
|
Fire.extinguish(world.tileWorld(hitx, hity), intensity);
|
||||||
for(GridPoint2 p : Geometry.d4){
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import io.anuke.mindustry.content.fx.BulletFx;
|
|||||||
import io.anuke.mindustry.graphics.Palette;
|
import io.anuke.mindustry.graphics.Palette;
|
||||||
import io.anuke.ucore.core.Effects;
|
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);
|
super(speed, damage, bulletSprite);
|
||||||
backColor = Palette.missileYellowBack;
|
backColor = Palette.missileYellowBack;
|
||||||
frontColor = Palette.missileYellow;
|
frontColor = Palette.missileYellow;
|
||||||
@@ -14,7 +14,7 @@ public class MissileBulletType extends BasicBulletType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Bullet b) {
|
public void update(Bullet b){
|
||||||
super.update(b);
|
super.update(b);
|
||||||
|
|
||||||
if(b.timer.get(0, 4f)){
|
if(b.timer.get(0, 4f)){
|
||||||
|
|||||||
@@ -10,24 +10,26 @@ import io.anuke.ucore.util.Mathf;
|
|||||||
|
|
||||||
import static io.anuke.mindustry.Vars.groundEffectGroup;
|
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");
|
private static final Color color = Color.valueOf("52504e");
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float lifetime() {
|
public float lifetime(){
|
||||||
return 8200f;
|
return 8200f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(){
|
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();
|
drawDecal();
|
||||||
Draw.color();
|
Draw.color();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityGroup targetGroup() {
|
public EntityGroup targetGroup(){
|
||||||
return groundEffectGroup;
|
return groundEffectGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import java.io.IOException;
|
|||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
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<Fire> map = new IntMap<>();
|
private static final IntMap<Fire> map = new IntMap<>();
|
||||||
private static final float baseLifetime = 1000f;
|
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 baseFlammability = -1, puddleFlammability;
|
||||||
private float lifetime;
|
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){
|
public static void create(Tile tile){
|
||||||
if(Net.client() || tile == null) return; //not clientside.
|
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) {
|
* Attempts to extinguish a fire by shortening its life. If there is no fire here, does nothing.
|
||||||
if (tile != null && map.containsKey(tile.packedPosition())) {
|
*/
|
||||||
|
public static void extinguish(Tile tile, float intensity){
|
||||||
|
if(tile != null && map.containsKey(tile.packedPosition())){
|
||||||
map.get(tile.packedPosition()).time += intensity * Timers.delta();
|
map.get(tile.packedPosition()).time += intensity * Timers.delta();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Deserialization use only!*/
|
@Remote(called = Loc.server, in = In.entities)
|
||||||
public Fire(){}
|
public static void onFireRemoved(int fireid){
|
||||||
|
fireGroup.removeByID(fireid);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float lifetime() {
|
public float lifetime(){
|
||||||
return lifetime;
|
return lifetime;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update() {
|
public void update(){
|
||||||
if(Mathf.chance(0.1 * Timers.delta())) {
|
if(Mathf.chance(0.1 * Timers.delta())){
|
||||||
Effects.effect(EnvironmentFx.fire, x + Mathf.range(4f), y + Mathf.range(4f));
|
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;
|
float flammability = baseFlammability + puddleFlammability;
|
||||||
|
|
||||||
if(!damage && flammability <= 0){
|
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);
|
baseFlammability = tile.block().getFlammability(tile);
|
||||||
block = tile.block();
|
block = tile.block();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(damage) {
|
if(damage){
|
||||||
lifetime += Mathf.clamp(flammability / 8f, 0f, 0.6f) * Timers.delta();
|
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);
|
GridPoint2 p = Mathf.select(Geometry.d4);
|
||||||
Tile other = world.tile(tile.x + p.x, tile.y + p.y);
|
Tile other = world.tile(tile.x + p.x, tile.y + p.y);
|
||||||
create(other);
|
create(other);
|
||||||
@@ -128,7 +140,7 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable
|
|||||||
if(Mathf.chance(0.1 * Timers.delta())){
|
if(Mathf.chance(0.1 * Timers.delta())){
|
||||||
Puddle p = Puddle.getPuddle(tile);
|
Puddle p = Puddle.getPuddle(tile);
|
||||||
if(p != null){
|
if(p != null){
|
||||||
puddleFlammability = p.getFlammability()/3f;
|
puddleFlammability = p.getFlammability() / 3f;
|
||||||
}else{
|
}else{
|
||||||
puddleFlammability = 0;
|
puddleFlammability = 0;
|
||||||
}
|
}
|
||||||
@@ -141,14 +153,14 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeSave(DataOutput stream) throws IOException {
|
public void writeSave(DataOutput stream) throws IOException{
|
||||||
stream.writeInt(tile.packedPosition());
|
stream.writeInt(tile.packedPosition());
|
||||||
stream.writeFloat(lifetime);
|
stream.writeFloat(lifetime);
|
||||||
stream.writeFloat(time);
|
stream.writeFloat(time);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readSave(DataInput stream) throws IOException {
|
public void readSave(DataInput stream) throws IOException{
|
||||||
this.loadedPosition = stream.readInt();
|
this.loadedPosition = stream.readInt();
|
||||||
this.lifetime = stream.readFloat();
|
this.lifetime = stream.readFloat();
|
||||||
this.time = stream.readFloat();
|
this.time = stream.readFloat();
|
||||||
@@ -156,19 +168,19 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(DataOutput data) throws IOException {
|
public void write(DataOutput data) throws IOException{
|
||||||
data.writeFloat(x);
|
data.writeFloat(x);
|
||||||
data.writeFloat(y);
|
data.writeFloat(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(DataInput data, long time) throws IOException {
|
public void read(DataInput data, long time) throws IOException{
|
||||||
x = data.readFloat();
|
x = data.readFloat();
|
||||||
y = data.readFloat();
|
y = data.readFloat();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reset() {
|
public void reset(){
|
||||||
loadedPosition = -1;
|
loadedPosition = -1;
|
||||||
tile = null;
|
tile = null;
|
||||||
baseFlammability = -1;
|
baseFlammability = -1;
|
||||||
@@ -176,7 +188,7 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void added() {
|
public void added(){
|
||||||
if(loadedPosition != -1){
|
if(loadedPosition != -1){
|
||||||
map.put(loadedPosition, this);
|
map.put(loadedPosition, this);
|
||||||
tile = world.tile(loadedPosition);
|
tile = world.tile(loadedPosition);
|
||||||
@@ -185,7 +197,7 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removed() {
|
public void removed(){
|
||||||
if(tile != null){
|
if(tile != null){
|
||||||
map.remove(tile.packedPosition());
|
map.remove(tile.packedPosition());
|
||||||
}
|
}
|
||||||
@@ -193,12 +205,7 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityGroup targetGroup() {
|
public EntityGroup targetGroup(){
|
||||||
return fireGroup;
|
return fireGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Remote(called = Loc.server, in = In.entities)
|
|
||||||
public static void onFireRemoved(int fireid){
|
|
||||||
fireGroup.removeByID(fireid);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,27 +9,29 @@ import io.anuke.ucore.entities.impl.EffectEntity;
|
|||||||
import io.anuke.ucore.function.EffectRenderer;
|
import io.anuke.ucore.function.EffectRenderer;
|
||||||
import io.anuke.ucore.util.Mathf;
|
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;
|
private boolean once;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(){
|
public void update(){
|
||||||
GroundEffect effect = (GroundEffect)this.effect;
|
GroundEffect effect = (GroundEffect) this.effect;
|
||||||
|
|
||||||
if(effect.isStatic) {
|
if(effect.isStatic){
|
||||||
time += Timers.delta();
|
time += Timers.delta();
|
||||||
|
|
||||||
time = Mathf.clamp(time, 0, effect.staticLife);
|
time = Mathf.clamp(time, 0, effect.staticLife);
|
||||||
|
|
||||||
if (!once && time >= lifetime()) {
|
if(!once && time >= lifetime()){
|
||||||
once = true;
|
once = true;
|
||||||
time = 0f;
|
time = 0f;
|
||||||
Tile tile = Vars.world.tileWorld(x, y);
|
Tile tile = Vars.world.tileWorld(x, y);
|
||||||
if(tile != null && tile.floor().isLiquid){
|
if(tile != null && tile.floor().isLiquid){
|
||||||
remove();
|
remove();
|
||||||
}
|
}
|
||||||
} else if (once && time >= effect.staticLife) {
|
}else if(once && time >= effect.staticLife){
|
||||||
remove();
|
remove();
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
@@ -39,7 +41,7 @@ public class GroundEffectEntity extends EffectEntity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(){
|
public void draw(){
|
||||||
GroundEffect effect = (GroundEffect)this.effect;
|
GroundEffect effect = (GroundEffect) this.effect;
|
||||||
|
|
||||||
if(once && effect.isStatic)
|
if(once && effect.isStatic)
|
||||||
Effects.renderEffect(id, effect, color, lifetime(), rotation, x, y, data);
|
Effects.renderEffect(id, effect, color, lifetime(), rotation, x, y, data);
|
||||||
@@ -48,32 +50,38 @@ public class GroundEffectEntity extends EffectEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reset() {
|
public void reset(){
|
||||||
super.reset();
|
super.reset();
|
||||||
once = false;
|
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{
|
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;
|
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 final boolean isStatic;
|
||||||
|
|
||||||
public GroundEffect(float life, float staticLife, EffectRenderer draw) {
|
public GroundEffect(float life, float staticLife, EffectRenderer draw){
|
||||||
super(life, draw);
|
super(life, draw);
|
||||||
this.staticLife = staticLife;
|
this.staticLife = staticLife;
|
||||||
this.isStatic = true;
|
this.isStatic = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GroundEffect(boolean isStatic, float life, EffectRenderer draw) {
|
public GroundEffect(boolean isStatic, float life, EffectRenderer draw){
|
||||||
super(life, draw);
|
super(life, draw);
|
||||||
this.staticLife = 0f;
|
this.staticLife = 0f;
|
||||||
this.isStatic = isStatic;
|
this.isStatic = isStatic;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GroundEffect(float life, EffectRenderer draw) {
|
public GroundEffect(float life, EffectRenderer draw){
|
||||||
super(life, draw);
|
super(life, draw);
|
||||||
this.staticLife = 0f;
|
this.staticLife = 0f;
|
||||||
this.isStatic = false;
|
this.isStatic = false;
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ import java.io.IOException;
|
|||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
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 static final float sinkLifetime = 80f;
|
||||||
|
|
||||||
private Interpolator interpolator = new Interpolator();
|
private Interpolator interpolator = new Interpolator();
|
||||||
@@ -46,6 +46,14 @@ public class ItemDrop extends SolidEntity implements SaveTrait, SyncTrait, DrawT
|
|||||||
private float time;
|
private float time;
|
||||||
private float sinktime;
|
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){
|
public static ItemDrop create(Item item, int amount, float x, float y, float angle){
|
||||||
ItemDrop drop = new ItemDrop();
|
ItemDrop drop = new ItemDrop();
|
||||||
drop.item = item;
|
drop.item = item;
|
||||||
@@ -73,13 +81,7 @@ public class ItemDrop extends SolidEntity implements SaveTrait, SyncTrait, DrawT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Internal use only!*/
|
public Item getItem(){
|
||||||
public ItemDrop(){
|
|
||||||
hitbox.setSize(5f);
|
|
||||||
hitboxTile.setSize(5f);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Item getItem() {
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,66 +90,66 @@ public class ItemDrop extends SolidEntity implements SaveTrait, SyncTrait, DrawT
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDead() {
|
public boolean isDead(){
|
||||||
return !isAdded();
|
return !isAdded();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Team getTeam() {
|
public Team getTeam(){
|
||||||
return Team.none;
|
return Team.none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float lifetime() {
|
public float lifetime(){
|
||||||
return 60*60;
|
return 60 * 60;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void time(float time) {
|
public void time(float time){
|
||||||
this.time = time;
|
this.time = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float time() {
|
public float time(){
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vector2 getVelocity() {
|
public Vector2 getVelocity(){
|
||||||
return velocity;
|
return velocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean collides(SolidTrait other) {
|
public boolean collides(SolidTrait other){
|
||||||
return other instanceof Player && time > 20f;
|
return other instanceof Player && time > 20f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void collision(SolidTrait other, float x, float y) {
|
public void collision(SolidTrait other, float x, float y){
|
||||||
Unit player = (Unit)other;
|
Unit player = (Unit) other;
|
||||||
if(player.inventory.canAcceptItem(item, 1)){
|
if(player.inventory.canAcceptItem(item, 1)){
|
||||||
int used = Math.min(amount, player.inventory.capacity() - player.inventory.getItem().amount);
|
int used = Math.min(amount, player.inventory.capacity() - player.inventory.getItem().amount);
|
||||||
player.inventory.addItem(item, used);
|
player.inventory.addItem(item, used);
|
||||||
amount -= used;
|
amount -= used;
|
||||||
|
|
||||||
if(amount <= 0) {
|
if(amount <= 0){
|
||||||
CallEntity.onPickup(getID());
|
CallEntity.onPickup(getID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw() {
|
public void draw(){
|
||||||
float size = itemSize * (1f - sinktime/sinkLifetime) * (1f-Mathf.curve(fin(), 0.98f));
|
float size = itemSize * (1f - sinktime / sinkLifetime) * (1f - Mathf.curve(fin(), 0.98f));
|
||||||
|
|
||||||
Tile tile = world.tileWorld(x, y);
|
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);
|
Draw.rect(item.region, x, y, size, size);
|
||||||
|
|
||||||
int stored = Mathf.clamp(amount / 6, 1, 8);
|
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 px = stored == 1 ? 0 : Mathf.randomSeedRange(i + 1, 4f);
|
||||||
float py = stored == 1 ? 0 : Mathf.randomSeedRange(i + 2, 4f);
|
float py = stored == 1 ? 0 : Mathf.randomSeedRange(i + 2, 4f);
|
||||||
Draw.rect(item.region, x + px, y + py, size, size);
|
Draw.rect(item.region, x + px, y + py, size, size);
|
||||||
@@ -157,8 +159,8 @@ public class ItemDrop extends SolidEntity implements SaveTrait, SyncTrait, DrawT
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update() {
|
public void update(){
|
||||||
if(Net.client()) {
|
if(Net.client()){
|
||||||
interpolate();
|
interpolate();
|
||||||
}else{
|
}else{
|
||||||
updateVelocity(0.2f);
|
updateVelocity(0.2f);
|
||||||
@@ -190,28 +192,28 @@ public class ItemDrop extends SolidEntity implements SaveTrait, SyncTrait, DrawT
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reset() {
|
public void reset(){
|
||||||
time = 0f;
|
time = 0f;
|
||||||
interpolator.reset();
|
interpolator.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Interpolator getInterpolator() {
|
public Interpolator getInterpolator(){
|
||||||
return interpolator;
|
return interpolator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float drawSize() {
|
public float drawSize(){
|
||||||
return 10;
|
return 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityGroup targetGroup() {
|
public EntityGroup targetGroup(){
|
||||||
return itemGroup;
|
return itemGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeSave(DataOutput data) throws IOException {
|
public void writeSave(DataOutput data) throws IOException{
|
||||||
data.writeFloat(x);
|
data.writeFloat(x);
|
||||||
data.writeFloat(y);
|
data.writeFloat(y);
|
||||||
data.writeByte(item.id);
|
data.writeByte(item.id);
|
||||||
@@ -219,7 +221,7 @@ public class ItemDrop extends SolidEntity implements SaveTrait, SyncTrait, DrawT
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readSave(DataInput data) throws IOException {
|
public void readSave(DataInput data) throws IOException{
|
||||||
x = data.readFloat();
|
x = data.readFloat();
|
||||||
y = data.readFloat();
|
y = data.readFloat();
|
||||||
item = Item.getByID(data.readByte());
|
item = Item.getByID(data.readByte());
|
||||||
|
|||||||
@@ -32,17 +32,22 @@ public class ItemTransfer extends TimedEntity implements DrawTrait{
|
|||||||
private PosTrait to;
|
private PosTrait to;
|
||||||
private Runnable done;
|
private Runnable done;
|
||||||
|
|
||||||
|
public ItemTransfer(){
|
||||||
|
}
|
||||||
|
|
||||||
@Remote(in = In.entities, called = Loc.server, unreliable = true)
|
@Remote(in = In.entities, called = Loc.server, unreliable = true)
|
||||||
public static void transferAmmo(Item item, float x, float y, Unit to){
|
public static void transferAmmo(Item item, float x, float y, Unit to){
|
||||||
if(to == null) return;
|
if(to == null) return;
|
||||||
to.addAmmo(item);
|
to.addAmmo(item);
|
||||||
create(item, x, y, to, () -> {});
|
create(item, x, y, to, () -> {
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Remote(in = In.entities, called = Loc.server, unreliable = true)
|
@Remote(in = In.entities, called = Loc.server, unreliable = true)
|
||||||
public static void transferItemEffect(Item item, float x, float y, Unit to){
|
public static void transferItemEffect(Item item, float x, float y, Unit to){
|
||||||
if(to == null) return;
|
if(to == null) return;
|
||||||
create(item, x, y, to, () -> {});
|
create(item, x, y, to, () -> {
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Remote(in = In.entities, called = Loc.server, unreliable = true)
|
@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)
|
@Remote(in = In.entities, called = Loc.server)
|
||||||
public static void transferItemTo(Item item, int amount, float x, float y, Tile tile){
|
public static void transferItemTo(Item item, int amount, float x, float y, Tile tile){
|
||||||
if(tile == null) return;
|
if(tile == null) return;
|
||||||
for (int i = 0; i < Mathf.clamp(amount/3, 1, 8); i++) {
|
for(int i = 0; i < Mathf.clamp(amount / 3, 1, 8); i++){
|
||||||
Timers.run(i*3, () -> create(item, x, y, tile, () -> {}));
|
Timers.run(i * 3, () -> create(item, x, y, tile, () -> {
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
tile.entity.items.add(item, amount);
|
tile.entity.items.add(item, amount);
|
||||||
}
|
}
|
||||||
@@ -70,15 +76,13 @@ public class ItemTransfer extends TimedEntity implements DrawTrait{
|
|||||||
tr.add();
|
tr.add();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemTransfer(){}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float lifetime() {
|
public float lifetime(){
|
||||||
return 60;
|
return 60;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reset() {
|
public void reset(){
|
||||||
super.reset();
|
super.reset();
|
||||||
item = null;
|
item = null;
|
||||||
to = null;
|
to = null;
|
||||||
@@ -89,7 +93,7 @@ public class ItemTransfer extends TimedEntity implements DrawTrait{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removed() {
|
public void removed(){
|
||||||
if(done != null){
|
if(done != null){
|
||||||
threads.run(done);
|
threads.run(done);
|
||||||
}
|
}
|
||||||
@@ -97,7 +101,7 @@ public class ItemTransfer extends TimedEntity implements DrawTrait{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update() {
|
public void update(){
|
||||||
if(to == null){
|
if(to == null){
|
||||||
remove();
|
remove();
|
||||||
return;
|
return;
|
||||||
@@ -110,24 +114,24 @@ public class ItemTransfer extends TimedEntity implements DrawTrait{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw() {
|
public void draw(){
|
||||||
float length = fslope()*6f;
|
float length = fslope() * 6f;
|
||||||
float angle = current.set(x, y).sub(from).angle();
|
float angle = current.set(x, y).sub(from).angle();
|
||||||
Draw.color(Palette.accent);
|
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.lineAngleCenter(x, y, angle, length);
|
||||||
Lines.lineAngle(x, y, angle, fout()*6f);
|
Lines.lineAngle(x, y, angle, fout() * 6f);
|
||||||
|
|
||||||
Draw.color(item.color);
|
Draw.color(item.color);
|
||||||
Fill.circle(x, y, fslope()*1.5f);
|
Fill.circle(x, y, fslope() * 1.5f);
|
||||||
|
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityGroup targetGroup() {
|
public EntityGroup targetGroup(){
|
||||||
return effectGroup;
|
return effectGroup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,15 @@ public class Lightning extends TimedEntity implements Poolable, DrawTrait, SyncT
|
|||||||
private Color color = Palette.lancerLaser;
|
private Color color = Palette.lancerLaser;
|
||||||
private SeedRandom random = new SeedRandom();
|
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){
|
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);
|
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);
|
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));
|
l.lines.add(new Vector2(x, y));
|
||||||
|
|
||||||
float fx = x, fy = y;
|
float fx = x, fy = y;
|
||||||
@@ -82,15 +90,15 @@ public class Lightning extends TimedEntity implements Poolable, DrawTrait, SyncT
|
|||||||
|
|
||||||
Units.getNearbyEnemies(team, rect, entity -> {
|
Units.getNearbyEnemies(team, rect, entity -> {
|
||||||
float dst = entity.distanceTo(x2, y2);
|
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);
|
angle = Mathf.slerp(angle, Angles.angle(x2, y2, entity.x, entity.y), (attractRange - dst) / attractRange / 4f);
|
||||||
}
|
}
|
||||||
|
|
||||||
entity.getHitbox(hitrect);
|
entity.getHitbox(hitrect);
|
||||||
hitrect.x -= range/2f;
|
hitrect.x -= range / 2f;
|
||||||
hitrect.y -= range/2f;
|
hitrect.y -= range / 2f;
|
||||||
hitrect.width += range/2f;
|
hitrect.width += range / 2f;
|
||||||
hitrect.height += range/2f;
|
hitrect.height += range / 2f;
|
||||||
|
|
||||||
if(hitrect.contains(x2, y2) || hitrect.contains(fx, fy)){
|
if(hitrect.contains(x2, y2) || hitrect.contains(fx, fy)){
|
||||||
float result = damage;
|
float result = damage;
|
||||||
@@ -104,7 +112,7 @@ public class Lightning extends TimedEntity implements Poolable, DrawTrait, SyncT
|
|||||||
});
|
});
|
||||||
|
|
||||||
if(l.random.chance(0.1f)){
|
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;
|
x = x2;
|
||||||
@@ -115,47 +123,44 @@ public class Lightning extends TimedEntity implements Poolable, DrawTrait, SyncT
|
|||||||
l.add();
|
l.add();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**For pooling use only. Do not call directly!*/
|
|
||||||
public Lightning(){}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSyncing() {
|
public boolean isSyncing(){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(DataOutput data) throws IOException {
|
public void write(DataOutput data) throws IOException{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(DataInput data, long time) throws IOException {
|
public void read(DataInput data, long time) throws IOException{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float lifetime() {
|
public float lifetime(){
|
||||||
return 10;
|
return 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reset() {
|
public void reset(){
|
||||||
color = Palette.lancerLaser;
|
color = Palette.lancerLaser;
|
||||||
lines.clear();
|
lines.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removed() {
|
public void removed(){
|
||||||
Pooling.free(this);
|
Pooling.free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw() {
|
public void draw(){
|
||||||
float lx = x, ly = y;
|
float lx = x, ly = y;
|
||||||
Draw.color(color, Color.WHITE, fin());
|
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);
|
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);
|
Lines.line(lx, ly, v.x, v.y);
|
||||||
lx = v.x;
|
lx = v.x;
|
||||||
ly = v.y;
|
ly = v.y;
|
||||||
@@ -164,7 +169,7 @@ public class Lightning extends TimedEntity implements Poolable, DrawTrait, SyncT
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityGroup targetGroup() {
|
public EntityGroup targetGroup(){
|
||||||
return bulletGroup;
|
return bulletGroup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ import java.io.IOException;
|
|||||||
import static io.anuke.mindustry.Vars.puddleGroup;
|
import static io.anuke.mindustry.Vars.puddleGroup;
|
||||||
import static io.anuke.mindustry.Vars.world;
|
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<Puddle> map = new IntMap<>();
|
private static final IntMap<Puddle> map = new IntMap<>();
|
||||||
private static final float maxLiquid = 70f;
|
private static final float maxLiquid = 70f;
|
||||||
private static final int maxGeneration = 2;
|
private static final int maxGeneration = 2;
|
||||||
@@ -58,17 +58,29 @@ public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait
|
|||||||
private float accepting;
|
private float accepting;
|
||||||
private byte generation;
|
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){
|
public static void deposit(Tile tile, Tile source, Liquid liquid, float amount){
|
||||||
deposit(tile, source, liquid, amount, 0);
|
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){
|
public static void deposit(Tile tile, Liquid liquid, float amount){
|
||||||
deposit(tile, tile, liquid, amount, 0);
|
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){
|
public static Puddle getPuddle(Tile tile){
|
||||||
return map.get(tile.packedPosition());
|
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){
|
private static void deposit(Tile tile, Tile source, Liquid liquid, float amount, int generation){
|
||||||
if(tile.floor().isLiquid && !canStayOn(liquid, tile.floor().liquidDrop)){
|
if(tile.floor().isLiquid && !canStayOn(liquid, tile.floor().liquidDrop)){
|
||||||
reactPuddle(tile.floor().liquidDrop, liquid, amount, tile,
|
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)){
|
if(generation == 0 && Timers.get(tile, "ripple", 50)){
|
||||||
Effects.effect(BlockFx.ripple, tile.floor().liquidDrop.color,
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@@ -93,28 +105,32 @@ public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait
|
|||||||
puddle.tile = tile;
|
puddle.tile = tile;
|
||||||
puddle.liquid = liquid;
|
puddle.liquid = liquid;
|
||||||
puddle.amount = amount;
|
puddle.amount = amount;
|
||||||
puddle.generation = (byte)generation;
|
puddle.generation = (byte) generation;
|
||||||
puddle.set((tile.worldx() + source.worldx())/2f, (tile.worldy() + source.worldy())/2f);
|
puddle.set((tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f);
|
||||||
puddle.add();
|
puddle.add();
|
||||||
map.put(tile.packedPosition(), puddle);
|
map.put(tile.packedPosition(), puddle);
|
||||||
}else if(p.liquid == liquid){
|
}else if(p.liquid == liquid){
|
||||||
p.accepting = Math.max(amount, p.accepting);
|
p.accepting = Math.max(amount, p.accepting);
|
||||||
|
|
||||||
if(generation == 0 && Timers.get(p, "ripple2", 50) && p.amount >= maxLiquid/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);
|
Effects.effect(BlockFx.ripple, p.liquid.color, (tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
p.amount -= reactPuddle(p.liquid, liquid, amount, p.tile, p.x, p.y);
|
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){
|
private static boolean canStayOn(Liquid liquid, Liquid other){
|
||||||
return liquid == Liquids.oil && other == Liquids.water;
|
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){
|
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) ||
|
if((dest.flammability > 0.3f && liquid.temperature > 0.7f) ||
|
||||||
(liquid.flammability > 0.3f && dest.temperature > 0.7f)){ //flammable liquid + hot liquid
|
(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)){
|
if(Mathf.chance(0.5f * amount)){
|
||||||
Effects.effect(EnvironmentFx.steam, x, y);
|
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
|
}else if(liquid.temperature > 0.7f && dest.temperature < 0.55f){ //hot liquid poured onto cold puddle
|
||||||
if(Mathf.chance(0.8f * amount)){
|
if(Mathf.chance(0.8f * amount)){
|
||||||
Effects.effect(EnvironmentFx.steam, x, y);
|
Effects.effect(EnvironmentFx.steam, x, y);
|
||||||
}
|
}
|
||||||
return - 0.4f * amount;
|
return -0.4f * amount;
|
||||||
}
|
}
|
||||||
return 0f;
|
return 0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Deserialization use only!*/
|
@Remote(called = Loc.server, in = In.entities)
|
||||||
public Puddle(){}
|
public static void onPuddleRemoved(int puddleid){
|
||||||
|
puddleGroup.removeByID(puddleid);
|
||||||
|
}
|
||||||
|
|
||||||
public float getFlammability(){
|
public float getFlammability(){
|
||||||
return liquid.flammability * amount;
|
return liquid.flammability * amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update() {
|
public void update(){
|
||||||
|
|
||||||
//no updating happens clientside
|
//no updating happens clientside
|
||||||
if(Net.client()){
|
if(Net.client()){
|
||||||
@@ -158,11 +176,11 @@ public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait
|
|||||||
amount += accepting;
|
amount += accepting;
|
||||||
accepting = 0f;
|
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();
|
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);
|
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);
|
deposit(other, tile, liquid, deposited, generation + 1);
|
||||||
amount -= deposited / 2f; //tweak to speed up/slow down puddle propagation
|
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);
|
amount = Mathf.clamp(amount, 0, maxLiquid);
|
||||||
|
|
||||||
if (amount <= 0f) {
|
if(amount <= 0f){
|
||||||
CallEntity.onPuddleRemoved(getID());
|
CallEntity.onPuddleRemoved(getID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//effects-only code
|
//effects-only code
|
||||||
if(amount >= maxLiquid/2f && updateTime <= 0f){
|
if(amount >= maxLiquid / 2f && updateTime <= 0f){
|
||||||
Units.getNearby(rect.setSize(Mathf.clamp(amount/(maxLiquid/1.5f))*10f).setCenter(x, y), unit -> {
|
Units.getNearby(rect.setSize(Mathf.clamp(amount / (maxLiquid / 1.5f)) * 10f).setCenter(x, y), unit -> {
|
||||||
if(unit.isFlying()) return;
|
if(unit.isFlying()) return;
|
||||||
|
|
||||||
unit.getHitbox(rect2);
|
unit.getHitbox(rect2);
|
||||||
@@ -186,7 +204,7 @@ public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait
|
|||||||
|
|
||||||
unit.applyEffect(liquid.effect, 0.5f);
|
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);
|
Effects.effect(BlockFx.ripple, liquid.color, unit.x, unit.y);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -202,30 +220,30 @@ public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw() {
|
public void draw(){
|
||||||
seeds = id;
|
seeds = id;
|
||||||
boolean onLiquid = tile.floor().isLiquid;
|
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 smag = onLiquid ? 0.8f : 0f;
|
||||||
float sscl = 20f;
|
float sscl = 20f;
|
||||||
|
|
||||||
Draw.color(Hue.shift(tmp.set(liquid.color), 2, -0.05f));
|
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) -> {
|
Angles.randLenVectors(id, 3, f * 6f, (ex, ey) -> {
|
||||||
Fill.circle(x + ex + Mathf.sin(Timers.time() + seeds*532, sscl, smag),
|
Fill.circle(x + ex + Mathf.sin(Timers.time() + seeds * 532, sscl, smag),
|
||||||
y + ey + Mathf.sin(Timers.time() + seeds*53, sscl, smag), f * 5f);
|
y + ey + Mathf.sin(Timers.time() + seeds * 53, sscl, smag), f * 5f);
|
||||||
seeds ++;
|
seeds++;
|
||||||
});
|
});
|
||||||
Draw.color();
|
Draw.color();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float drawSize() {
|
public float drawSize(){
|
||||||
return 20;
|
return 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeSave(DataOutput stream) throws IOException {
|
public void writeSave(DataOutput stream) throws IOException{
|
||||||
stream.writeInt(tile.packedPosition());
|
stream.writeInt(tile.packedPosition());
|
||||||
stream.writeFloat(x);
|
stream.writeFloat(x);
|
||||||
stream.writeFloat(y);
|
stream.writeFloat(y);
|
||||||
@@ -235,7 +253,7 @@ public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readSave(DataInput stream) throws IOException {
|
public void readSave(DataInput stream) throws IOException{
|
||||||
this.loadedPosition = stream.readInt();
|
this.loadedPosition = stream.readInt();
|
||||||
this.x = stream.readFloat();
|
this.x = stream.readFloat();
|
||||||
this.y = stream.readFloat();
|
this.y = stream.readFloat();
|
||||||
@@ -246,7 +264,7 @@ public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reset() {
|
public void reset(){
|
||||||
loadedPosition = -1;
|
loadedPosition = -1;
|
||||||
tile = null;
|
tile = null;
|
||||||
liquid = null;
|
liquid = null;
|
||||||
@@ -256,7 +274,7 @@ public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void added() {
|
public void added(){
|
||||||
if(loadedPosition != -1){
|
if(loadedPosition != -1){
|
||||||
map.put(loadedPosition, this);
|
map.put(loadedPosition, this);
|
||||||
tile = world.tile(loadedPosition);
|
tile = world.tile(loadedPosition);
|
||||||
@@ -264,38 +282,33 @@ public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removed() {
|
public void removed(){
|
||||||
map.remove(tile.packedPosition());
|
map.remove(tile.packedPosition());
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(DataOutput data) throws IOException {
|
public void write(DataOutput data) throws IOException{
|
||||||
data.writeFloat(x);
|
data.writeFloat(x);
|
||||||
data.writeFloat(y);
|
data.writeFloat(y);
|
||||||
data.writeByte(liquid.id);
|
data.writeByte(liquid.id);
|
||||||
data.writeShort((short)(amount * 4));
|
data.writeShort((short) (amount * 4));
|
||||||
data.writeInt(tile.packedPosition());
|
data.writeInt(tile.packedPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(DataInput data, long time) throws IOException {
|
public void read(DataInput data, long time) throws IOException{
|
||||||
x = data.readFloat();
|
x = data.readFloat();
|
||||||
y = data.readFloat();
|
y = data.readFloat();
|
||||||
liquid = Liquid.getByID(data.readByte());
|
liquid = Liquid.getByID(data.readByte());
|
||||||
targetAmount = data.readShort()/4f;
|
targetAmount = data.readShort() / 4f;
|
||||||
tile = world.tile(data.readInt());
|
tile = world.tile(data.readInt());
|
||||||
|
|
||||||
map.put(tile.packedPosition(), this);
|
map.put(tile.packedPosition(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityGroup targetGroup() {
|
public EntityGroup targetGroup(){
|
||||||
return puddleGroup;
|
return puddleGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Remote(called = Loc.server, in = In.entities)
|
|
||||||
public static void onPuddleRemoved(int puddleid){
|
|
||||||
puddleGroup.removeByID(puddleid);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,12 @@ package io.anuke.mindustry.entities.effect;
|
|||||||
import io.anuke.ucore.graphics.Draw;
|
import io.anuke.ucore.graphics.Draw;
|
||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
|
|
||||||
public class RubbleDecal extends Decal {
|
public class RubbleDecal extends Decal{
|
||||||
private int size;
|
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){
|
public static void create(float x, float y, int size){
|
||||||
RubbleDecal decal = new RubbleDecal();
|
RubbleDecal decal = new RubbleDecal();
|
||||||
decal.size = size;
|
decal.size = size;
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ import io.anuke.ucore.util.Mathf;
|
|||||||
|
|
||||||
import static io.anuke.mindustry.Vars.world;
|
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 int scorches = 5;
|
||||||
private static final TextureRegion[] regions = new TextureRegion[scorches];
|
private static final TextureRegion[] regions = new TextureRegion[scorches];
|
||||||
|
|
||||||
public static void create(float x, float y){
|
public static void create(float x, float y){
|
||||||
if(regions[0] == null){
|
if(regions[0] == null){
|
||||||
for (int i = 0; i < regions.length; i++) {
|
for(int i = 0; i < regions.length; i++){
|
||||||
regions[i] = Draw.region("scorch" + (i+1));
|
regions[i] = Draw.region("scorch" + (i + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,10 +31,10 @@ public class ScorchDecal extends Decal {
|
|||||||
@Override
|
@Override
|
||||||
public void drawDecal(){
|
public void drawDecal(){
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++) {
|
for(int i = 0; i < 5; i++){
|
||||||
TextureRegion region = regions[Mathf.randomSeed(id - i, 0, scorches-1)];
|
TextureRegion region = regions[Mathf.randomSeed(id - i, 0, scorches - 1)];
|
||||||
float rotation = Mathf.randomSeed(id + i, 0, 360);
|
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);
|
Draw.grect(region, x + Angles.trnsx(rotation, space), y + Angles.trnsy(rotation, space), rotation - 90);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user