Merge branch 'master' of https://github.com/Anuken/Mindustry into v106-alpha
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -7,6 +7,8 @@ assignees: ''
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
**Note**: Do not report any new bugs directly relating to the v6 campaign. They will not be fixed or considered at this time.
|
||||||
|
|
||||||
**Platform**: *Android/iOS/Mac/Windows/Linux*
|
**Platform**: *Android/iOS/Mac/Windows/Linux*
|
||||||
|
|
||||||
**Build**: *The build number under the title in the main menu. Required.*
|
**Build**: *The build number under the title in the main menu. Required.*
|
||||||
|
|||||||
10
README.md
@@ -22,9 +22,9 @@ First, make sure you have [JDK 14](https://adoptopenjdk.net/) installed. Open a
|
|||||||
|
|
||||||
#### Windows
|
#### Windows
|
||||||
|
|
||||||
_Running:_ `gradlew.bat desktop:run`
|
_Running:_ `gradlew desktop:run`
|
||||||
_Building:_ `gradlew.bat desktop:dist`
|
_Building:_ `gradlew desktop:dist`
|
||||||
_Sprite Packing:_ `gradlew.bat tools:pack`
|
_Sprite Packing:_ `gradlew tools:pack`
|
||||||
|
|
||||||
#### Linux/Mac OS
|
#### Linux/Mac OS
|
||||||
|
|
||||||
@@ -70,3 +70,7 @@ Post feature requests and feedback [here](https://github.com/Anuken/Mindustry-Su
|
|||||||
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
|
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
|
||||||
alt="Get it on F-Droid"
|
alt="Get it on F-Droid"
|
||||||
height="80">](https://f-droid.org/packages/io.anuke.mindustry/)
|
height="80">](https://f-droid.org/packages/io.anuke.mindustry/)
|
||||||
|
|
||||||
|
[<img src="https://flathub.org/assets/badges/flathub-badge-en.svg"
|
||||||
|
alt="Download On Flathub"
|
||||||
|
height="60">](https://flathub.org/apps/details/com.github.Anuken.Mindustry)
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import android.content.pm.*;
|
|||||||
import android.net.*;
|
import android.net.*;
|
||||||
import android.os.Build.*;
|
import android.os.Build.*;
|
||||||
import android.os.*;
|
import android.os.*;
|
||||||
import android.provider.Settings.*;
|
|
||||||
import android.telephony.*;
|
import android.telephony.*;
|
||||||
import arc.*;
|
import arc.*;
|
||||||
import arc.backend.android.*;
|
import arc.backend.android.*;
|
||||||
@@ -15,7 +14,7 @@ import arc.files.*;
|
|||||||
import arc.func.*;
|
import arc.func.*;
|
||||||
import arc.scene.ui.layout.*;
|
import arc.scene.ui.layout.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import arc.util.serialization.*;
|
import dalvik.system.*;
|
||||||
import mindustry.*;
|
import mindustry.*;
|
||||||
import mindustry.game.Saves.*;
|
import mindustry.game.Saves.*;
|
||||||
import mindustry.io.*;
|
import mindustry.io.*;
|
||||||
@@ -23,7 +22,6 @@ import mindustry.net.*;
|
|||||||
import mindustry.ui.dialogs.*;
|
import mindustry.ui.dialogs.*;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.lang.System;
|
|
||||||
import java.lang.Thread.*;
|
import java.lang.Thread.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -73,12 +71,25 @@ public class AndroidLauncher extends AndroidApplication{
|
|||||||
public void shareFile(Fi file){
|
public void shareFile(Fi file){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<?> loadJar(Fi jar, String mainClass) throws Exception{
|
||||||
|
DexClassLoader loader = new DexClassLoader(jar.file().getPath(), getFilesDir().getPath(), null, getClassLoader());
|
||||||
|
return Class.forName(mainClass, true, loader);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void showFileChooser(boolean open, String extension, Cons<Fi> cons){
|
public void showFileChooser(boolean open, String extension, Cons<Fi> cons){
|
||||||
|
showFileChooser(open, cons, extension);
|
||||||
|
}
|
||||||
|
|
||||||
|
void showFileChooser(boolean open, Cons<Fi> cons, String... extensions){
|
||||||
|
String extension = extensions[0];
|
||||||
|
|
||||||
if(VERSION.SDK_INT >= VERSION_CODES.Q){
|
if(VERSION.SDK_INT >= VERSION_CODES.Q){
|
||||||
Intent intent = new Intent(open ? Intent.ACTION_OPEN_DOCUMENT : Intent.ACTION_CREATE_DOCUMENT);
|
Intent intent = new Intent(open ? Intent.ACTION_OPEN_DOCUMENT : Intent.ACTION_CREATE_DOCUMENT);
|
||||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||||
intent.setType(extension.equals("zip") && !open ? "application/zip" : "*/*");
|
intent.setType(extension.equals("zip") && !open && extensions.length == 1 ? "application/zip" : "*/*");
|
||||||
|
|
||||||
addResultListener(i -> startActivityForResult(intent, i), (code, in) -> {
|
addResultListener(i -> startActivityForResult(intent, i), (code, in) -> {
|
||||||
if(code == Activity.RESULT_OK && in != null && in.getData() != null){
|
if(code == Activity.RESULT_OK && in != null && in.getData() != null){
|
||||||
Uri uri = in.getData();
|
Uri uri = in.getData();
|
||||||
@@ -108,7 +119,7 @@ public class AndroidLauncher extends AndroidApplication{
|
|||||||
});
|
});
|
||||||
}else if(VERSION.SDK_INT >= VERSION_CODES.M && !(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED &&
|
}else if(VERSION.SDK_INT >= 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 = new FileChooser(open ? "@open" : "@save", file -> file.extension().equalsIgnoreCase(extension), open, file -> {
|
chooser = new FileChooser(open ? "@open" : "@save", file -> Structs.contains(extensions, file.extension().toLowerCase()), open, file -> {
|
||||||
if(!open){
|
if(!open){
|
||||||
cons.get(file.parent().child(file.nameWithoutExtension() + "." + extension));
|
cons.get(file.parent().child(file.nameWithoutExtension() + "." + extension));
|
||||||
}else{
|
}else{
|
||||||
@@ -125,10 +136,19 @@ public class AndroidLauncher extends AndroidApplication{
|
|||||||
}
|
}
|
||||||
requestPermissions(perms.toArray(new String[0]), PERMISSION_REQUEST_CODE);
|
requestPermissions(perms.toArray(new String[0]), PERMISSION_REQUEST_CODE);
|
||||||
}else{
|
}else{
|
||||||
super.showFileChooser(open, extension, cons);
|
if(open){
|
||||||
|
new FileChooser("@open", file -> Structs.contains(extensions, file.extension().toLowerCase()), true, cons).show();
|
||||||
|
}else{
|
||||||
|
super.showFileChooser(open, extension, cons);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showMultiFileChooser(Cons<Fi> cons, String... extensions){
|
||||||
|
showFileChooser(true, cons, extensions);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beginForceLandscape(){
|
public void beginForceLandscape(){
|
||||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
|
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package mindustry.annotations.entity;
|
package mindustry.annotations.entity;
|
||||||
|
|
||||||
import arc.*;
|
|
||||||
import arc.files.*;
|
import arc.files.*;
|
||||||
import arc.func.*;
|
import arc.func.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
@@ -520,7 +519,7 @@ public class EntityProcess extends BaseProcessor{
|
|||||||
//add free code to remove methods - always at the end
|
//add free code to remove methods - always at the end
|
||||||
//this only gets called next frame.
|
//this only gets called next frame.
|
||||||
if(first.name().equals("remove") && ann.pooled()){
|
if(first.name().equals("remove") && ann.pooled()){
|
||||||
mbuilder.addStatement("$T.app.post(() -> $T.free(this))", Core.class, Pools.class);
|
mbuilder.addStatement("mindustry.gen.Groups.queueFree(($T)this)", Poolable.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.addMethod(mbuilder.build());
|
builder.addMethod(mbuilder.build());
|
||||||
@@ -587,6 +586,17 @@ public class EntityProcess extends BaseProcessor{
|
|||||||
//write clear
|
//write clear
|
||||||
groupsBuilder.addMethod(groupClear.build());
|
groupsBuilder.addMethod(groupClear.build());
|
||||||
|
|
||||||
|
//add method for pool storage
|
||||||
|
groupsBuilder.addField(FieldSpec.builder(ParameterizedTypeName.get(Seq.class, Poolable.class), "freeQueue", Modifier.PRIVATE, Modifier.STATIC).initializer("new Seq<>()").build());
|
||||||
|
|
||||||
|
//method for freeing things
|
||||||
|
MethodSpec.Builder groupFreeQueue = MethodSpec.methodBuilder("queueFree")
|
||||||
|
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
|
||||||
|
.addParameter(Poolable.class, "obj")
|
||||||
|
.addStatement("freeQueue.add(obj)");
|
||||||
|
|
||||||
|
groupsBuilder.addMethod(groupFreeQueue.build());
|
||||||
|
|
||||||
//add method for resizing all necessary groups
|
//add method for resizing all necessary groups
|
||||||
MethodSpec.Builder groupResize = MethodSpec.methodBuilder("resize")
|
MethodSpec.Builder groupResize = MethodSpec.methodBuilder("resize")
|
||||||
.addParameter(TypeName.FLOAT, "x").addParameter(TypeName.FLOAT, "y").addParameter(TypeName.FLOAT, "w").addParameter(TypeName.FLOAT, "h")
|
.addParameter(TypeName.FLOAT, "x").addParameter(TypeName.FLOAT, "y").addParameter(TypeName.FLOAT, "w").addParameter(TypeName.FLOAT, "h")
|
||||||
@@ -595,6 +605,11 @@ public class EntityProcess extends BaseProcessor{
|
|||||||
MethodSpec.Builder groupUpdate = MethodSpec.methodBuilder("update")
|
MethodSpec.Builder groupUpdate = MethodSpec.methodBuilder("update")
|
||||||
.addModifiers(Modifier.PUBLIC, Modifier.STATIC);
|
.addModifiers(Modifier.PUBLIC, Modifier.STATIC);
|
||||||
|
|
||||||
|
//free everything pooled at the start of each updaet
|
||||||
|
groupUpdate
|
||||||
|
.addStatement("for($T p : freeQueue) $T.free(p)", Poolable.class, Pools.class)
|
||||||
|
.addStatement("freeQueue.clear()");
|
||||||
|
|
||||||
//method resize
|
//method resize
|
||||||
for(GroupDefinition group : groupDefs){
|
for(GroupDefinition group : groupDefs){
|
||||||
if(group.spatial){
|
if(group.spatial){
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package mindustry.annotations.impl;
|
|||||||
import arc.files.*;
|
import arc.files.*;
|
||||||
import arc.scene.style.*;
|
import arc.scene.style.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
|
import arc.util.*;
|
||||||
|
import arc.util.io.*;
|
||||||
import arc.util.serialization.*;
|
import arc.util.serialization.*;
|
||||||
import com.squareup.javapoet.*;
|
import com.squareup.javapoet.*;
|
||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
@@ -33,6 +35,17 @@ public class AssetsProcess extends BaseProcessor{
|
|||||||
String resources = rootDirectory + "/core/assets-raw/sprites/ui";
|
String resources = rootDirectory + "/core/assets-raw/sprites/ui";
|
||||||
Jval icons = Jval.read(Fi.get(rootDirectory + "/core/assets-raw/fontgen/config.json").readString());
|
Jval icons = Jval.read(Fi.get(rootDirectory + "/core/assets-raw/fontgen/config.json").readString());
|
||||||
|
|
||||||
|
ObjectMap<String, String> texIcons = new OrderedMap<>();
|
||||||
|
PropertiesUtils.load(texIcons, Fi.get(rootDirectory + "/core/assets/icons/icons.properties").reader());
|
||||||
|
|
||||||
|
texIcons.each((key, val) -> {
|
||||||
|
String[] split = val.split("\\|");
|
||||||
|
String name = Strings.kebabToCamel(split[1]).replace("Medium", "").replace("Icon", "");
|
||||||
|
if(SourceVersion.isKeyword(name) || name.equals("char")) name = name + "i";
|
||||||
|
|
||||||
|
ichtype.addField(FieldSpec.builder(char.class, name, Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL).initializer("(char)" + key).build());
|
||||||
|
});
|
||||||
|
|
||||||
ictype.addField(FieldSpec.builder(ParameterizedTypeName.get(ObjectMap.class, String.class, TextureRegionDrawable.class),
|
ictype.addField(FieldSpec.builder(ParameterizedTypeName.get(ObjectMap.class, String.class, TextureRegionDrawable.class),
|
||||||
"icons", Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL).initializer("new ObjectMap<>()").build());
|
"icons", Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL).initializer("new ObjectMap<>()").build());
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ public class LogicStatementProcessor extends BaseProcessor{
|
|||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
for(Svar field : fields){
|
for(Svar field : fields){
|
||||||
if(field.is(Modifier.TRANSIENT)) continue;
|
if(field.isAny(Modifier.TRANSIENT, Modifier.STATIC)) continue;
|
||||||
|
|
||||||
writer.addStatement("out.append(\" \")");
|
writer.addStatement("out.append(\" \")");
|
||||||
writer.addStatement("out.append((($T)obj).$L$L)", c.mirror(), field.name(),
|
writer.addStatement("out.append((($T)obj).$L$L)", c.mirror(), field.name(),
|
||||||
|
|||||||
@@ -200,7 +200,6 @@ project(":desktop"){
|
|||||||
|
|
||||||
dependencies{
|
dependencies{
|
||||||
implementation project(":core")
|
implementation project(":core")
|
||||||
implementation arcModule("natives:natives-box2d-desktop")
|
|
||||||
implementation arcModule("natives:natives-desktop")
|
implementation arcModule("natives:natives-desktop")
|
||||||
implementation arcModule("natives:natives-freetype-desktop")
|
implementation arcModule("natives:natives-freetype-desktop")
|
||||||
implementation 'com.github.MinnDevelopment:java-discord-rpc:v2.0.1'
|
implementation 'com.github.MinnDevelopment:java-discord-rpc:v2.0.1'
|
||||||
@@ -239,7 +238,6 @@ project(":ios"){
|
|||||||
|
|
||||||
implementation arcModule("natives:natives-ios")
|
implementation arcModule("natives:natives-ios")
|
||||||
implementation arcModule("natives:natives-freetype-ios")
|
implementation arcModule("natives:natives-freetype-ios")
|
||||||
implementation arcModule("natives:natives-box2d-ios")
|
|
||||||
implementation arcModule("backends:backend-robovm")
|
implementation arcModule("backends:backend-robovm")
|
||||||
|
|
||||||
compileOnly project(":annotations")
|
compileOnly project(":annotations")
|
||||||
@@ -282,7 +280,6 @@ project(":core"){
|
|||||||
api "org.lz4:lz4-java:1.4.1"
|
api "org.lz4:lz4-java:1.4.1"
|
||||||
api arcModule("arc-core")
|
api arcModule("arc-core")
|
||||||
api arcModule("extensions:freetype")
|
api arcModule("extensions:freetype")
|
||||||
api arcModule("extensions:box2d")
|
|
||||||
api arcModule("extensions:g3d")
|
api arcModule("extensions:g3d")
|
||||||
api arcModule("extensions:fx")
|
api arcModule("extensions:fx")
|
||||||
api arcModule("extensions:arcnet")
|
api arcModule("extensions:arcnet")
|
||||||
@@ -299,7 +296,6 @@ project(":server"){
|
|||||||
|
|
||||||
dependencies{
|
dependencies{
|
||||||
implementation project(":core")
|
implementation project(":core")
|
||||||
implementation arcModule("natives:natives-box2d-desktop")
|
|
||||||
implementation arcModule("backends:backend-headless")
|
implementation arcModule("backends:backend-headless")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -312,7 +308,6 @@ project(":tests"){
|
|||||||
testImplementation "org.junit.jupiter:junit-jupiter-params:5.3.1"
|
testImplementation "org.junit.jupiter:junit-jupiter-params:5.3.1"
|
||||||
testImplementation "org.junit.jupiter:junit-jupiter-api:5.3.1"
|
testImplementation "org.junit.jupiter:junit-jupiter-api:5.3.1"
|
||||||
testImplementation arcModule("backends:backend-headless")
|
testImplementation arcModule("backends:backend-headless")
|
||||||
testImplementation arcModule("natives:natives-box2d-desktop")
|
|
||||||
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.3.1"
|
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.3.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,7 +329,6 @@ project(":tools"){
|
|||||||
|
|
||||||
implementation arcModule("natives:natives-desktop")
|
implementation arcModule("natives:natives-desktop")
|
||||||
implementation arcModule("natives:natives-freetype-desktop")
|
implementation arcModule("natives:natives-freetype-desktop")
|
||||||
implementation arcModule("natives:natives-box2d-desktop")
|
|
||||||
implementation arcModule("backends:backend-headless")
|
implementation arcModule("backends:backend-headless")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 330 B After Width: | Height: | Size: 376 B |
|
Before Width: | Height: | Size: 289 B After Width: | Height: | Size: 490 B |
|
Before Width: | Height: | Size: 189 B After Width: | Height: | Size: 304 B |
|
Before Width: | Height: | Size: 812 B After Width: | Height: | Size: 1.1 KiB |
BIN
core/assets-raw/sprites/blocks/turrets/wave-top.png
Normal file
|
After Width: | Height: | Size: 285 B |
BIN
core/assets-raw/sprites/blocks/units/command-center-team.png
Normal file
|
After Width: | Height: | Size: 511 B |
|
Before Width: | Height: | Size: 783 B After Width: | Height: | Size: 347 B |
|
Before Width: | Height: | Size: 427 B After Width: | Height: | Size: 660 B |
|
Before Width: | Height: | Size: 546 B After Width: | Height: | Size: 843 B |
|
Before Width: | Height: | Size: 244 B After Width: | Height: | Size: 323 B |
|
Before Width: | Height: | Size: 602 B After Width: | Height: | Size: 796 B |
|
Before Width: | Height: | Size: 226 B After Width: | Height: | Size: 323 B |
|
Before Width: | Height: | Size: 428 B After Width: | Height: | Size: 655 B |
|
Before Width: | Height: | Size: 890 B After Width: | Height: | Size: 908 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 589 B After Width: | Height: | Size: 586 B |
@@ -473,16 +473,9 @@ requirement.wave = Reach Wave {0} in {1}
|
|||||||
requirement.core = Destroy Enemy Core in {0}
|
requirement.core = Destroy Enemy Core in {0}
|
||||||
requirement.research = Research {0}
|
requirement.research = Research {0}
|
||||||
requirement.capture = Capture {0}
|
requirement.capture = Capture {0}
|
||||||
resume = Resume Zone:\n[lightgray]{0}
|
|
||||||
bestwave = [lightgray]Best Wave: {0}
|
bestwave = [lightgray]Best Wave: {0}
|
||||||
#TODO fix/remove this
|
|
||||||
launch = < LAUNCH >
|
|
||||||
launch.text = Launch
|
launch.text = Launch
|
||||||
launch.title = Launch Successful
|
campaign.multiplayer = While playing multiplayer in campaign, you can only research using items from [accent]your[] sectors, [scarlet]not[] the host's sector that you are on right now.\n\nTo get items to [accent]your[] sectors in multiplayer, use a [accent]launch pad[].
|
||||||
launch.next = [lightgray]next opportunity at wave {0}
|
|
||||||
launch.unable2 = [scarlet]Unable to LAUNCH.[]
|
|
||||||
launch.confirm = This will launch all resources in your core.\nYou will not be able to return to this base.
|
|
||||||
launch.skip.confirm = If you skip now, you will not be able to launch until later waves.
|
|
||||||
uncover = Uncover
|
uncover = Uncover
|
||||||
configure = Configure Loadout
|
configure = Configure Loadout
|
||||||
#TODO
|
#TODO
|
||||||
@@ -1173,7 +1166,7 @@ tutorial.drillturret = Duo turrets require[accent] copper ammo[] to shoot.\nPlac
|
|||||||
tutorial.pause = During battle, you are able to[accent] pause the game.[]\nYou may queue buildings while paused.\n\n[accent]Press space to pause.
|
tutorial.pause = During battle, you are able to[accent] pause the game.[]\nYou may queue buildings while paused.\n\n[accent]Press space to pause.
|
||||||
tutorial.pause.mobile = During battle, you are able to[accent] pause the game.[]\nYou may queue buildings while paused.\n\n[accent]Press this button in the top left to pause.
|
tutorial.pause.mobile = During battle, you are able to[accent] pause the game.[]\nYou may queue buildings while paused.\n\n[accent]Press this button in the top left to pause.
|
||||||
tutorial.unpause = Now press space again to unpause.
|
tutorial.unpause = Now press space again to unpause.
|
||||||
tutorial.unpause.mobile = Now press it again to unpause.d
|
tutorial.unpause.mobile = Now press it again to unpause.
|
||||||
tutorial.breaking = Blocks frequently need to be destroyed.\n[accent]Hold down right-click[] to destroy all blocks in a selection.[]\n\n[accent]Destroy all the scrap blocks to the left of your core using area selection.
|
tutorial.breaking = Blocks frequently need to be destroyed.\n[accent]Hold down right-click[] to destroy all blocks in a selection.[]\n\n[accent]Destroy all the scrap blocks to the left of your core using area selection.
|
||||||
tutorial.breaking.mobile = Blocks frequently need to be destroyed.\n[accent]Select deconstruction mode[], then tap a block to begin breaking it.\nDestroy an area by holding down your finger for a few seconds[] and dragging in a direction.\nPress the checkmark button to confirm breaking.\n\n[accent]Destroy all the scrap blocks to the left of your core using area selection.
|
tutorial.breaking.mobile = Blocks frequently need to be destroyed.\n[accent]Select deconstruction mode[], then tap a block to begin breaking it.\nDestroy an area by holding down your finger for a few seconds[] and dragging in a direction.\nPress the checkmark button to confirm breaking.\n\n[accent]Destroy all the scrap blocks to the left of your core using area selection.
|
||||||
tutorial.withdraw = In some situations, taking items directly from blocks is necessary.\nTo do this, [accent]tap a block[] with items in it, then [accent]tap the item[] in the inventory.\nMultiple items can be withdrawn by [accent]tapping and holding[].\n\n[accent]Withdraw some copper from the core.[]
|
tutorial.withdraw = In some situations, taking items directly from blocks is necessary.\nTo do this, [accent]tap a block[] with items in it, then [accent]tap the item[] in the inventory.\nMultiple items can be withdrawn by [accent]tapping and holding[].\n\n[accent]Withdraw some copper from the core.[]
|
||||||
|
|||||||
@@ -21,15 +21,8 @@
|
|||||||
63723=ice|block-ice-medium
|
63723=ice|block-ice-medium
|
||||||
63722=ice-snow|block-ice-snow-medium
|
63722=ice-snow|block-ice-snow-medium
|
||||||
63721=cliffs|block-cliffs-medium
|
63721=cliffs|block-cliffs-medium
|
||||||
63720=rocks|block-rocks-medium
|
|
||||||
63719=sporerocks|block-sporerocks-medium
|
|
||||||
63718=rock|block-rock-medium
|
63718=rock|block-rock-medium
|
||||||
63717=snowrock|block-snowrock-medium
|
63717=snowrock|block-snowrock-medium
|
||||||
63716=icerocks|block-icerocks-medium
|
|
||||||
63715=snowrocks|block-snowrocks-medium
|
|
||||||
63714=dunerocks|block-dunerocks-medium
|
|
||||||
63713=sandrocks|block-sandrocks-medium
|
|
||||||
63712=saltrocks|block-saltrocks-medium
|
|
||||||
63711=spore-pine|block-spore-pine-medium
|
63711=spore-pine|block-spore-pine-medium
|
||||||
63710=snow-pine|block-snow-pine-medium
|
63710=snow-pine|block-snow-pine-medium
|
||||||
63709=pine|block-pine-medium
|
63709=pine|block-pine-medium
|
||||||
@@ -38,7 +31,6 @@
|
|||||||
63706=white-tree|block-white-tree-medium
|
63706=white-tree|block-white-tree-medium
|
||||||
63705=spore-cluster|block-spore-cluster-medium
|
63705=spore-cluster|block-spore-cluster-medium
|
||||||
63704=shale|block-shale-medium
|
63704=shale|block-shale-medium
|
||||||
63703=shalerocks|block-shalerocks-medium
|
|
||||||
63702=shale-boulder|block-shale-boulder-medium
|
63702=shale-boulder|block-shale-boulder-medium
|
||||||
63701=sand-boulder|block-sand-boulder-medium
|
63701=sand-boulder|block-sand-boulder-medium
|
||||||
63700=moss|block-moss-medium
|
63700=moss|block-moss-medium
|
||||||
|
|||||||
@@ -154,7 +154,6 @@ const SaveLoadEvent = Packages.mindustry.game.EventType.SaveLoadEvent
|
|||||||
const MapPublishEvent = Packages.mindustry.game.EventType.MapPublishEvent
|
const MapPublishEvent = Packages.mindustry.game.EventType.MapPublishEvent
|
||||||
const MapMakeEvent = Packages.mindustry.game.EventType.MapMakeEvent
|
const MapMakeEvent = Packages.mindustry.game.EventType.MapMakeEvent
|
||||||
const ResizeEvent = Packages.mindustry.game.EventType.ResizeEvent
|
const ResizeEvent = Packages.mindustry.game.EventType.ResizeEvent
|
||||||
const LaunchEvent = Packages.mindustry.game.EventType.LaunchEvent
|
|
||||||
const LoseEvent = Packages.mindustry.game.EventType.LoseEvent
|
const LoseEvent = Packages.mindustry.game.EventType.LoseEvent
|
||||||
const WinEvent = Packages.mindustry.game.EventType.WinEvent
|
const WinEvent = Packages.mindustry.game.EventType.WinEvent
|
||||||
const Trigger = Packages.mindustry.game.EventType.Trigger
|
const Trigger = Packages.mindustry.game.EventType.Trigger
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 813 B After Width: | Height: | Size: 812 B |
|
Before Width: | Height: | Size: 553 KiB After Width: | Height: | Size: 563 KiB |
|
Before Width: | Height: | Size: 662 KiB After Width: | Height: | Size: 668 KiB |
|
Before Width: | Height: | Size: 951 KiB After Width: | Height: | Size: 969 KiB |
|
Before Width: | Height: | Size: 508 KiB After Width: | Height: | Size: 506 KiB |
|
Before Width: | Height: | Size: 187 KiB After Width: | Height: | Size: 188 KiB |
|
Before Width: | Height: | Size: 419 KiB After Width: | Height: | Size: 419 KiB |
|
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 2.8 MiB After Width: | Height: | Size: 2.9 MiB |
|
Before Width: | Height: | Size: 188 KiB After Width: | Height: | Size: 189 KiB |
|
Before Width: | Height: | Size: 420 KiB After Width: | Height: | Size: 419 KiB |
|
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.4 MiB |
@@ -63,7 +63,7 @@ public class Vars implements Loadable{
|
|||||||
/** URL to the JSON file containing all the BE servers. Only queried in the V6 alpha (will be removed once it's out). */
|
/** URL to the JSON file containing all the BE servers. Only queried in the V6 alpha (will be removed once it's out). */
|
||||||
public static final String serverJsonV6URL = "https://raw.githubusercontent.com/Anuken/Mindustry/master/servers_v6.json";
|
public static final String serverJsonV6URL = "https://raw.githubusercontent.com/Anuken/Mindustry/master/servers_v6.json";
|
||||||
/** URL of the github issue report template.*/
|
/** URL of the github issue report template.*/
|
||||||
public static final String reportIssueURL = "https://github.com/Anuken/Mindustry/issues/new?template=bug_report.md";
|
public static final String reportIssueURL = "https://github.com/Anuken/Mindustry/issues/new?labels=bug&template=bug_report.md";
|
||||||
/** list of built-in servers.*/
|
/** list of built-in servers.*/
|
||||||
public static final Seq<String> defaultServers = Seq.with();
|
public static final Seq<String> defaultServers = Seq.with();
|
||||||
/** maximum distance between mine and core that supports automatic transferring */
|
/** maximum distance between mine and core that supports automatic transferring */
|
||||||
@@ -72,8 +72,6 @@ public class Vars implements Loadable{
|
|||||||
public static final int maxTextLength = 150;
|
public static final int maxTextLength = 150;
|
||||||
/** max player name length in bytes */
|
/** max player name length in bytes */
|
||||||
public static final int maxNameLength = 40;
|
public static final int maxNameLength = 40;
|
||||||
/** shadow color for turrets */
|
|
||||||
public static final float turretShadowColor = Color.toFloatBits(0, 0, 0, 0.22f);
|
|
||||||
/** displayed item size when ingame. */
|
/** displayed item size when ingame. */
|
||||||
public static final float itemSize = 5f;
|
public static final float itemSize = 5f;
|
||||||
/** units outside of this bound will die instantly */
|
/** units outside of this bound will die instantly */
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import arc.math.*;
|
|||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.struct.EnumSet;
|
import arc.struct.EnumSet;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
|
import arc.util.ArcAnnotate.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
@@ -165,6 +166,11 @@ public class BlockIndexer{
|
|||||||
return flagMap[team.id][type.ordinal()];
|
return flagMap[team.id][type.ordinal()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public Tile findClosestFlag(float x, float y, Team team, BlockFlag flag){
|
||||||
|
return Geometry.findClosest(x, y, getAllied(team, flag));
|
||||||
|
}
|
||||||
|
|
||||||
public boolean eachBlock(Teamc team, float range, Boolf<Building> pred, Cons<Building> cons){
|
public boolean eachBlock(Teamc team, float range, Boolf<Building> pred, Cons<Building> cons){
|
||||||
return eachBlock(team.team(), team.getX(), team.getY(), range, pred, cons);
|
return eachBlock(team.team(), team.getX(), team.getY(), range, pred, cons);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public class Pathfinder implements Runnable{
|
|||||||
PathTile.health(tile) * 5 +
|
PathTile.health(tile) * 5 +
|
||||||
(PathTile.nearSolid(tile) ? 2 : 0) +
|
(PathTile.nearSolid(tile) ? 2 : 0) +
|
||||||
(PathTile.nearLiquid(tile) ? 6 : 0) +
|
(PathTile.nearLiquid(tile) ? 6 : 0) +
|
||||||
(PathTile.deep(tile) ? 70 : 0) +
|
(PathTile.deep(tile) ? 6000 : 0) +
|
||||||
(PathTile.damages(tile) ? 30 : 0),
|
(PathTile.damages(tile) ? 30 : 0),
|
||||||
|
|
||||||
//legs
|
//legs
|
||||||
@@ -116,7 +116,7 @@ public class Pathfinder implements Runnable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
return PathTile.get(
|
return PathTile.get(
|
||||||
tile.build == null ? 0 : Math.min((int)(tile.build.health / 40), 127),
|
tile.build == null ? 0 : Math.min((int)(tile.build.health / 40), 80),
|
||||||
tile.getTeamID(),
|
tile.getTeamID(),
|
||||||
tile.solid(),
|
tile.solid(),
|
||||||
tile.floor().isLiquid,
|
tile.floor().isLiquid,
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ public class FlyingAI extends AIController{
|
|||||||
moveTo(target, unit.range() * 0.8f);
|
moveTo(target, unit.range() * 0.8f);
|
||||||
unit.lookAt(target);
|
unit.lookAt(target);
|
||||||
}else{
|
}else{
|
||||||
attack(80f);
|
attack(100f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,6 @@ public class GroundAI extends AIController{
|
|||||||
|
|
||||||
if(!Units.invalidateTarget(target, unit, unit.range()) && unit.type().rotateShooting){
|
if(!Units.invalidateTarget(target, unit, unit.range()) && unit.type().rotateShooting){
|
||||||
if(unit.type().hasWeapons()){
|
if(unit.type().hasWeapons()){
|
||||||
//TODO certain units should not look at the target, e.g. ships
|
|
||||||
unit.lookAt(Predict.intercept(unit, target, unit.type().weapons.first().bullet.speed));
|
unit.lookAt(Predict.intercept(unit, target, unit.type().weapons.first().bullet.speed));
|
||||||
}
|
}
|
||||||
}else if(unit.moving()){
|
}else if(unit.moving()){
|
||||||
|
|||||||
@@ -1,31 +1,25 @@
|
|||||||
package mindustry.async;
|
package mindustry.async;
|
||||||
|
|
||||||
import arc.box2d.*;
|
import arc.math.*;
|
||||||
import arc.box2d.BodyDef.*;
|
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
|
import arc.math.geom.QuadTree.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
|
import mindustry.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
|
import mindustry.async.PhysicsProcess.PhysicsWorld.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
|
|
||||||
public class PhysicsProcess implements AsyncProcess{
|
public class PhysicsProcess implements AsyncProcess{
|
||||||
private Physics physics;
|
private static final int
|
||||||
|
layers = 3,
|
||||||
|
layerGround = 0,
|
||||||
|
layerLegs = 1,
|
||||||
|
layerFlying = 2;
|
||||||
|
|
||||||
|
private PhysicsWorld physics;
|
||||||
private Seq<PhysicRef> refs = new Seq<>(false);
|
private Seq<PhysicRef> refs = new Seq<>(false);
|
||||||
private BodyDef def;
|
//currently only enabled for units
|
||||||
|
private EntityGroup<Unit> group = Groups.unit;
|
||||||
private EntityGroup<? extends Physicsc> group;
|
|
||||||
private Filter flying = new Filter(){{
|
|
||||||
maskBits = categoryBits = 2;
|
|
||||||
}}, ground = new Filter(){{
|
|
||||||
maskBits = categoryBits = 1;
|
|
||||||
}};
|
|
||||||
|
|
||||||
public PhysicsProcess(){
|
|
||||||
def = new BodyDef();
|
|
||||||
def.type = BodyType.dynamicBody;
|
|
||||||
|
|
||||||
//currently only enabled for units
|
|
||||||
group = Groups.unit;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void begin(){
|
public void begin(){
|
||||||
@@ -34,47 +28,39 @@ public class PhysicsProcess implements AsyncProcess{
|
|||||||
//remove stale entities
|
//remove stale entities
|
||||||
refs.removeAll(ref -> {
|
refs.removeAll(ref -> {
|
||||||
if(!ref.entity.isAdded()){
|
if(!ref.entity.isAdded()){
|
||||||
physics.destroyBody(ref.body);
|
physics.remove(ref.body);
|
||||||
ref.entity.physref(null);
|
ref.entity.physref(null);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
//find entities without bodies and assign them
|
//find Unit without bodies and assign them
|
||||||
for(Physicsc entity : group){
|
for(Unit entity : group){
|
||||||
boolean grounded = entity.isGrounded();
|
|
||||||
int bits = grounded ? ground.maskBits : flying.maskBits;
|
|
||||||
|
|
||||||
if(entity.physref() == null){
|
if(entity.physref() == null){
|
||||||
//add bodies to entities that have none
|
PhysicsBody body = new PhysicsBody();
|
||||||
FixtureDef fd = new FixtureDef();
|
body.x = entity.x();
|
||||||
fd.shape = new CircleShape(entity.hitSize() / 2f);
|
body.y = entity.y();
|
||||||
fd.density = 5f;
|
body.mass = entity.mass();
|
||||||
fd.restitution = 0.0f;
|
body.radius = entity.hitSize() / 2f;
|
||||||
fd.filter.maskBits = fd.filter.categoryBits = (grounded ? ground : flying).maskBits;
|
|
||||||
|
|
||||||
def.position.set(entity);
|
|
||||||
|
|
||||||
Body body = physics.createBody(def);
|
|
||||||
body.createFixture(fd);
|
|
||||||
|
|
||||||
PhysicRef ref = new PhysicRef(entity, body);
|
PhysicRef ref = new PhysicRef(entity, body);
|
||||||
refs.add(ref);
|
refs.add(ref);
|
||||||
|
|
||||||
entity.physref(ref);
|
entity.physref(ref);
|
||||||
|
|
||||||
|
physics.add(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
//save last position
|
//save last position
|
||||||
PhysicRef ref = entity.physref();
|
PhysicRef ref = entity.physref();
|
||||||
|
|
||||||
if(ref.body.getFixtureList().any() && ref.body.getFixtureList().first().getFilterData().categoryBits != bits){
|
ref.body.layer =
|
||||||
//set correct filter
|
entity.type().allowLegStep ? layerLegs :
|
||||||
ref.body.getFixtureList().first().setFilterData(grounded ? ground : flying);
|
entity.isGrounded() ? layerGround : layerFlying;
|
||||||
}
|
ref.x = entity.x();
|
||||||
|
ref.y = entity.y();
|
||||||
ref.velocity.set(entity.deltaX(), entity.deltaY());
|
|
||||||
ref.position.set(entity);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,26 +71,11 @@ public class PhysicsProcess implements AsyncProcess{
|
|||||||
//get last position vectors before step
|
//get last position vectors before step
|
||||||
for(PhysicRef ref : refs){
|
for(PhysicRef ref : refs){
|
||||||
//force set target position
|
//force set target position
|
||||||
ref.body.setPosition(ref.position.x, ref.position.y);
|
ref.body.x = ref.x;
|
||||||
|
ref.body.y = ref.y;
|
||||||
//save last position for delta
|
|
||||||
ref.lastPosition.set(ref.body.getPosition());
|
|
||||||
|
|
||||||
//write velocity
|
|
||||||
ref.body.setLinearVelocity(ref.velocity);
|
|
||||||
|
|
||||||
ref.lastVelocity.set(ref.velocity);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
physics.step(1f/45f, 5, 8);
|
physics.update();
|
||||||
|
|
||||||
//get delta vectors
|
|
||||||
for(PhysicRef ref : refs){
|
|
||||||
//get delta vector
|
|
||||||
ref.delta.set(ref.body.getPosition()).sub(ref.lastPosition);
|
|
||||||
|
|
||||||
ref.velocity.set(ref.body.getLinearVelocity());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -115,13 +86,8 @@ public class PhysicsProcess implements AsyncProcess{
|
|||||||
for(PhysicRef ref : refs){
|
for(PhysicRef ref : refs){
|
||||||
Physicsc entity = ref.entity;
|
Physicsc entity = ref.entity;
|
||||||
|
|
||||||
entity.move(ref.delta.x, ref.delta.y);
|
//move by delta
|
||||||
|
entity.move(ref.body.x - ref.x, ref.body.y - ref.y);
|
||||||
//save last position
|
|
||||||
ref.position.set(entity);
|
|
||||||
|
|
||||||
//add delta velocity - this doesn't work very well yet
|
|
||||||
//entity.vel().add(ref.velocity).sub(ref.lastVelocity);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,7 +95,6 @@ public class PhysicsProcess implements AsyncProcess{
|
|||||||
public void reset(){
|
public void reset(){
|
||||||
if(physics != null){
|
if(physics != null){
|
||||||
refs.clear();
|
refs.clear();
|
||||||
physics.dispose();
|
|
||||||
physics = null;
|
physics = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138,17 +103,95 @@ public class PhysicsProcess implements AsyncProcess{
|
|||||||
public void init(){
|
public void init(){
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
physics = new Physics(new Vec2(), true);
|
physics = new PhysicsWorld(Vars.world.getQuadBounds(new Rect()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class PhysicRef{
|
public static class PhysicRef{
|
||||||
public Physicsc entity;
|
public Physicsc entity;
|
||||||
public Body body;
|
public PhysicsBody body;
|
||||||
public Vec2 lastPosition = new Vec2(), delta = new Vec2(), velocity = new Vec2(), lastVelocity = new Vec2(), position = new Vec2();
|
public float x, y;
|
||||||
|
|
||||||
public PhysicRef(Physicsc entity, Body body){
|
public PhysicRef(Physicsc entity, PhysicsBody body){
|
||||||
this.entity = entity;
|
this.entity = entity;
|
||||||
this.body = body;
|
this.body = body;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//world for simulating physics in a different thread
|
||||||
|
public static class PhysicsWorld{
|
||||||
|
//how much to soften movement by
|
||||||
|
private static final float scl = 1.25f;
|
||||||
|
|
||||||
|
private final QuadTree<PhysicsBody>[] trees = new QuadTree[layers];
|
||||||
|
private final Seq<PhysicsBody> bodies = new Seq<>(false, 16, PhysicsBody.class);
|
||||||
|
private final Seq<PhysicsBody> seq = new Seq<>(PhysicsBody.class);
|
||||||
|
private final Rect rect = new Rect();
|
||||||
|
private final Vec2 vec = new Vec2();
|
||||||
|
|
||||||
|
public PhysicsWorld(Rect bounds){
|
||||||
|
for(int i = 0; i < layers; i++){
|
||||||
|
trees[i] = new QuadTree<>(new Rect(bounds));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(PhysicsBody body){
|
||||||
|
bodies.add(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove(PhysicsBody body){
|
||||||
|
bodies.remove(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(){
|
||||||
|
for(int i = 0; i < layers; i++){
|
||||||
|
trees[i].clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < bodies.size; i++){
|
||||||
|
PhysicsBody body = bodies.items[i];
|
||||||
|
body.collided = false;
|
||||||
|
trees[body.layer].insert(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < bodies.size; i++){
|
||||||
|
PhysicsBody body = bodies.items[i];
|
||||||
|
body.hitbox(rect);
|
||||||
|
|
||||||
|
seq.size = 0;
|
||||||
|
trees[body.layer].intersect(rect, seq);
|
||||||
|
|
||||||
|
for(int j = 0; j < seq.size; j++){
|
||||||
|
PhysicsBody other = seq.items[j];
|
||||||
|
|
||||||
|
if(other == body || other.collided) continue;
|
||||||
|
|
||||||
|
float rs = body.radius + other.radius;
|
||||||
|
float dst = Mathf.dst(body.x, body.y, other.x, other.y);
|
||||||
|
|
||||||
|
if(dst < rs){
|
||||||
|
vec.set(body.x - other.x, body.y - other.y).setLength(rs - dst);
|
||||||
|
float ms = body.mass + other.mass;
|
||||||
|
float m1 = other.mass / ms, m2 = body.mass / ms;
|
||||||
|
|
||||||
|
body.x += vec.x * m1 / scl;
|
||||||
|
body.y += vec.y * m1 / scl;
|
||||||
|
other.x -= vec.x * m2 / scl;
|
||||||
|
other.y -= vec.y * m2 / scl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
body.collided = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PhysicsBody implements QuadTreeObject{
|
||||||
|
public float x, y, radius, mass;
|
||||||
|
public int layer = 0;
|
||||||
|
public boolean collided = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void hitbox(Rect out){
|
||||||
|
out.setCentered(x, y, radius * 2, radius * 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -208,6 +208,7 @@ public class Blocks implements ContentList{
|
|||||||
liquidDrop = Liquids.slag;
|
liquidDrop = Liquids.slag;
|
||||||
isLiquid = true;
|
isLiquid = true;
|
||||||
cacheLayer = CacheLayer.slag;
|
cacheLayer = CacheLayer.slag;
|
||||||
|
attributes.set(Attribute.heat, 0.85f);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
stone = new Floor("stone");
|
stone = new Floor("stone");
|
||||||
@@ -265,7 +266,7 @@ public class Blocks implements ContentList{
|
|||||||
variants = 3;
|
variants = 3;
|
||||||
status = StatusEffects.muddy;
|
status = StatusEffects.muddy;
|
||||||
statusDuration = 30f;
|
statusDuration = 30f;
|
||||||
attributes.set(Attribute.water, 2f);
|
attributes.set(Attribute.water, 1f);
|
||||||
cacheLayer = CacheLayer.mud;
|
cacheLayer = CacheLayer.mud;
|
||||||
albedo = 0.35f;
|
albedo = 0.35f;
|
||||||
}};
|
}};
|
||||||
@@ -865,7 +866,8 @@ public class Blocks implements ContentList{
|
|||||||
size = 2;
|
size = 2;
|
||||||
reload = 250f;
|
reload = 250f;
|
||||||
range = 85f;
|
range = 85f;
|
||||||
healPercent = 14f;
|
healPercent = 11f;
|
||||||
|
phaseBoost = 15f;
|
||||||
health = 80 * size * size;
|
health = 80 * size * size;
|
||||||
consumes.item(Items.phasefabric).boost();
|
consumes.item(Items.phasefabric).boost();
|
||||||
}};
|
}};
|
||||||
@@ -1142,13 +1144,14 @@ public class Blocks implements ContentList{
|
|||||||
powerProduction = 1.8f;
|
powerProduction = 1.8f;
|
||||||
generateEffect = Fx.redgeneratespark;
|
generateEffect = Fx.redgeneratespark;
|
||||||
size = 2;
|
size = 2;
|
||||||
|
floating = true;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
steamGenerator = new BurnerGenerator("steam-generator"){{
|
steamGenerator = new BurnerGenerator("steam-generator"){{
|
||||||
requirements(Category.power, with(Items.copper, 35, Items.graphite, 25, Items.lead, 40, Items.silicon, 30));
|
requirements(Category.power, with(Items.copper, 35, Items.graphite, 25, Items.lead, 40, Items.silicon, 30));
|
||||||
powerProduction = 5.5f;
|
powerProduction = 5.5f;
|
||||||
itemDuration = 90f;
|
itemDuration = 90f;
|
||||||
consumes.liquid(Liquids.water, 0.09f);
|
consumes.liquid(Liquids.water, 0.1f);
|
||||||
hasLiquids = true;
|
hasLiquids = true;
|
||||||
size = 2;
|
size = 2;
|
||||||
}};
|
}};
|
||||||
@@ -1268,7 +1271,7 @@ public class Blocks implements ContentList{
|
|||||||
rotateSpeed = 1.4f;
|
rotateSpeed = 1.4f;
|
||||||
attribute = Attribute.water;
|
attribute = Attribute.water;
|
||||||
|
|
||||||
consumes.power(1.25f);
|
consumes.power(1.5f);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
cultivator = new Cultivator("cultivator"){{
|
cultivator = new Cultivator("cultivator"){{
|
||||||
@@ -1751,6 +1754,7 @@ public class Blocks implements ContentList{
|
|||||||
};
|
};
|
||||||
size = 3;
|
size = 3;
|
||||||
consumes.power(1.2f);
|
consumes.power(1.2f);
|
||||||
|
floating = true;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
additiveReconstructor = new Reconstructor("additive-reconstructor"){{
|
additiveReconstructor = new Reconstructor("additive-reconstructor"){{
|
||||||
|
|||||||
@@ -378,7 +378,11 @@ public class TechTree implements ContentList{
|
|||||||
node(nova, () -> {
|
node(nova, () -> {
|
||||||
node(pulsar, () -> {
|
node(pulsar, () -> {
|
||||||
node(quasar, () -> {
|
node(quasar, () -> {
|
||||||
|
node(vela, () -> {
|
||||||
|
node(corvus, () -> {
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ public class UnitTypes implements ContentList{
|
|||||||
|
|
||||||
dagger = new UnitType("dagger"){{
|
dagger = new UnitType("dagger"){{
|
||||||
speed = 0.5f;
|
speed = 0.5f;
|
||||||
hitsize = 8f;
|
hitSize = 8f;
|
||||||
health = 140;
|
health = 140;
|
||||||
weapons.add(new Weapon("large-weapon"){{
|
weapons.add(new Weapon("large-weapon"){{
|
||||||
reload = 14f;
|
reload = 14f;
|
||||||
@@ -83,7 +83,7 @@ public class UnitTypes implements ContentList{
|
|||||||
|
|
||||||
mace = new UnitType("mace"){{
|
mace = new UnitType("mace"){{
|
||||||
speed = 0.4f;
|
speed = 0.4f;
|
||||||
hitsize = 9f;
|
hitSize = 9f;
|
||||||
health = 500;
|
health = 500;
|
||||||
armor = 4f;
|
armor = 4f;
|
||||||
|
|
||||||
@@ -114,7 +114,7 @@ public class UnitTypes implements ContentList{
|
|||||||
|
|
||||||
fortress = new UnitType("fortress"){{
|
fortress = new UnitType("fortress"){{
|
||||||
speed = 0.38f;
|
speed = 0.38f;
|
||||||
hitsize = 13f;
|
hitSize = 13f;
|
||||||
rotateSpeed = 3f;
|
rotateSpeed = 3f;
|
||||||
targetAir = false;
|
targetAir = false;
|
||||||
health = 790;
|
health = 790;
|
||||||
@@ -147,7 +147,7 @@ public class UnitTypes implements ContentList{
|
|||||||
|
|
||||||
scepter = new UnitType("scepter"){{
|
scepter = new UnitType("scepter"){{
|
||||||
speed = 0.35f;
|
speed = 0.35f;
|
||||||
hitsize = 20f;
|
hitSize = 20f;
|
||||||
rotateSpeed = 2.1f;
|
rotateSpeed = 2.1f;
|
||||||
health = 9000;
|
health = 9000;
|
||||||
armor = 11f;
|
armor = 11f;
|
||||||
@@ -156,6 +156,7 @@ public class UnitTypes implements ContentList{
|
|||||||
|
|
||||||
mechStepParticles = true;
|
mechStepParticles = true;
|
||||||
mechStepShake = 0.15f;
|
mechStepShake = 0.15f;
|
||||||
|
singleTarget = true;
|
||||||
|
|
||||||
weapons.add(
|
weapons.add(
|
||||||
new Weapon("scepter-weapon"){{
|
new Weapon("scepter-weapon"){{
|
||||||
@@ -207,7 +208,7 @@ public class UnitTypes implements ContentList{
|
|||||||
|
|
||||||
reign = new UnitType("reign"){{
|
reign = new UnitType("reign"){{
|
||||||
speed = 0.35f;
|
speed = 0.35f;
|
||||||
hitsize = 26f;
|
hitSize = 26f;
|
||||||
rotateSpeed = 1.65f;
|
rotateSpeed = 1.65f;
|
||||||
health = 24000;
|
health = 24000;
|
||||||
armor = 14f;
|
armor = 14f;
|
||||||
@@ -269,13 +270,14 @@ public class UnitTypes implements ContentList{
|
|||||||
canBoost = true;
|
canBoost = true;
|
||||||
boostMultiplier = 1.5f;
|
boostMultiplier = 1.5f;
|
||||||
speed = 0.55f;
|
speed = 0.55f;
|
||||||
hitsize = 8f;
|
hitSize = 8f;
|
||||||
health = 110f;
|
health = 110f;
|
||||||
buildSpeed = 0.8f;
|
buildSpeed = 0.8f;
|
||||||
armor = 1f;
|
armor = 1f;
|
||||||
commandLimit = 8;
|
commandLimit = 8;
|
||||||
|
|
||||||
abilities.add(new HealFieldAbility(10f, 60f * 4, 60f));
|
abilities.add(new HealFieldAbility(10f, 60f * 4, 60f));
|
||||||
|
ammoType = AmmoTypes.power;
|
||||||
|
|
||||||
weapons.add(new Weapon("heal-weapon"){{
|
weapons.add(new Weapon("heal-weapon"){{
|
||||||
top = false;
|
top = false;
|
||||||
@@ -295,16 +297,17 @@ public class UnitTypes implements ContentList{
|
|||||||
canBoost = true;
|
canBoost = true;
|
||||||
boostMultiplier = 1.5f;
|
boostMultiplier = 1.5f;
|
||||||
speed = 0.65f;
|
speed = 0.65f;
|
||||||
hitsize = 10f;
|
hitSize = 10f;
|
||||||
health = 320f;
|
health = 320f;
|
||||||
buildSpeed = 0.9f;
|
buildSpeed = 0.9f;
|
||||||
armor = 4f;
|
armor = 4f;
|
||||||
|
|
||||||
mineTier = 2;
|
mineTier = 2;
|
||||||
mineSpeed = 5f;
|
mineSpeed = 5f;
|
||||||
commandLimit = 15;
|
commandLimit = 8;
|
||||||
|
|
||||||
abilities.add(new ShieldFieldAbility(20f, 40f, 60f * 5, 60f));
|
abilities.add(new ShieldFieldAbility(20f, 40f, 60f * 5, 60f));
|
||||||
|
ammoType = AmmoTypes.power;
|
||||||
|
|
||||||
weapons.add(new Weapon("heal-shotgun-weapon"){{
|
weapons.add(new Weapon("heal-shotgun-weapon"){{
|
||||||
top = false;
|
top = false;
|
||||||
@@ -335,7 +338,7 @@ public class UnitTypes implements ContentList{
|
|||||||
|
|
||||||
quasar = new UnitType("quasar"){{
|
quasar = new UnitType("quasar"){{
|
||||||
mineTier = 1;
|
mineTier = 1;
|
||||||
hitsize = 12f;
|
hitSize = 12f;
|
||||||
boostMultiplier = 2f;
|
boostMultiplier = 2f;
|
||||||
itemCapacity = 80;
|
itemCapacity = 80;
|
||||||
health = 650f;
|
health = 650f;
|
||||||
@@ -344,11 +347,12 @@ public class UnitTypes implements ContentList{
|
|||||||
armor = 9f;
|
armor = 9f;
|
||||||
landShake = 2f;
|
landShake = 2f;
|
||||||
|
|
||||||
commandLimit = 18;
|
commandLimit = 10;
|
||||||
mechFrontSway = 0.55f;
|
mechFrontSway = 0.55f;
|
||||||
|
ammoType = AmmoTypes.power;
|
||||||
|
|
||||||
speed = 0.4f;
|
speed = 0.4f;
|
||||||
hitsize = 10f;
|
hitSize = 10f;
|
||||||
|
|
||||||
mineTier = 2;
|
mineTier = 2;
|
||||||
mineSpeed = 7f;
|
mineSpeed = 7f;
|
||||||
@@ -377,7 +381,7 @@ public class UnitTypes implements ContentList{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
vela = new UnitType("vela"){{
|
vela = new UnitType("vela"){{
|
||||||
hitsize = 23f;
|
hitSize = 23f;
|
||||||
|
|
||||||
rotateSpeed = 1.6f;
|
rotateSpeed = 1.6f;
|
||||||
canDrown = false;
|
canDrown = false;
|
||||||
@@ -385,6 +389,7 @@ public class UnitTypes implements ContentList{
|
|||||||
|
|
||||||
mechStepParticles = true;
|
mechStepParticles = true;
|
||||||
mechStepShake = 0.15f;
|
mechStepShake = 0.15f;
|
||||||
|
ammoType = AmmoTypes.powerHigh;
|
||||||
|
|
||||||
speed = 0.35f;
|
speed = 0.35f;
|
||||||
boostMultiplier = 2.1f;
|
boostMultiplier = 2.1f;
|
||||||
@@ -392,12 +397,12 @@ public class UnitTypes implements ContentList{
|
|||||||
engineSize = 6f;
|
engineSize = 6f;
|
||||||
lowAltitude = true;
|
lowAltitude = true;
|
||||||
|
|
||||||
health = 6000f;
|
health = 6500f;
|
||||||
armor = 7f;
|
armor = 7f;
|
||||||
canBoost = true;
|
canBoost = true;
|
||||||
landShake = 4f;
|
landShake = 4f;
|
||||||
|
|
||||||
commandLimit = 20;
|
commandLimit = 8;
|
||||||
|
|
||||||
weapons.add(new Weapon("vela-weapon"){{
|
weapons.add(new Weapon("vela-weapon"){{
|
||||||
mirror = false;
|
mirror = false;
|
||||||
@@ -414,7 +419,7 @@ public class UnitTypes implements ContentList{
|
|||||||
continuous = true;
|
continuous = true;
|
||||||
cooldownTime = 200f;
|
cooldownTime = 200f;
|
||||||
|
|
||||||
bullet = new ContinuousLaserBulletType(16){{
|
bullet = new ContinuousLaserBulletType(17){{
|
||||||
length = 150f;
|
length = 150f;
|
||||||
hitEffect = Fx.hitMeltHeal;
|
hitEffect = Fx.hitMeltHeal;
|
||||||
drawSize = 420f;
|
drawSize = 420f;
|
||||||
@@ -439,7 +444,7 @@ public class UnitTypes implements ContentList{
|
|||||||
|
|
||||||
corvus = new UnitType("corvus"){{
|
corvus = new UnitType("corvus"){{
|
||||||
mineTier = 1;
|
mineTier = 1;
|
||||||
hitsize = 29f;
|
hitSize = 29f;
|
||||||
itemCapacity = 80;
|
itemCapacity = 80;
|
||||||
health = 19000f;
|
health = 19000f;
|
||||||
buildSpeed = 1.7f;
|
buildSpeed = 1.7f;
|
||||||
@@ -447,7 +452,7 @@ public class UnitTypes implements ContentList{
|
|||||||
landShake = 1.5f;
|
landShake = 1.5f;
|
||||||
rotateSpeed = 1.5f;
|
rotateSpeed = 1.5f;
|
||||||
|
|
||||||
commandLimit = 20;
|
commandLimit = 8;
|
||||||
|
|
||||||
legCount = 4;
|
legCount = 4;
|
||||||
legLength = 14f;
|
legLength = 14f;
|
||||||
@@ -457,6 +462,8 @@ public class UnitTypes implements ContentList{
|
|||||||
hovering = true;
|
hovering = true;
|
||||||
visualElevation = 0.2f;
|
visualElevation = 0.2f;
|
||||||
allowLegStep = true;
|
allowLegStep = true;
|
||||||
|
ammoType = AmmoTypes.powerHigh;
|
||||||
|
groundLayer = Layer.legUnit;
|
||||||
|
|
||||||
speed = 0.3f;
|
speed = 0.3f;
|
||||||
|
|
||||||
@@ -513,7 +520,7 @@ public class UnitTypes implements ContentList{
|
|||||||
defaultController = SuicideAI::new;
|
defaultController = SuicideAI::new;
|
||||||
|
|
||||||
speed = 0.85f;
|
speed = 0.85f;
|
||||||
hitsize = 8f;
|
hitSize = 8f;
|
||||||
health = 180;
|
health = 180;
|
||||||
mechSideSway = 0.25f;
|
mechSideSway = 0.25f;
|
||||||
range = 40f;
|
range = 40f;
|
||||||
@@ -541,7 +548,7 @@ public class UnitTypes implements ContentList{
|
|||||||
itemCapacity = 80;
|
itemCapacity = 80;
|
||||||
speed = 0.5f;
|
speed = 0.5f;
|
||||||
drag = 0.4f;
|
drag = 0.4f;
|
||||||
hitsize = 10f;
|
hitSize = 10f;
|
||||||
rotateSpeed = 3f;
|
rotateSpeed = 3f;
|
||||||
targetAir = false;
|
targetAir = false;
|
||||||
health = 600;
|
health = 600;
|
||||||
@@ -581,7 +588,7 @@ public class UnitTypes implements ContentList{
|
|||||||
spiroct = new UnitType("spiroct"){{
|
spiroct = new UnitType("spiroct"){{
|
||||||
speed = 0.4f;
|
speed = 0.4f;
|
||||||
drag = 0.4f;
|
drag = 0.4f;
|
||||||
hitsize = 12f;
|
hitSize = 12f;
|
||||||
rotateSpeed = 3f;
|
rotateSpeed = 3f;
|
||||||
health = 760;
|
health = 760;
|
||||||
immunities = ObjectSet.with(StatusEffects.burning, StatusEffects.melting);
|
immunities = ObjectSet.with(StatusEffects.burning, StatusEffects.melting);
|
||||||
@@ -592,6 +599,7 @@ public class UnitTypes implements ContentList{
|
|||||||
legBaseOffset = 2f;
|
legBaseOffset = 2f;
|
||||||
hovering = true;
|
hovering = true;
|
||||||
armor = 5f;
|
armor = 5f;
|
||||||
|
ammoType = AmmoTypes.power;
|
||||||
|
|
||||||
buildSpeed = 0.75f;
|
buildSpeed = 0.75f;
|
||||||
|
|
||||||
@@ -646,7 +654,7 @@ public class UnitTypes implements ContentList{
|
|||||||
arkyid = new UnitType("arkyid"){{
|
arkyid = new UnitType("arkyid"){{
|
||||||
drag = 0.1f;
|
drag = 0.1f;
|
||||||
speed = 0.5f;
|
speed = 0.5f;
|
||||||
hitsize = 21f;
|
hitSize = 21f;
|
||||||
health = 8000;
|
health = 8000;
|
||||||
armor = 6f;
|
armor = 6f;
|
||||||
|
|
||||||
@@ -663,6 +671,7 @@ public class UnitTypes implements ContentList{
|
|||||||
legLengthScl = 0.96f;
|
legLengthScl = 0.96f;
|
||||||
rippleScale = 2f;
|
rippleScale = 2f;
|
||||||
legSpeed = 0.2f;
|
legSpeed = 0.2f;
|
||||||
|
ammoType = AmmoTypes.power;
|
||||||
|
|
||||||
legSplashDamage = 32;
|
legSplashDamage = 32;
|
||||||
legSplashRange = 30;
|
legSplashRange = 30;
|
||||||
@@ -744,7 +753,7 @@ public class UnitTypes implements ContentList{
|
|||||||
toxopid = new UnitType("toxopid"){{
|
toxopid = new UnitType("toxopid"){{
|
||||||
drag = 0.1f;
|
drag = 0.1f;
|
||||||
speed = 0.5f;
|
speed = 0.5f;
|
||||||
hitsize = 21f;
|
hitSize = 21f;
|
||||||
health = 22000;
|
health = 22000;
|
||||||
armor = 13f;
|
armor = 13f;
|
||||||
|
|
||||||
@@ -761,6 +770,7 @@ public class UnitTypes implements ContentList{
|
|||||||
legLengthScl = 0.93f;
|
legLengthScl = 0.93f;
|
||||||
rippleScale = 3f;
|
rippleScale = 3f;
|
||||||
legSpeed = 0.19f;
|
legSpeed = 0.19f;
|
||||||
|
ammoType = AmmoTypes.powerHigh;
|
||||||
|
|
||||||
legSplashDamage = 80;
|
legSplashDamage = 80;
|
||||||
legSplashRange = 60;
|
legSplashRange = 60;
|
||||||
@@ -875,7 +885,7 @@ public class UnitTypes implements ContentList{
|
|||||||
weapons.add(new Weapon(){{
|
weapons.add(new Weapon(){{
|
||||||
y = 0f;
|
y = 0f;
|
||||||
x = 2f;
|
x = 2f;
|
||||||
reload = 15f;
|
reload = 13f;
|
||||||
ejectEffect = Fx.shellEjectSmall;
|
ejectEffect = Fx.shellEjectSmall;
|
||||||
bullet = Bullets.standardCopper;
|
bullet = Bullets.standardCopper;
|
||||||
shootSound = Sounds.shoot;
|
shootSound = Sounds.shoot;
|
||||||
@@ -888,7 +898,7 @@ public class UnitTypes implements ContentList{
|
|||||||
accel = 0.08f;
|
accel = 0.08f;
|
||||||
drag = 0.016f;
|
drag = 0.016f;
|
||||||
flying = true;
|
flying = true;
|
||||||
hitsize = 9f;
|
hitSize = 9f;
|
||||||
targetAir = false;
|
targetAir = false;
|
||||||
engineOffset = 7.8f;
|
engineOffset = 7.8f;
|
||||||
range = 140f;
|
range = 140f;
|
||||||
@@ -925,7 +935,7 @@ public class UnitTypes implements ContentList{
|
|||||||
drag = 0.016f;
|
drag = 0.016f;
|
||||||
flying = true;
|
flying = true;
|
||||||
range = 140f;
|
range = 140f;
|
||||||
hitsize = 18f;
|
hitSize = 20f;
|
||||||
lowAltitude = true;
|
lowAltitude = true;
|
||||||
armor = 5f;
|
armor = 5f;
|
||||||
|
|
||||||
@@ -963,9 +973,9 @@ public class UnitTypes implements ContentList{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
antumbra = new UnitType("antumbra"){{
|
antumbra = new UnitType("antumbra"){{
|
||||||
speed = 1.13f;
|
speed = 0.8f;
|
||||||
accel = 0.035f;
|
accel = 0.04f;
|
||||||
drag = 0.05f;
|
drag = 0.04f;
|
||||||
rotateSpeed = 1.9f;
|
rotateSpeed = 1.9f;
|
||||||
flying = true;
|
flying = true;
|
||||||
lowAltitude = true;
|
lowAltitude = true;
|
||||||
@@ -973,7 +983,7 @@ public class UnitTypes implements ContentList{
|
|||||||
armor = 9f;
|
armor = 9f;
|
||||||
engineOffset = 21;
|
engineOffset = 21;
|
||||||
engineSize = 5.3f;
|
engineSize = 5.3f;
|
||||||
hitsize = 56f;
|
hitSize = 56f;
|
||||||
|
|
||||||
BulletType missiles = new MissileBulletType(2.7f, 10){{
|
BulletType missiles = new MissileBulletType(2.7f, 10){{
|
||||||
width = 8f;
|
width = 8f;
|
||||||
@@ -1036,16 +1046,16 @@ public class UnitTypes implements ContentList{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
eclipse = new UnitType("eclipse"){{
|
eclipse = new UnitType("eclipse"){{
|
||||||
speed = 1.09f;
|
speed = 0.52f;
|
||||||
accel = 0.02f;
|
accel = 0.04f;
|
||||||
drag = 0.05f;
|
drag = 0.04f;
|
||||||
rotateSpeed = 1f;
|
rotateSpeed = 1f;
|
||||||
flying = true;
|
flying = true;
|
||||||
lowAltitude = true;
|
lowAltitude = true;
|
||||||
health = 20000;
|
health = 20000;
|
||||||
engineOffset = 38;
|
engineOffset = 38;
|
||||||
engineSize = 7.3f;
|
engineSize = 7.3f;
|
||||||
hitsize = 58f;
|
hitSize = 58f;
|
||||||
destructibleWreck = false;
|
destructibleWreck = false;
|
||||||
armor = 13f;
|
armor = 13f;
|
||||||
|
|
||||||
@@ -1128,6 +1138,8 @@ public class UnitTypes implements ContentList{
|
|||||||
range = 50f;
|
range = 50f;
|
||||||
isCounted = false;
|
isCounted = false;
|
||||||
|
|
||||||
|
ammoType = AmmoTypes.powerLow;
|
||||||
|
|
||||||
mineTier = 1;
|
mineTier = 1;
|
||||||
mineSpeed = 2.5f;
|
mineSpeed = 2.5f;
|
||||||
}};
|
}};
|
||||||
@@ -1145,10 +1157,12 @@ public class UnitTypes implements ContentList{
|
|||||||
health = 400;
|
health = 400;
|
||||||
buildSpeed = 0.5f;
|
buildSpeed = 0.5f;
|
||||||
engineOffset = 6.5f;
|
engineOffset = 6.5f;
|
||||||
hitsize = 8f;
|
hitSize = 8f;
|
||||||
lowAltitude = true;
|
lowAltitude = true;
|
||||||
isCounted = false;
|
isCounted = false;
|
||||||
|
|
||||||
|
ammoType = AmmoTypes.power;
|
||||||
|
|
||||||
mineTier = 2;
|
mineTier = 2;
|
||||||
mineSpeed = 3.5f;
|
mineSpeed = 3.5f;
|
||||||
|
|
||||||
@@ -1197,11 +1211,13 @@ public class UnitTypes implements ContentList{
|
|||||||
flying = true;
|
flying = true;
|
||||||
engineOffset = 10.5f;
|
engineOffset = 10.5f;
|
||||||
rotateShooting = false;
|
rotateShooting = false;
|
||||||
hitsize = 15f;
|
hitSize = 15f;
|
||||||
engineSize = 3f;
|
engineSize = 3f;
|
||||||
payloadCapacity = (2 * 2) * tilePayload;
|
payloadCapacity = (2 * 2) * tilePayload;
|
||||||
buildSpeed = 2.5f;
|
buildSpeed = 2.5f;
|
||||||
|
|
||||||
|
ammoType = AmmoTypes.power;
|
||||||
|
|
||||||
weapons.add(
|
weapons.add(
|
||||||
new Weapon("heal-weapon-mount"){{
|
new Weapon("heal-weapon-mount"){{
|
||||||
reload = 25f;
|
reload = 25f;
|
||||||
@@ -1231,12 +1247,14 @@ public class UnitTypes implements ContentList{
|
|||||||
engineOffset = 12f;
|
engineOffset = 12f;
|
||||||
engineSize = 6f;
|
engineSize = 6f;
|
||||||
rotateShooting = false;
|
rotateShooting = false;
|
||||||
hitsize = 32f;
|
hitSize = 32f;
|
||||||
payloadCapacity = (3 * 3) * tilePayload;
|
payloadCapacity = (3 * 3) * tilePayload;
|
||||||
buildSpeed = 2.5f;
|
buildSpeed = 2.5f;
|
||||||
range = 140f;
|
range = 140f;
|
||||||
targetAir = false;
|
targetAir = false;
|
||||||
|
|
||||||
|
ammoType = AmmoTypes.powerHigh;
|
||||||
|
|
||||||
weapons.add(
|
weapons.add(
|
||||||
new Weapon(){{
|
new Weapon(){{
|
||||||
x = y = 0f;
|
x = y = 0f;
|
||||||
@@ -1291,11 +1309,11 @@ public class UnitTypes implements ContentList{
|
|||||||
engineOffset = 46f;
|
engineOffset = 46f;
|
||||||
engineSize = 7.8f;
|
engineSize = 7.8f;
|
||||||
rotateShooting = false;
|
rotateShooting = false;
|
||||||
hitsize = 60f;
|
hitSize = 60f;
|
||||||
payloadCapacity = (5.3f * 5.3f) * tilePayload;
|
payloadCapacity = (5.3f * 5.3f) * tilePayload;
|
||||||
buildSpeed = 4f;
|
buildSpeed = 4f;
|
||||||
drawShields = false;
|
drawShields = false;
|
||||||
commandLimit = 25;
|
commandLimit = 6;
|
||||||
|
|
||||||
abilities.add(new ForceFieldAbility(140f, 4f, 7000f, 60f * 8), new HealFieldAbility(130f, 60f * 2, 140f));
|
abilities.add(new ForceFieldAbility(140f, 4f, 7000f, 60f * 8), new HealFieldAbility(130f, 60f * 2, 140f));
|
||||||
}};
|
}};
|
||||||
@@ -1306,7 +1324,7 @@ public class UnitTypes implements ContentList{
|
|||||||
risso = new UnitType("risso"){{
|
risso = new UnitType("risso"){{
|
||||||
speed = 1.1f;
|
speed = 1.1f;
|
||||||
drag = 0.13f;
|
drag = 0.13f;
|
||||||
hitsize = 9f;
|
hitSize = 9f;
|
||||||
health = 280;
|
health = 280;
|
||||||
accel = 0.4f;
|
accel = 0.4f;
|
||||||
rotateSpeed = 3.3f;
|
rotateSpeed = 3.3f;
|
||||||
@@ -1357,7 +1375,7 @@ public class UnitTypes implements ContentList{
|
|||||||
health = 600;
|
health = 600;
|
||||||
speed = 0.9f;
|
speed = 0.9f;
|
||||||
drag = 0.15f;
|
drag = 0.15f;
|
||||||
hitsize = 11f;
|
hitSize = 11f;
|
||||||
armor = 4f;
|
armor = 4f;
|
||||||
accel = 0.3f;
|
accel = 0.3f;
|
||||||
rotateSpeed = 2.6f;
|
rotateSpeed = 2.6f;
|
||||||
@@ -1400,7 +1418,7 @@ public class UnitTypes implements ContentList{
|
|||||||
accel = 0.2f;
|
accel = 0.2f;
|
||||||
rotateSpeed = 1.8f;
|
rotateSpeed = 1.8f;
|
||||||
drag = 0.17f;
|
drag = 0.17f;
|
||||||
hitsize = 16f;
|
hitSize = 16f;
|
||||||
armor = 7f;
|
armor = 7f;
|
||||||
rotateShooting = false;
|
rotateShooting = false;
|
||||||
|
|
||||||
@@ -1493,7 +1511,7 @@ public class UnitTypes implements ContentList{
|
|||||||
|
|
||||||
speed = 0.73f;
|
speed = 0.73f;
|
||||||
drag = 0.17f;
|
drag = 0.17f;
|
||||||
hitsize = 39f;
|
hitSize = 39f;
|
||||||
accel = 0.2f;
|
accel = 0.2f;
|
||||||
rotateSpeed = 1.3f;
|
rotateSpeed = 1.3f;
|
||||||
rotateShooting = false;
|
rotateShooting = false;
|
||||||
@@ -1576,7 +1594,7 @@ public class UnitTypes implements ContentList{
|
|||||||
health = 22000;
|
health = 22000;
|
||||||
speed = 0.62f;
|
speed = 0.62f;
|
||||||
drag = 0.18f;
|
drag = 0.18f;
|
||||||
hitsize = 50f;
|
hitSize = 50f;
|
||||||
armor = 16f;
|
armor = 16f;
|
||||||
accel = 0.19f;
|
accel = 0.19f;
|
||||||
rotateSpeed = 0.9f;
|
rotateSpeed = 0.9f;
|
||||||
@@ -1639,7 +1657,7 @@ public class UnitTypes implements ContentList{
|
|||||||
itemCapacity = 30;
|
itemCapacity = 30;
|
||||||
health = 120f;
|
health = 120f;
|
||||||
engineOffset = 6f;
|
engineOffset = 6f;
|
||||||
hitsize = 8f;
|
hitSize = 8f;
|
||||||
|
|
||||||
weapons.add(new Weapon("small-basic-weapon"){{
|
weapons.add(new Weapon("small-basic-weapon"){{
|
||||||
reload = 17f;
|
reload = 17f;
|
||||||
@@ -1673,7 +1691,7 @@ public class UnitTypes implements ContentList{
|
|||||||
itemCapacity = 50;
|
itemCapacity = 50;
|
||||||
health = 150f;
|
health = 150f;
|
||||||
engineOffset = 6f;
|
engineOffset = 6f;
|
||||||
hitsize = 9f;
|
hitSize = 9f;
|
||||||
rotateShooting = false;
|
rotateShooting = false;
|
||||||
lowAltitude = true;
|
lowAltitude = true;
|
||||||
|
|
||||||
@@ -1713,7 +1731,7 @@ public class UnitTypes implements ContentList{
|
|||||||
itemCapacity = 70;
|
itemCapacity = 70;
|
||||||
health = 190f;
|
health = 190f;
|
||||||
engineOffset = 6f;
|
engineOffset = 6f;
|
||||||
hitsize = 10f;
|
hitSize = 10f;
|
||||||
|
|
||||||
weapons.add(new Weapon("small-mount-weapon"){{
|
weapons.add(new Weapon("small-mount-weapon"){{
|
||||||
top = false;
|
top = false;
|
||||||
@@ -1743,7 +1761,7 @@ public class UnitTypes implements ContentList{
|
|||||||
block = new UnitType("block"){
|
block = new UnitType("block"){
|
||||||
{
|
{
|
||||||
speed = 0f;
|
speed = 0f;
|
||||||
hitsize = 0f;
|
hitSize = 0f;
|
||||||
health = 1;
|
health = 1;
|
||||||
rotateSpeed = 360f;
|
rotateSpeed = 360f;
|
||||||
itemCapacity = 0;
|
itemCapacity = 0;
|
||||||
|
|||||||
@@ -170,12 +170,13 @@ public class Weathers implements ContentList{
|
|||||||
sandstorm = new Weather("sandstorm"){
|
sandstorm = new Weather("sandstorm"){
|
||||||
TextureRegion region;
|
TextureRegion region;
|
||||||
float size = 140f, padding = size, invDensity = 1500f, baseSpeed = 6.1f;
|
float size = 140f, padding = size, invDensity = 1500f, baseSpeed = 6.1f;
|
||||||
float force = 0.45f;
|
float force = 0.4f * 0;
|
||||||
Color color = Color.valueOf("f7cba4");
|
Color color = Color.valueOf("f7cba4");
|
||||||
Texture noise;
|
Texture noise;
|
||||||
|
|
||||||
{
|
{
|
||||||
attrs.set(Attribute.light, -0.1f);
|
attrs.set(Attribute.light, -0.1f);
|
||||||
|
opacityMultiplier = 0.8f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -250,7 +251,7 @@ public class Weathers implements ContentList{
|
|||||||
|
|
||||||
sporestorm = new Weather("sporestorm"){
|
sporestorm = new Weather("sporestorm"){
|
||||||
TextureRegion region;
|
TextureRegion region;
|
||||||
float size = 5f, padding = size, invDensity = 2000f, baseSpeed = 4.3f, force = 0.28f;
|
float size = 5f, padding = size, invDensity = 2000f, baseSpeed = 4.3f, force = 0.28f * 0;
|
||||||
Color color = Color.valueOf("7457ce");
|
Color color = Color.valueOf("7457ce");
|
||||||
Texture noise;
|
Texture noise;
|
||||||
|
|
||||||
@@ -259,6 +260,7 @@ public class Weathers implements ContentList{
|
|||||||
attrs.set(Attribute.light, -0.15f);
|
attrs.set(Attribute.light, -0.15f);
|
||||||
status = StatusEffects.sporeSlowed;
|
status = StatusEffects.sporeSlowed;
|
||||||
statusGround = false;
|
statusGround = false;
|
||||||
|
opacityMultiplier = 0.85f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ public class ContentLoader{
|
|||||||
new StatusEffects(),
|
new StatusEffects(),
|
||||||
new Liquids(),
|
new Liquids(),
|
||||||
new Bullets(),
|
new Bullets(),
|
||||||
|
new AmmoTypes(),
|
||||||
new UnitTypes(),
|
new UnitTypes(),
|
||||||
new Blocks(),
|
new Blocks(),
|
||||||
new Loadouts(),
|
new Loadouts(),
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public class GameState{
|
|||||||
/** Wave countdown in ticks. */
|
/** Wave countdown in ticks. */
|
||||||
public float wavetime;
|
public float wavetime;
|
||||||
/** Whether the game is in game over state. */
|
/** Whether the game is in game over state. */
|
||||||
public boolean gameOver = false, launched = false, serverPaused = false, wasTimeout;
|
public boolean gameOver = false, serverPaused = false, wasTimeout;
|
||||||
/** Map that is currently being played on. */
|
/** Map that is currently being played on. */
|
||||||
public @NonNull Map map = emptyMap;
|
public @NonNull Map map = emptyMap;
|
||||||
/** The current game rules. */
|
/** The current game rules. */
|
||||||
@@ -52,7 +52,7 @@ public class GameState{
|
|||||||
|
|
||||||
/** @return whether the player is in a campaign and they are out of sector time */
|
/** @return whether the player is in a campaign and they are out of sector time */
|
||||||
public boolean isOutOfTime(){
|
public boolean isOutOfTime(){
|
||||||
return isCampaign() && isGame() && getSector().getTimeSpent() >= turnDuration;
|
return isCampaign() && isGame() && getSector().getTimeSpent() >= turnDuration && !net.active();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasSector(){
|
public boolean hasSector(){
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import arc.*;
|
|||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
import mindustry.content.*;
|
|
||||||
import mindustry.core.GameState.*;
|
import mindustry.core.GameState.*;
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
@@ -178,7 +177,7 @@ public class Logic implements ApplicationListener{
|
|||||||
public void runWave(){
|
public void runWave(){
|
||||||
spawner.spawnEnemies();
|
spawner.spawnEnemies();
|
||||||
state.wave++;
|
state.wave++;
|
||||||
state.wavetime = state.hasSector() && state.getSector().isLaunchWave(state.wave) ? state.rules.waveSpacing * state.rules.launchWaveMultiplier : state.rules.waveSpacing;
|
state.wavetime = state.rules.waveSpacing;
|
||||||
|
|
||||||
Events.fire(new WaveEvent());
|
Events.fire(new WaveEvent());
|
||||||
}
|
}
|
||||||
@@ -251,58 +250,6 @@ public class Logic implements ApplicationListener{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Remote(called = Loc.both)
|
|
||||||
public static void launchZone(){
|
|
||||||
if(!state.isCampaign()) return;
|
|
||||||
|
|
||||||
if(!headless){
|
|
||||||
ui.hudfrag.showLaunch();
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO better core launch effect
|
|
||||||
for(Building tile : state.teams.playerCores()){
|
|
||||||
Fx.launch.at(tile);
|
|
||||||
}
|
|
||||||
|
|
||||||
Sector sector = state.rules.sector;
|
|
||||||
|
|
||||||
//TODO containers must be launched too
|
|
||||||
Time.runTask(30f, () -> {
|
|
||||||
Sector origin = sector.save.meta.secinfo.origin;
|
|
||||||
if(origin != null){
|
|
||||||
ItemSeq stacks = origin.getExtraItems();
|
|
||||||
|
|
||||||
//add up all items into list
|
|
||||||
for(Building entity : state.teams.playerCores()){
|
|
||||||
entity.items.each(stacks::add);
|
|
||||||
}
|
|
||||||
|
|
||||||
//save received items
|
|
||||||
origin.setExtraItems(stacks);
|
|
||||||
}
|
|
||||||
|
|
||||||
//remove all the cores
|
|
||||||
state.teams.playerCores().each(b -> b.tile.remove());
|
|
||||||
|
|
||||||
state.launched = true;
|
|
||||||
state.gameOver = true;
|
|
||||||
|
|
||||||
//save over the data w/o the cores
|
|
||||||
sector.save.save();
|
|
||||||
|
|
||||||
//run a turn, since launching takes up a turn
|
|
||||||
universe.runTurn();
|
|
||||||
|
|
||||||
//TODO apply extra damage to sector
|
|
||||||
//sector.setTurnsPassed(sector.getTurnsPassed() + 3);
|
|
||||||
|
|
||||||
//TODO load the sector that was launched from
|
|
||||||
Events.fire(new LaunchEvent());
|
|
||||||
//manually fire game over event now
|
|
||||||
Events.fire(new GameOverEvent(state.rules.defaultTeam));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Remote(called = Loc.both)
|
@Remote(called = Loc.both)
|
||||||
public static void updateGameOver(Team winner){
|
public static void updateGameOver(Team winner){
|
||||||
state.gameOver = true;
|
state.gameOver = true;
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ public class NetServer implements ApplicationListener{
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Time.millis() < info.lastKicked){
|
if(Time.millis() < admins.getKickTime(uuid, con.address)){
|
||||||
con.kick(KickReason.recentKick);
|
con.kick(KickReason.recentKick);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,10 +14,18 @@ import mindustry.type.*;
|
|||||||
import mindustry.ui.dialogs.*;
|
import mindustry.ui.dialogs.*;
|
||||||
import rhino.*;
|
import rhino.*;
|
||||||
|
|
||||||
|
import java.net.*;
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public interface Platform{
|
public interface Platform{
|
||||||
|
|
||||||
|
/** Dynamically loads a jar file. */
|
||||||
|
default Class<?> loadJar(Fi jar, String mainClass) throws Exception{
|
||||||
|
URLClassLoader classLoader = new URLClassLoader(new URL[]{jar.file().toURI().toURL()}, ClassLoader.getSystemClassLoader());
|
||||||
|
return classLoader.loadClass(mainClass);
|
||||||
|
}
|
||||||
|
|
||||||
/** Steam: Update lobby visibility.*/
|
/** Steam: Update lobby visibility.*/
|
||||||
default void updateLobby(){}
|
default void updateLobby(){}
|
||||||
|
|
||||||
@@ -121,7 +129,7 @@ public interface Platform{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show a file chooser for multiple file types. Only supported on desktop.
|
* Show a file chooser for multiple file types.
|
||||||
* @param cons Selection listener
|
* @param cons Selection listener
|
||||||
* @param extensions File extensions to filter
|
* @param extensions File extensions to filter
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ public enum ContentType{
|
|||||||
loadout_UNUSED,
|
loadout_UNUSED,
|
||||||
typeid_UNUSED,
|
typeid_UNUSED,
|
||||||
error,
|
error,
|
||||||
planet;
|
planet,
|
||||||
|
ammo;
|
||||||
|
|
||||||
public static final ContentType[] all = values();
|
public static final ContentType[] all = values();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -257,6 +257,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
player.set(world.width() * tilesize/2f, world.height() * tilesize/2f);
|
player.set(world.width() * tilesize/2f, world.height() * tilesize/2f);
|
||||||
player.clearUnit();
|
player.clearUnit();
|
||||||
Groups.unit.clear();
|
Groups.unit.clear();
|
||||||
|
Groups.build.clear();
|
||||||
logic.play();
|
logic.play();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,17 +24,17 @@ public class Lightning{
|
|||||||
|
|
||||||
/** Create a lighting branch at a location. Use Team.derelict to damage everyone. */
|
/** Create a lighting branch at a location. Use Team.derelict to damage everyone. */
|
||||||
public static void create(Team team, Color color, float damage, float x, float y, float targetAngle, int length){
|
public static void create(Team team, Color color, float damage, float x, float y, float targetAngle, int length){
|
||||||
createLightingInternal(null, lastSeed++, team, color, damage, x, y, targetAngle, length);
|
createLightningInternal(null, lastSeed++, team, color, damage, x, y, targetAngle, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create a lighting branch at a location. Uses bullet parameters. */
|
/** Create a lighting branch at a location. Uses bullet parameters. */
|
||||||
public static void create(Bullet bullet, Color color, float damage, float x, float y, float targetAngle, int length){
|
public static void create(Bullet bullet, Color color, float damage, float x, float y, float targetAngle, int length){
|
||||||
createLightingInternal(bullet, lastSeed++, bullet.team, color, damage, x, y, targetAngle, length);
|
createLightningInternal(bullet, lastSeed++, bullet.team, color, damage, x, y, targetAngle, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO remote method
|
//TODO remote method
|
||||||
//@Remote(called = Loc.server, unreliable = true)
|
//@Remote(called = Loc.server, unreliable = true)
|
||||||
private static void createLightingInternal(Bullet hitter, int seed, Team team, Color color, float damage, float x, float y, float rotation, int length){
|
private static void createLightningInternal(Bullet hitter, int seed, Team team, Color color, float damage, float x, float y, float rotation, int length){
|
||||||
random.setSeed(seed);
|
random.setSeed(seed);
|
||||||
hit.clear();
|
hit.clear();
|
||||||
|
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ public abstract class BulletType extends Content{
|
|||||||
//additional effects
|
//additional effects
|
||||||
|
|
||||||
public float fragCone = 360f;
|
public float fragCone = 360f;
|
||||||
|
public float fragAngle = 0f;
|
||||||
public int fragBullets = 9;
|
public int fragBullets = 9;
|
||||||
public float fragVelocityMin = 0.2f, fragVelocityMax = 1f, fragLifeMin = 1f, fragLifeMax = 1f;
|
public float fragVelocityMin = 0.2f, fragVelocityMax = 1f, fragLifeMin = 1f, fragLifeMax = 1f;
|
||||||
public BulletType fragBullet = null;
|
public BulletType fragBullet = null;
|
||||||
@@ -101,6 +102,8 @@ public abstract class BulletType extends Content{
|
|||||||
public int lightningLength = 5, lightningLengthRand = 0;
|
public int lightningLength = 5, lightningLengthRand = 0;
|
||||||
/** Use a negative value to use default bullet damage. */
|
/** Use a negative value to use default bullet damage. */
|
||||||
public float lightningDamage = -1;
|
public float lightningDamage = -1;
|
||||||
|
public float lightningCone = 360f;
|
||||||
|
public float lightningAngle = 0f;
|
||||||
|
|
||||||
public float weaveScale = 1f;
|
public float weaveScale = 1f;
|
||||||
public float weaveMag = -1f;
|
public float weaveMag = -1f;
|
||||||
@@ -156,7 +159,7 @@ public abstract class BulletType extends Content{
|
|||||||
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 = b.rotation() + Mathf.range(fragCone/2);
|
float a = b.rotation() + Mathf.range(fragCone/2) + fragAngle;
|
||||||
fragBullet.create(b, x + Angles.trnsx(a, len), y + Angles.trnsy(a, len), a, Mathf.random(fragVelocityMin, fragVelocityMax), Mathf.random(fragLifeMin, fragLifeMax));
|
fragBullet.create(b, x + Angles.trnsx(a, len), y + Angles.trnsy(a, len), a, Mathf.random(fragVelocityMin, fragVelocityMax), Mathf.random(fragLifeMin, fragLifeMax));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -181,7 +184,7 @@ public abstract class BulletType extends Content{
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < lightning; i++){
|
for(int i = 0; i < lightning; i++){
|
||||||
Lightning.create(b, lightningColor, lightningDamage < 0 ? damage : lightningDamage, b.x, b.y, Mathf.random(360f), lightningLength + Mathf.random(lightningLengthRand));
|
Lightning.create(b, lightningColor, lightningDamage < 0 ? damage : lightningDamage, b.x, b.y, b.rotation() + Mathf.range(lightningCone/2) + lightningAngle, lightningLength + Mathf.random(lightningLengthRand));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ public class HealBulletType extends BulletType{
|
|||||||
despawnEffect = Fx.hitLaser;
|
despawnEffect = Fx.hitLaser;
|
||||||
collidesTeam = true;
|
collidesTeam = true;
|
||||||
hittable = false;
|
hittable = false;
|
||||||
|
reflectable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HealBulletType(){
|
public HealBulletType(){
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ abstract class BuilderComp implements Unitc{
|
|||||||
Tile tile = world.tile(current.x, current.y);
|
Tile tile = world.tile(current.x, current.y);
|
||||||
|
|
||||||
if(within(tile, finalPlaceDst)){
|
if(within(tile, finalPlaceDst)){
|
||||||
rotation = Mathf.slerpDelta(rotation, angleTo(tile), 0.4f);
|
lookAt(angleTo(tile));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(tile.block() instanceof ConstructBlock)){
|
if(!(tile.block() instanceof ConstructBlock)){
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ abstract class CommanderComp implements Unitc{
|
|||||||
void command(Formation formation, Seq<Unit> units){
|
void command(Formation formation, Seq<Unit> units){
|
||||||
clearCommand();
|
clearCommand();
|
||||||
|
|
||||||
float spacing = hitSize() * 1f;
|
float spacing = hitSize() * 0.65f;
|
||||||
minFormationSpeed = type().speed;
|
minFormationSpeed = type().speed;
|
||||||
|
|
||||||
controlling.addAll(units);
|
controlling.addAll(units);
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
package mindustry.entities.comp;
|
package mindustry.entities.comp;
|
||||||
|
|
||||||
|
import arc.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
|
import mindustry.game.EventType.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.world.blocks.environment.*;
|
import mindustry.world.blocks.environment.*;
|
||||||
|
|
||||||
@@ -90,7 +92,7 @@ abstract class FlyingComp implements Posc, Velc, Healthc, Hitboxc{
|
|||||||
//TODO is the netClient check necessary?
|
//TODO is the netClient check necessary?
|
||||||
if(drownTime >= 0.999f && !net.client()){
|
if(drownTime >= 0.999f && !net.client()){
|
||||||
kill();
|
kill();
|
||||||
//TODO drown event!
|
Events.fire(new UnitDrownEvent(self()));
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
drownTime = Mathf.lerpDelta(drownTime, 0f, 0.03f);
|
drownTime = Mathf.lerpDelta(drownTime, 0f, 0.03f);
|
||||||
|
|||||||
@@ -1,13 +1,23 @@
|
|||||||
package mindustry.entities.comp;
|
package mindustry.entities.comp;
|
||||||
|
|
||||||
|
import arc.graphics.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
|
import mindustry.content.*;
|
||||||
|
import mindustry.entities.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
|
import mindustry.type.*;
|
||||||
|
import mindustry.world.*;
|
||||||
|
|
||||||
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
abstract class MechComp implements Posc, Flyingc, Hitboxc, Unitc, Mechc, ElevationMovec{
|
abstract class MechComp implements Posc, Flyingc, Hitboxc, Unitc, Mechc, ElevationMovec{
|
||||||
|
@Import float x, y, hitSize;
|
||||||
|
@Import UnitType type;
|
||||||
|
|
||||||
@SyncField(false) @SyncLocal float baseRotation;
|
@SyncField(false) @SyncLocal float baseRotation;
|
||||||
transient float walkTime, walkExtension;
|
transient float walkTime, walkExtension;
|
||||||
transient private boolean walked;
|
transient private boolean walked;
|
||||||
@@ -21,6 +31,49 @@ abstract class MechComp implements Posc, Flyingc, Hitboxc, Unitc, Mechc, Elevati
|
|||||||
walkTime += len;
|
walkTime += len;
|
||||||
walked = false;
|
walked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//update mech effects
|
||||||
|
float extend = walkExtend(false);
|
||||||
|
float base = walkExtend(true);
|
||||||
|
float extendScl = base % 1f;
|
||||||
|
|
||||||
|
float lastExtend = walkExtension;
|
||||||
|
|
||||||
|
if(extendScl < lastExtend && base % 2f > 1f){
|
||||||
|
int side = -Mathf.sign(extend);
|
||||||
|
float width = hitSize / 2f * side, length = type.mechStride * 1.35f;
|
||||||
|
|
||||||
|
float cx = x + Angles.trnsx(baseRotation, length, width),
|
||||||
|
cy = y + Angles.trnsy(baseRotation, length, width);
|
||||||
|
|
||||||
|
if(type.mechStepShake > 0){
|
||||||
|
Effect.shake(type.mechStepShake, type.mechStepShake, cx, cy);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(type.mechStepParticles){
|
||||||
|
Tile tile = world.tileWorld(cx, cy);
|
||||||
|
if(tile != null){
|
||||||
|
Color color = tile.floor().mapColor;
|
||||||
|
Fx.unitLand.at(cx, cy, hitSize/8f, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
walkExtension = extendScl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float walkExtend(boolean scaled){
|
||||||
|
|
||||||
|
//now ranges from -maxExtension to maxExtension*3
|
||||||
|
float raw = walkTime % (type.mechStride * 4);
|
||||||
|
|
||||||
|
if(scaled) return raw / type.mechStride;
|
||||||
|
|
||||||
|
if(raw > type.mechStride*3) raw = raw - type.mechStride * 4;
|
||||||
|
else if(raw > type.mechStride*2) raw = type.mechStride * 2 - raw;
|
||||||
|
else if(raw > type.mechStride) raw = type.mechStride * 2 - raw;
|
||||||
|
|
||||||
|
return raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc, Unitc{
|
|||||||
mineTimer = 0f;
|
mineTimer = 0f;
|
||||||
}else if(mining()){
|
}else if(mining()){
|
||||||
Item item = mineTile.drop();
|
Item item = mineTile.drop();
|
||||||
rotation = Mathf.slerpDelta(rotation, angleTo(mineTile.worldx(), mineTile.worldy()), 0.4f);
|
lookAt(angleTo(mineTile.worldx(), mineTile.worldy()));
|
||||||
mineTimer += Time.delta *type.mineSpeed;
|
mineTimer += Time.delta *type.mineSpeed;
|
||||||
|
|
||||||
if(Mathf.chance(0.06 * Time.delta)){
|
if(Mathf.chance(0.06 * Time.delta)){
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
|
|||||||
|
|
||||||
@Replace
|
@Replace
|
||||||
public float clipSize(){
|
public float clipSize(){
|
||||||
return unit.isNull() ? 20 : unit.type().hitsize * 2f;
|
return unit.isNull() ? 20 : unit.type().hitSize * 2f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -30,9 +30,8 @@ import static mindustry.Vars.*;
|
|||||||
@Component(base = true)
|
@Component(base = true)
|
||||||
abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, Itemsc, Rotc, Unitc, Weaponsc, Drawc, Boundedc, Syncc, Shieldc, Displayable, Senseable{
|
abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, Itemsc, Rotc, Unitc, Weaponsc, Drawc, Boundedc, Syncc, Shieldc, Displayable, Senseable{
|
||||||
|
|
||||||
@Import boolean hovering;
|
@Import boolean hovering, dead;
|
||||||
@Import float x, y, rotation, elevation, maxHealth, drag, armor, hitSize, health;
|
@Import float x, y, rotation, elevation, maxHealth, drag, armor, hitSize, health, ammo;
|
||||||
@Import boolean dead;
|
|
||||||
@Import Team team;
|
@Import Team team;
|
||||||
@Import int id;
|
@Import int id;
|
||||||
|
|
||||||
@@ -41,6 +40,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||||||
boolean spawnedByCore;
|
boolean spawnedByCore;
|
||||||
|
|
||||||
transient Seq<Ability> abilities = new Seq<>(0);
|
transient Seq<Ability> abilities = new Seq<>(0);
|
||||||
|
private transient float resupplyTime = Mathf.random(10f);
|
||||||
|
|
||||||
public void moveAt(Vec2 vector){
|
public void moveAt(Vec2 vector){
|
||||||
moveAt(vector, type.accel);
|
moveAt(vector, type.accel);
|
||||||
@@ -191,7 +191,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||||||
this.maxHealth = type.health;
|
this.maxHealth = type.health;
|
||||||
this.drag = type.drag;
|
this.drag = type.drag;
|
||||||
this.armor = type.armor;
|
this.armor = type.armor;
|
||||||
this.hitSize = type.hitsize;
|
this.hitSize = type.hitSize;
|
||||||
this.hovering = type.hovering;
|
this.hovering = type.hovering;
|
||||||
|
|
||||||
if(controller == null) controller(type.createController());
|
if(controller == null) controller(type.createController());
|
||||||
@@ -245,6 +245,16 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||||||
|
|
||||||
type.update(self());
|
type.update(self());
|
||||||
|
|
||||||
|
if(state.rules.unitAmmo && ammo < type.ammoCapacity - 0.0001f){
|
||||||
|
resupplyTime += Time.delta;
|
||||||
|
|
||||||
|
//resupply only at a fixed interval to prevent lag
|
||||||
|
if(resupplyTime > 10f){
|
||||||
|
type.ammoType.resupply(self());
|
||||||
|
resupplyTime = 0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(abilities.size > 0){
|
if(abilities.size > 0){
|
||||||
for(Ability a : abilities){
|
for(Ability a : abilities){
|
||||||
a.update(self());
|
a.update(self());
|
||||||
@@ -366,7 +376,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||||||
if(!headless){
|
if(!headless){
|
||||||
for(int i = 0; i < type.wreckRegions.length; i++){
|
for(int i = 0; i < type.wreckRegions.length; i++){
|
||||||
if(type.wreckRegions[i].found()){
|
if(type.wreckRegions[i].found()){
|
||||||
float range = type.hitsize/4f;
|
float range = type.hitSize /4f;
|
||||||
Tmp.v1.rnd(range);
|
Tmp.v1.rnd(range);
|
||||||
Effect.decal(type.wreckRegions[i], x + Tmp.v1.x, y + Tmp.v1.y, rotation - 90);
|
Effect.decal(type.wreckRegions[i], x + Tmp.v1.x, y + Tmp.v1.y, rotation - 90);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,6 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc, Velc, Statusc{
|
|||||||
@Import Vec2 vel;
|
@Import Vec2 vel;
|
||||||
@Import UnitType type;
|
@Import UnitType type;
|
||||||
|
|
||||||
/** minimum cursor distance from unit, fixes 'cross-eyed' shooting */
|
|
||||||
static final float minAimDst = 18f;
|
|
||||||
/** temporary weapon sequence number */
|
/** temporary weapon sequence number */
|
||||||
static int sequenceNum = 0;
|
static int sequenceNum = 0;
|
||||||
|
|
||||||
@@ -67,7 +65,7 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc, Velc, Statusc{
|
|||||||
/** Aim at something. This will make all mounts point at it. */
|
/** Aim at something. This will make all mounts point at it. */
|
||||||
void aim(float x, float y){
|
void aim(float x, float y){
|
||||||
Tmp.v1.set(x, y).sub(this.x, this.y);
|
Tmp.v1.set(x, y).sub(this.x, this.y);
|
||||||
if(Tmp.v1.len() < minAimDst) Tmp.v1.setLength(minAimDst);
|
if(Tmp.v1.len() < type.aimDst) Tmp.v1.setLength(type.aimDst);
|
||||||
|
|
||||||
x = Tmp.v1.x + this.x;
|
x = Tmp.v1.x + this.x;
|
||||||
y = Tmp.v1.y + this.y;
|
y = Tmp.v1.y + this.y;
|
||||||
|
|||||||
@@ -1,47 +1,51 @@
|
|||||||
package mindustry.game;
|
package mindustry.game;
|
||||||
|
|
||||||
import arc.struct.Seq;
|
import arc.math.*;
|
||||||
|
import arc.struct.*;
|
||||||
|
import arc.util.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.type.ItemStack;
|
import mindustry.type.*;
|
||||||
|
|
||||||
|
import static mindustry.content.UnitTypes.*;
|
||||||
|
|
||||||
public class DefaultWaves{
|
public class DefaultWaves{
|
||||||
private Seq<SpawnGroup> spawns;
|
private Seq<SpawnGroup> spawns;
|
||||||
|
|
||||||
public Seq<SpawnGroup> get(){
|
public Seq<SpawnGroup> get(){
|
||||||
if(spawns == null && UnitTypes.dagger != null){
|
if(spawns == null && dagger != null){
|
||||||
spawns = Seq.with(
|
spawns = Seq.with(
|
||||||
new SpawnGroup(UnitTypes.dagger){{
|
new SpawnGroup(dagger){{
|
||||||
end = 10;
|
end = 10;
|
||||||
unitScaling = 2f;
|
unitScaling = 2f;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.crawler){{
|
new SpawnGroup(crawler){{
|
||||||
begin = 4;
|
begin = 4;
|
||||||
end = 13;
|
end = 13;
|
||||||
unitAmount = 2;
|
unitAmount = 2;
|
||||||
unitScaling = 1.5f;
|
unitScaling = 1.5f;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.flare){{
|
new SpawnGroup(flare){{
|
||||||
begin = 12;
|
begin = 12;
|
||||||
end = 16;
|
end = 16;
|
||||||
unitScaling = 1f;
|
unitScaling = 1f;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.dagger){{
|
new SpawnGroup(dagger){{
|
||||||
begin = 11;
|
begin = 11;
|
||||||
unitScaling = 1.7f;
|
unitScaling = 1.7f;
|
||||||
spacing = 2;
|
spacing = 2;
|
||||||
max = 4;
|
max = 4;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.pulsar){{
|
new SpawnGroup(pulsar){{
|
||||||
begin = 13;
|
begin = 13;
|
||||||
spacing = 3;
|
spacing = 3;
|
||||||
unitScaling = 0.5f;
|
unitScaling = 0.5f;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.mace){{
|
new SpawnGroup(mace){{
|
||||||
begin = 7;
|
begin = 7;
|
||||||
spacing = 3;
|
spacing = 3;
|
||||||
unitScaling = 2;
|
unitScaling = 2;
|
||||||
@@ -49,28 +53,28 @@ public class DefaultWaves{
|
|||||||
end = 30;
|
end = 30;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.dagger){{
|
new SpawnGroup(dagger){{
|
||||||
begin = 8;
|
begin = 8;
|
||||||
unitScaling = 1;
|
unitScaling = 1;
|
||||||
unitAmount = 4;
|
unitAmount = 4;
|
||||||
spacing = 2;
|
spacing = 2;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.mace){{
|
new SpawnGroup(mace){{
|
||||||
begin = 28;
|
begin = 28;
|
||||||
spacing = 3;
|
spacing = 3;
|
||||||
unitScaling = 1;
|
unitScaling = 1;
|
||||||
end = 40;
|
end = 40;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.mace){{
|
new SpawnGroup(mace){{
|
||||||
begin = 45;
|
begin = 45;
|
||||||
spacing = 3;
|
spacing = 3;
|
||||||
unitScaling = 2;
|
unitScaling = 2;
|
||||||
effect = StatusEffects.overdrive;
|
effect = StatusEffects.overdrive;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.mace){{
|
new SpawnGroup(mace){{
|
||||||
begin = 120;
|
begin = 120;
|
||||||
spacing = 2;
|
spacing = 2;
|
||||||
unitScaling = 3;
|
unitScaling = 3;
|
||||||
@@ -78,13 +82,13 @@ public class DefaultWaves{
|
|||||||
effect = StatusEffects.overdrive;
|
effect = StatusEffects.overdrive;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.flare){{
|
new SpawnGroup(flare){{
|
||||||
begin = 16;
|
begin = 16;
|
||||||
unitScaling = 1;
|
unitScaling = 1;
|
||||||
spacing = 2;
|
spacing = 2;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.dagger){{
|
new SpawnGroup(dagger){{
|
||||||
begin = 82;
|
begin = 82;
|
||||||
spacing = 3;
|
spacing = 3;
|
||||||
unitAmount = 4;
|
unitAmount = 4;
|
||||||
@@ -92,7 +96,7 @@ public class DefaultWaves{
|
|||||||
effect = StatusEffects.overdrive;
|
effect = StatusEffects.overdrive;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.dagger){{
|
new SpawnGroup(dagger){{
|
||||||
begin = 41;
|
begin = 41;
|
||||||
spacing = 5;
|
spacing = 5;
|
||||||
unitAmount = 1;
|
unitAmount = 1;
|
||||||
@@ -100,7 +104,7 @@ public class DefaultWaves{
|
|||||||
effect = StatusEffects.shielded;
|
effect = StatusEffects.shielded;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.fortress){{
|
new SpawnGroup(fortress){{
|
||||||
begin = 40;
|
begin = 40;
|
||||||
spacing = 5;
|
spacing = 5;
|
||||||
unitAmount = 2;
|
unitAmount = 2;
|
||||||
@@ -108,7 +112,7 @@ public class DefaultWaves{
|
|||||||
max = 20;
|
max = 20;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.dagger){{
|
new SpawnGroup(dagger){{
|
||||||
begin = 35;
|
begin = 35;
|
||||||
spacing = 3;
|
spacing = 3;
|
||||||
unitAmount = 4;
|
unitAmount = 4;
|
||||||
@@ -117,7 +121,7 @@ public class DefaultWaves{
|
|||||||
end = 60;
|
end = 60;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.dagger){{
|
new SpawnGroup(dagger){{
|
||||||
begin = 42;
|
begin = 42;
|
||||||
spacing = 3;
|
spacing = 3;
|
||||||
unitAmount = 4;
|
unitAmount = 4;
|
||||||
@@ -126,14 +130,14 @@ public class DefaultWaves{
|
|||||||
end = 130;
|
end = 130;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.horizon){{
|
new SpawnGroup(horizon){{
|
||||||
begin = 40;
|
begin = 40;
|
||||||
unitAmount = 2;
|
unitAmount = 2;
|
||||||
spacing = 2;
|
spacing = 2;
|
||||||
unitScaling = 2;
|
unitScaling = 2;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.flare){{
|
new SpawnGroup(flare){{
|
||||||
begin = 50;
|
begin = 50;
|
||||||
unitAmount = 4;
|
unitAmount = 4;
|
||||||
unitScaling = 3;
|
unitScaling = 3;
|
||||||
@@ -141,7 +145,7 @@ public class DefaultWaves{
|
|||||||
effect = StatusEffects.overdrive;
|
effect = StatusEffects.overdrive;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.zenith){{
|
new SpawnGroup(zenith){{
|
||||||
begin = 50;
|
begin = 50;
|
||||||
unitAmount = 2;
|
unitAmount = 2;
|
||||||
unitScaling = 3;
|
unitScaling = 3;
|
||||||
@@ -149,42 +153,42 @@ public class DefaultWaves{
|
|||||||
max = 16;
|
max = 16;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.horizon){{
|
new SpawnGroup(horizon){{
|
||||||
begin = 53;
|
begin = 53;
|
||||||
unitAmount = 2;
|
unitAmount = 2;
|
||||||
unitScaling = 3;
|
unitScaling = 3;
|
||||||
spacing = 4;
|
spacing = 4;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.atrax){{
|
new SpawnGroup(atrax){{
|
||||||
begin = 31;
|
begin = 31;
|
||||||
unitAmount = 4;
|
unitAmount = 4;
|
||||||
unitScaling = 1;
|
unitScaling = 1;
|
||||||
spacing = 3;
|
spacing = 3;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.scepter){{
|
new SpawnGroup(scepter){{
|
||||||
begin = 41;
|
begin = 41;
|
||||||
unitAmount = 1;
|
unitAmount = 1;
|
||||||
unitScaling = 1;
|
unitScaling = 1;
|
||||||
spacing = 30;
|
spacing = 30;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.reign){{
|
new SpawnGroup(reign){{
|
||||||
begin = 81;
|
begin = 81;
|
||||||
unitAmount = 1;
|
unitAmount = 1;
|
||||||
unitScaling = 1;
|
unitScaling = 1;
|
||||||
spacing = 40;
|
spacing = 40;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.antumbra){{
|
new SpawnGroup(antumbra){{
|
||||||
begin = 131;
|
begin = 131;
|
||||||
unitAmount = 1;
|
unitAmount = 1;
|
||||||
unitScaling = 1;
|
unitScaling = 1;
|
||||||
spacing = 40;
|
spacing = 40;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.horizon){{
|
new SpawnGroup(horizon){{
|
||||||
begin = 90;
|
begin = 90;
|
||||||
unitAmount = 2;
|
unitAmount = 2;
|
||||||
unitScaling = 3;
|
unitScaling = 3;
|
||||||
@@ -194,4 +198,76 @@ public class DefaultWaves{
|
|||||||
}
|
}
|
||||||
return spawns == null ? new Seq<>() : spawns;
|
return spawns == null ? new Seq<>() : spawns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO move elsewhere
|
||||||
|
public static Seq<SpawnGroup> generate(){
|
||||||
|
UnitType[][] species = {
|
||||||
|
{dagger, mace, fortress, scepter, reign},
|
||||||
|
{nova, pulsar, quasar, vela, corvus},
|
||||||
|
{crawler, atrax, spiroct, arkyid, toxopid},
|
||||||
|
//{risso, minke, bryde, sei, omura}, //questionable choices
|
||||||
|
//{mono, poly, mega, quad, oct}, //do not attack
|
||||||
|
{flare, horizon, zenith, antumbra, eclipse}
|
||||||
|
};
|
||||||
|
|
||||||
|
//required progression:
|
||||||
|
//- extra periodic patterns
|
||||||
|
|
||||||
|
Seq<SpawnGroup> out = new Seq<>();
|
||||||
|
|
||||||
|
//max reasonable wave, after which everything gets boring
|
||||||
|
int cap = 400;
|
||||||
|
|
||||||
|
//main sequence
|
||||||
|
float shieldStart = 30, shieldsPerWave = 12;
|
||||||
|
UnitType[] curSpecies = Structs.random(species);
|
||||||
|
int curTier = 0;
|
||||||
|
|
||||||
|
for(int i = 0; i < cap;){
|
||||||
|
int f = i;
|
||||||
|
int next = Mathf.random(15, 25);
|
||||||
|
|
||||||
|
float shieldAmount = Math.max((i - shieldStart) * shieldsPerWave, 0);
|
||||||
|
|
||||||
|
//main progression
|
||||||
|
out.add(new SpawnGroup(curSpecies[Math.min(curTier, curSpecies.length - 1)]){{
|
||||||
|
unitAmount = f == 0 ? 1 : 10;
|
||||||
|
begin = f;
|
||||||
|
end = f + next >= cap ? never : f + next;
|
||||||
|
max = 16;
|
||||||
|
unitScaling = Mathf.random(1f, 2f);
|
||||||
|
shields = shieldAmount;
|
||||||
|
shieldScaling = shieldsPerWave;
|
||||||
|
}});
|
||||||
|
|
||||||
|
//extra progression that tails out, blends in
|
||||||
|
out.add(new SpawnGroup(curSpecies[Math.min(curTier, curSpecies.length - 1)]){{
|
||||||
|
unitAmount = 6;
|
||||||
|
begin = f + next;
|
||||||
|
end = f + next + Mathf.random(8, 12);
|
||||||
|
max = 10;
|
||||||
|
unitScaling = Mathf.random(2f);
|
||||||
|
spacing = Mathf.random(2, 3);
|
||||||
|
shields = shieldAmount;
|
||||||
|
shieldScaling = shieldsPerWave;
|
||||||
|
}});
|
||||||
|
|
||||||
|
i += next;
|
||||||
|
if(curTier < 3 || Mathf.chance(0.2)){
|
||||||
|
curTier ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//do not spawn bosses
|
||||||
|
curTier = Math.min(curTier, 3);
|
||||||
|
|
||||||
|
//small chance to switch species
|
||||||
|
if(Mathf.chance(0.2)){
|
||||||
|
curSpecies = Structs.random(species);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ public class EventType{
|
|||||||
|
|
||||||
public static class WinEvent{}
|
public static class WinEvent{}
|
||||||
public static class LoseEvent{}
|
public static class LoseEvent{}
|
||||||
public static class LaunchEvent{}
|
|
||||||
public static class ResizeEvent{}
|
public static class ResizeEvent{}
|
||||||
public static class MapMakeEvent{}
|
public static class MapMakeEvent{}
|
||||||
public static class MapPublishEvent{}
|
public static class MapPublishEvent{}
|
||||||
@@ -271,6 +270,14 @@ public class EventType{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class UnitDrownEvent{
|
||||||
|
public final Unit unit;
|
||||||
|
|
||||||
|
public UnitDrownEvent(Unit unit){
|
||||||
|
this.unit = unit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class UnitCreateEvent{
|
public static class UnitCreateEvent{
|
||||||
public final Unit unit;
|
public final Unit unit;
|
||||||
|
|
||||||
|
|||||||
@@ -68,8 +68,6 @@ public class Rules{
|
|||||||
public float dropZoneRadius = 300f;
|
public float dropZoneRadius = 300f;
|
||||||
/** Time between waves in ticks. */
|
/** Time between waves in ticks. */
|
||||||
public float waveSpacing = 60 * 60 * 2;
|
public float waveSpacing = 60 * 60 * 2;
|
||||||
/** How many times longer a launch wave takes. */
|
|
||||||
public float launchWaveMultiplier = 2f;
|
|
||||||
/** Wave after which the player 'wins'. Used in sectors. Use a value <= 0 to disable. */
|
/** Wave after which the player 'wins'. Used in sectors. Use a value <= 0 to disable. */
|
||||||
public int winWave = 0;
|
public int winWave = 0;
|
||||||
/** Base unit cap. Can still be increased by blocks. */
|
/** Base unit cap. Can still be increased by blocks. */
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ public class Stats{
|
|||||||
/** Friendly buildings destroyed. */
|
/** Friendly buildings destroyed. */
|
||||||
public int buildingsDestroyed;
|
public int buildingsDestroyed;
|
||||||
|
|
||||||
|
//TODO fix
|
||||||
public RankResult calculateRank(Sector zone, boolean launched){
|
public RankResult calculateRank(Sector zone, boolean launched){
|
||||||
float score = 0;
|
float score = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -84,6 +84,18 @@ public class Drawf{
|
|||||||
Draw.color();
|
Draw.color();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void shadow(TextureRegion region, float x, float y, float rotation){
|
||||||
|
Draw.color(Pal.shadow);
|
||||||
|
Draw.rect(region, x, y, rotation);
|
||||||
|
Draw.color();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void shadow(TextureRegion region, float x, float y){
|
||||||
|
Draw.color(Pal.shadow);
|
||||||
|
Draw.rect(region, x, y);
|
||||||
|
Draw.color();
|
||||||
|
}
|
||||||
|
|
||||||
public static void dashCircle(float x, float y, float rad, Color color){
|
public static void dashCircle(float x, float y, float rad, Color color){
|
||||||
Lines.stroke(3f, Pal.gray);
|
Lines.stroke(3f, Pal.gray);
|
||||||
Lines.dashCircle(x, y, rad);
|
Lines.dashCircle(x, y, rad);
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ public class FloorRenderer implements Disposable{
|
|||||||
int chunksx = Mathf.ceil((float)(world.width()) / chunksize),
|
int chunksx = Mathf.ceil((float)(world.width()) / chunksize),
|
||||||
chunksy = Mathf.ceil((float)(world.height()) / chunksize);
|
chunksy = Mathf.ceil((float)(world.height()) / chunksize);
|
||||||
cache = new Chunk[chunksx][chunksy];
|
cache = new Chunk[chunksx][chunksy];
|
||||||
cbatch = new MultiCacheBatch(chunksize * chunksize * 7);
|
cbatch = new MultiCacheBatch(chunksize * chunksize * 8);
|
||||||
|
|
||||||
Time.mark();
|
Time.mark();
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import arc.util.*;
|
|||||||
public class IndexedRenderer implements Disposable{
|
public class IndexedRenderer implements Disposable{
|
||||||
private static final int vsize = 5;
|
private static final int vsize = 5;
|
||||||
|
|
||||||
private Shader program = new Shader(
|
private final Shader program = new Shader(
|
||||||
"attribute vec4 a_position;\n" +
|
"attribute vec4 a_position;\n" +
|
||||||
"attribute vec4 a_color;\n" +
|
"attribute vec4 a_color;\n" +
|
||||||
"attribute vec2 a_texCoord0;\n" +
|
"attribute vec2 a_texCoord0;\n" +
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ public class MinimapRenderer implements Disposable{
|
|||||||
float dy = (Core.camera.position.y / tilesize);
|
float dy = (Core.camera.position.y / tilesize);
|
||||||
dx = Mathf.clamp(dx, sz, world.width() - sz);
|
dx = Mathf.clamp(dx, sz, world.width() - sz);
|
||||||
dy = Mathf.clamp(dy, sz, world.height() - sz);
|
dy = Mathf.clamp(dy, sz, world.height() - sz);
|
||||||
float invTexWidth = 1f / texture.getWidth();
|
float invTexWidth = 1f / texture.width;
|
||||||
float invTexHeight = 1f / texture.height;
|
float invTexHeight = 1f / texture.height;
|
||||||
float x = dx - sz, y = world.height() - dy - sz, width = sz * 2, height = sz * 2;
|
float x = dx - sz, y = world.height() - dy - sz, width = sz * 2, height = sz * 2;
|
||||||
region.set(x * invTexWidth, y * invTexHeight, (x + width) * invTexWidth, (y + height) * invTexHeight);
|
region.set(x * invTexWidth, y * invTexHeight, (x + width) * invTexWidth, (y + height) * invTexHeight);
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ public class Pal{
|
|||||||
darkishGray = new Color(0.3f, 0.3f, 0.3f, 1f),
|
darkishGray = new Color(0.3f, 0.3f, 0.3f, 1f),
|
||||||
darkerGray = new Color(0.2f, 0.2f, 0.2f, 1f),
|
darkerGray = new Color(0.2f, 0.2f, 0.2f, 1f),
|
||||||
darkestGray = new Color(0.1f, 0.1f, 0.1f, 1f),
|
darkestGray = new Color(0.1f, 0.1f, 0.1f, 1f),
|
||||||
|
shadow = new Color(0, 0, 0, 0.22f),
|
||||||
ammo = Color.valueOf("ff8947"),
|
ammo = Color.valueOf("ff8947"),
|
||||||
rubble = Color.valueOf("1c1817"),
|
rubble = Color.valueOf("1c1817"),
|
||||||
|
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ public class Shaders{
|
|||||||
setUniformf("u_progress", progress);
|
setUniformf("u_progress", progress);
|
||||||
setUniformf("u_uv", region.u, region.v);
|
setUniformf("u_uv", region.u, region.v);
|
||||||
setUniformf("u_uv2", region.u2, region.v2);
|
setUniformf("u_uv2", region.u2, region.v2);
|
||||||
setUniformf("u_texsize", region.texture.getWidth(), region.texture.height);
|
setUniformf("u_texsize", region.texture.width, region.texture.height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,7 +175,7 @@ public class Shaders{
|
|||||||
setUniformf("u_uv", region.u, region.v);
|
setUniformf("u_uv", region.u, region.v);
|
||||||
setUniformf("u_uv2", region.u2, region.v2);
|
setUniformf("u_uv2", region.u2, region.v2);
|
||||||
setUniformf("u_time", Time.time());
|
setUniformf("u_time", Time.time());
|
||||||
setUniformf("u_texsize", region.texture.getWidth(), region.texture.height);
|
setUniformf("u_texsize", region.texture.width, region.texture.height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,10 @@ import arc.graphics.*;
|
|||||||
import arc.graphics.VertexAttributes.*;
|
import arc.graphics.VertexAttributes.*;
|
||||||
import arc.graphics.gl.*;
|
import arc.graphics.gl.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.util.*;
|
|
||||||
import mindustry.graphics.g3d.PlanetGrid.*;
|
import mindustry.graphics.g3d.PlanetGrid.*;
|
||||||
|
|
||||||
public class MeshBuilder{
|
public class MeshBuilder{
|
||||||
private static final Vec3 v1 = new Vec3(), v2 = new Vec3(), v3 = new Vec3();
|
private static final Vec3 v1 = new Vec3(), v2 = new Vec3(), v3 = new Vec3(), v4 = new Vec3();
|
||||||
private static final float[] floats = new float[3 + 3 + 1];
|
private static final float[] floats = new float[3 + 3 + 1];
|
||||||
private static Mesh mesh;
|
private static Mesh mesh;
|
||||||
|
|
||||||
@@ -111,7 +110,7 @@ public class MeshBuilder{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Vec3 normal(Vec3 v1, Vec3 v2, Vec3 v3){
|
private static Vec3 normal(Vec3 v1, Vec3 v2, Vec3 v3){
|
||||||
return Tmp.v32.set(v2).sub(v1).crs(v3.x - v1.x, v3.y - v1.y, v3.z - v1.z).nor();
|
return v4.set(v2).sub(v1).crs(v3.x - v1.x, v3.y - v1.y, v3.z - v1.z).nor();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void verts(Vec3 a, Vec3 b, Vec3 c, Vec3 normal, Color color){
|
private static void verts(Vec3 a, Vec3 b, Vec3 c, Vec3 normal, Color color){
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
Payloadc pay = (Payloadc)unit;
|
Payloadc pay = (Payloadc)unit;
|
||||||
|
|
||||||
if(target.isAI() && target.isGrounded() && pay.canPickup(target)
|
if(target.isAI() && target.isGrounded() && pay.canPickup(target)
|
||||||
&& target.within(unit, unit.type().hitsize * 2f + target.type().hitsize * 2f)){
|
&& target.within(unit, unit.type().hitSize * 2f + target.type().hitSize * 2f)){
|
||||||
Call.pickedUnitPayload(player, target);
|
Call.pickedUnitPayload(player, target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -395,7 +395,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
if(!(unit instanceof Payloadc)) return;
|
if(!(unit instanceof Payloadc)) return;
|
||||||
Payloadc pay = (Payloadc)unit;
|
Payloadc pay = (Payloadc)unit;
|
||||||
|
|
||||||
Unit target = Units.closest(player.team(), pay.x(), pay.y(), unit.type().hitsize * 2.5f, u -> u.isAI() && u.isGrounded() && pay.canPickup(u) && u.within(unit, u.hitSize + unit.hitSize * 1.2f));
|
Unit target = Units.closest(player.team(), pay.x(), pay.y(), unit.type().hitSize * 2.5f, u -> u.isAI() && u.isGrounded() && pay.canPickup(u) && u.within(unit, u.hitSize + unit.hitSize * 1.2f));
|
||||||
if(target != null){
|
if(target != null){
|
||||||
Call.requestUnitPayload(player, target);
|
Call.requestUnitPayload(player, target);
|
||||||
}else{
|
}else{
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ public enum ConditionOp{
|
|||||||
lessThan("<", (a, b) -> a < b),
|
lessThan("<", (a, b) -> a < b),
|
||||||
lessThanEq("<=", (a, b) -> a <= b),
|
lessThanEq("<=", (a, b) -> a <= b),
|
||||||
greaterThan(">", (a, b) -> a > b),
|
greaterThan(">", (a, b) -> a > b),
|
||||||
greaterThanEq(">=", (a, b) -> a >= b);
|
greaterThanEq(">=", (a, b) -> a >= b),
|
||||||
|
always("always", (a, b) -> true);
|
||||||
|
|
||||||
public static final ConditionOp[] all = values();
|
public static final ConditionOp[] all = values();
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package mindustry.logic;
|
package mindustry.logic;
|
||||||
|
|
||||||
import arc.func.*;
|
import arc.func.*;
|
||||||
|
import arc.graphics.*;
|
||||||
import arc.scene.style.*;
|
import arc.scene.style.*;
|
||||||
import arc.scene.ui.*;
|
import arc.scene.ui.*;
|
||||||
import arc.scene.ui.layout.*;
|
import arc.scene.ui.layout.*;
|
||||||
@@ -633,6 +634,8 @@ public class LStatements{
|
|||||||
|
|
||||||
@RegisterStatement("jump")
|
@RegisterStatement("jump")
|
||||||
public static class JumpStatement extends LStatement{
|
public static class JumpStatement extends LStatement{
|
||||||
|
private static Color last = new Color();
|
||||||
|
|
||||||
public transient StatementElem dest;
|
public transient StatementElem dest;
|
||||||
|
|
||||||
public int destIndex;
|
public int destIndex;
|
||||||
@@ -644,19 +647,30 @@ public class LStatements{
|
|||||||
public void build(Table table){
|
public void build(Table table){
|
||||||
table.add("if ").padLeft(4);
|
table.add("if ").padLeft(4);
|
||||||
|
|
||||||
field(table, value, str -> value = str);
|
last = table.color;
|
||||||
|
table.table(this::rebuild);
|
||||||
table.button(b -> {
|
|
||||||
b.label(() -> op.symbol);
|
|
||||||
b.clicked(() -> showSelect(b, ConditionOp.all, op, o -> op = o));
|
|
||||||
}, Styles.logict, () -> {}).size(48f, 40f).pad(4f).color(table.color);
|
|
||||||
|
|
||||||
field(table, compare, str -> compare = str);
|
|
||||||
|
|
||||||
table.add().growX();
|
table.add().growX();
|
||||||
table.add(new JumpButton(() -> dest, s -> dest = s)).size(30).right().padLeft(-8);
|
table.add(new JumpButton(() -> dest, s -> dest = s)).size(30).right().padLeft(-8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rebuild(Table table){
|
||||||
|
table.clearChildren();
|
||||||
|
table.setColor(last);
|
||||||
|
|
||||||
|
if(op != ConditionOp.always) field(table, value, str -> value = str);
|
||||||
|
|
||||||
|
table.button(b -> {
|
||||||
|
b.label(() -> op.symbol);
|
||||||
|
b.clicked(() -> showSelect(b, ConditionOp.all, op, o -> {
|
||||||
|
op = o;
|
||||||
|
rebuild(table);
|
||||||
|
}));
|
||||||
|
}, Styles.logict, () -> {}).size(op == ConditionOp.always ? 80f : 48f, 40f).pad(4f).color(table.color);
|
||||||
|
|
||||||
|
if(op != ConditionOp.always) field(table, compare, str -> compare = str);
|
||||||
|
}
|
||||||
|
|
||||||
//elements need separate conversion logic
|
//elements need separate conversion logic
|
||||||
@Override
|
@Override
|
||||||
public void setupUI(){
|
public void setupUI(){
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import mindustry.gen.*;
|
|||||||
public enum RadarSort{
|
public enum RadarSort{
|
||||||
distance((pos, other) -> -pos.dst2(other)),
|
distance((pos, other) -> -pos.dst2(other)),
|
||||||
health((pos, other) -> other.health()),
|
health((pos, other) -> other.health()),
|
||||||
|
shield((pos, other) -> other.shield()),
|
||||||
|
armor((pos, other) -> other.armor()),
|
||||||
maxHealth((pos, other) -> other.maxHealth());
|
maxHealth((pos, other) -> other.maxHealth());
|
||||||
|
|
||||||
public final RadarSortFunc func;
|
public final RadarSortFunc func;
|
||||||
@@ -17,6 +19,6 @@ public enum RadarSort{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public interface RadarSortFunc{
|
public interface RadarSortFunc{
|
||||||
float get(Position pos, Healthc other);
|
float get(Position pos, Unit other);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ public enum RadarTarget{
|
|||||||
enemy((team, other) -> team != other.team),
|
enemy((team, other) -> team != other.team),
|
||||||
ally((team, other) -> team == other.team),
|
ally((team, other) -> team == other.team),
|
||||||
player((team, other) -> other.isPlayer()),
|
player((team, other) -> other.isPlayer()),
|
||||||
|
attacker((pos, other) -> other.canShoot()),
|
||||||
flying((team, other) -> other.isFlying()),
|
flying((team, other) -> other.isFlying()),
|
||||||
|
boss((team, other) -> other.isBoss()),
|
||||||
ground((team, other) -> other.isGrounded());
|
ground((team, other) -> other.isGrounded());
|
||||||
|
|
||||||
public final RadarTargetFunc func;
|
public final RadarTargetFunc func;
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import mindustry.type.*;
|
|||||||
import mindustry.ui.*;
|
import mindustry.ui.*;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.*;
|
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
@@ -634,12 +633,11 @@ public class Mods implements Loadable{
|
|||||||
//make sure the main class exists before loading it; if it doesn't just don't put it there
|
//make sure the main class exists before loading it; if it doesn't just don't put it there
|
||||||
if(mainFile.exists()){
|
if(mainFile.exists()){
|
||||||
//mobile versions don't support class mods
|
//mobile versions don't support class mods
|
||||||
if(mobile){
|
if(ios){
|
||||||
throw new IllegalArgumentException("Java class mods are not supported on mobile.");
|
throw new IllegalArgumentException("Java class mods are not supported on iOS.");
|
||||||
}
|
}
|
||||||
|
|
||||||
URLClassLoader classLoader = new URLClassLoader(new URL[]{sourceFile.file().toURI().toURL()}, ClassLoader.getSystemClassLoader());
|
Class<?> main = platform.loadJar(sourceFile, mainClass);
|
||||||
Class<?> main = classLoader.loadClass(mainClass);
|
|
||||||
metas.put(main, meta);
|
metas.put(main, meta);
|
||||||
mainMod = (Mod)main.getDeclaredConstructor().newInstance();
|
mainMod = (Mod)main.getDeclaredConstructor().newInstance();
|
||||||
}else{
|
}else{
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ public class Administration{
|
|||||||
public Seq<ChatFilter> chatFilters = new Seq<>();
|
public Seq<ChatFilter> chatFilters = new Seq<>();
|
||||||
public Seq<ActionFilter> actionFilters = new Seq<>();
|
public Seq<ActionFilter> actionFilters = new Seq<>();
|
||||||
public Seq<String> subnetBans = new Seq<>();
|
public Seq<String> subnetBans = new Seq<>();
|
||||||
|
public ObjectMap<String, Long> kickedIPs = new ObjectMap<>();
|
||||||
|
|
||||||
/** All player info. Maps UUIDs to info. This persists throughout restarts. Do not access directly. */
|
/** All player info. Maps UUIDs to info. This persists throughout restarts. Do not access directly. */
|
||||||
private ObjectMap<String, PlayerInfo> playerInfo = new ObjectMap<>();
|
private ObjectMap<String, PlayerInfo> playerInfo = new ObjectMap<>();
|
||||||
@@ -86,6 +87,20 @@ public class Administration{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return time at which a player would be pardoned for a kick (0 means they were never kicked) */
|
||||||
|
public long getKickTime(String uuid, String ip){
|
||||||
|
return Math.max(getInfo(uuid).lastKicked, kickedIPs.get(ip, 0L));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets up kick duration for a player. */
|
||||||
|
public void handleKicked(String uuid, String ip, long duration){
|
||||||
|
kickedIPs.put(ip, Math.max(kickedIPs.get(ip, 0L), Time.millis() + duration));
|
||||||
|
|
||||||
|
PlayerInfo info = getInfo(uuid);
|
||||||
|
info.timesKicked++;
|
||||||
|
info.lastKicked = Math.max(Time.millis() + duration, info.lastKicked);
|
||||||
|
}
|
||||||
|
|
||||||
public Seq<String> getSubnetBans(){
|
public Seq<String> getSubnetBans(){
|
||||||
return subnetBans;
|
return subnetBans;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,13 +27,13 @@ public class CrashSender{
|
|||||||
public static String createReport(String error){
|
public static String createReport(String error){
|
||||||
String report = "Oh no, Mindustry crashed!\n";
|
String report = "Oh no, Mindustry crashed!\n";
|
||||||
if(mods.list().size == 0){
|
if(mods.list().size == 0){
|
||||||
report += "Please report this at https://github.com/Anuken/Mindustry/issues/new?labels=bug&template=bug_report.md\n\n";
|
report += "Please report this at " + Vars.reportIssueURL + "\n\n";
|
||||||
}
|
}
|
||||||
return report + "Version: " + Version.combined() + (Vars.headless ? " (Server)" : "") + "\n"
|
return report + "Version: " + Version.combined() + (Vars.headless ? " (Server)" : "") + "\n"
|
||||||
+ "OS: " + System.getProperty("os.name") + " x" + (OS.is64Bit ? "64" : "32") + "\n"
|
+ "OS: " + System.getProperty("os.name") + " x" + (OS.is64Bit ? "64" : "32") + "\n"
|
||||||
+ "Java Version: " + System.getProperty("java.version") + "\n"
|
+ "Java Version: " + System.getProperty("java.version") + "\n"
|
||||||
+ "Java Architecture: " + System.getProperty("sun.arch.data.model") + "\n"
|
+ "Java Architecture: " + System.getProperty("sun.arch.data.model") + "\n"
|
||||||
+ mods.list().size + " Mods: " + mods.list().toString(", ", mod -> mod.name + ":" + mod.meta.version)
|
+ mods.list().size + " Mods: " + (mods.list().isEmpty() ? "none" : mods.list().toString(", ", mod -> mod.name + ":" + mod.meta.version))
|
||||||
+ "\n\n" + error;
|
+ "\n\n" + error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,9 +65,7 @@ public abstract class NetConnection{
|
|||||||
|
|
||||||
Log.info("Kicking connection @; Reason: @", address, reason.replace("\n", " "));
|
Log.info("Kicking connection @; Reason: @", address, reason.replace("\n", " "));
|
||||||
|
|
||||||
PlayerInfo info = netServer.admins.getInfo(uuid);
|
netServer.admins.handleKicked(uuid, address, kickDuration);
|
||||||
info.timesKicked++;
|
|
||||||
info.lastKicked = Math.max(Time.millis() + kickDuration, info.lastKicked);
|
|
||||||
|
|
||||||
Call.kick(this, reason);
|
Call.kick(this, reason);
|
||||||
|
|
||||||
|
|||||||
28
core/src/mindustry/type/AmmoType.java
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package mindustry.type;
|
||||||
|
|
||||||
|
import arc.graphics.*;
|
||||||
|
import mindustry.ctype.*;
|
||||||
|
import mindustry.gen.*;
|
||||||
|
import mindustry.graphics.*;
|
||||||
|
|
||||||
|
/** Type of ammo that a unit uses. */
|
||||||
|
public class AmmoType extends Content{
|
||||||
|
public String icon = Iconc.itemCopper + "";
|
||||||
|
public Color color = Pal.ammo;
|
||||||
|
public Color barColor = Pal.ammo;
|
||||||
|
|
||||||
|
public AmmoType(char icon, Color color){
|
||||||
|
this.icon = icon + "";
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AmmoType(){
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resupply(Unit unit){}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ContentType getContentType(){
|
||||||
|
return ContentType.ammo;
|
||||||
|
}
|
||||||
|
}
|
||||||
86
core/src/mindustry/type/AmmoTypes.java
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
package mindustry.type;
|
||||||
|
|
||||||
|
import arc.util.ArcAnnotate.*;
|
||||||
|
import mindustry.*;
|
||||||
|
import mindustry.content.*;
|
||||||
|
import mindustry.ctype.*;
|
||||||
|
import mindustry.gen.*;
|
||||||
|
import mindustry.graphics.*;
|
||||||
|
import mindustry.world.*;
|
||||||
|
import mindustry.world.meta.*;
|
||||||
|
|
||||||
|
public class AmmoTypes implements ContentList{
|
||||||
|
public static AmmoType
|
||||||
|
powerLow,
|
||||||
|
power,
|
||||||
|
powerHigh,
|
||||||
|
copper,
|
||||||
|
thorium;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void load(){
|
||||||
|
powerLow = new PowerAmmoType(500);
|
||||||
|
power = new PowerAmmoType(1000);
|
||||||
|
powerHigh = new PowerAmmoType(2000);
|
||||||
|
copper = new ItemAmmoType(Items.copper);
|
||||||
|
thorium = new ItemAmmoType(Items.thorium);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PowerAmmoType extends AmmoType{
|
||||||
|
public float totalPower = 1000;
|
||||||
|
|
||||||
|
public PowerAmmoType(){
|
||||||
|
super(Iconc.power, Pal.powerLight);
|
||||||
|
barColor = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PowerAmmoType(float totalPower){
|
||||||
|
this();
|
||||||
|
this.totalPower = totalPower;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resupply(Unit unit){
|
||||||
|
float range = unit.hitSize + 60f;
|
||||||
|
Tile closest = Vars.indexer.findClosestFlag(unit.x, unit.y, unit.team, BlockFlag.powerResupply);
|
||||||
|
|
||||||
|
if(closest != null && closest.build != null && unit.within(closest.build, range) && closest.build.power != null){
|
||||||
|
Building build = closest.build;
|
||||||
|
|
||||||
|
if(build.block.consumes.hasPower() && build.block.consumes.getPower().buffered){
|
||||||
|
float amount = closest.build.power.status * build.block.consumes.getPower().capacity;
|
||||||
|
float powerPerAmmo = totalPower / unit.type().ammoCapacity;
|
||||||
|
float ammoRequired = unit.type().ammoCapacity - unit.ammo;
|
||||||
|
float powerRequired = ammoRequired * powerPerAmmo;
|
||||||
|
float powerTaken = Math.min(amount, powerRequired);
|
||||||
|
|
||||||
|
if(powerTaken > 1){
|
||||||
|
closest.build.power.status -= powerTaken / build.block.consumes.getPower().capacity;
|
||||||
|
unit.ammo += powerTaken / powerPerAmmo;
|
||||||
|
|
||||||
|
Fx.itemTransfer.at(build.x, build.y, Math.max(powerTaken / 100f, 1f), Pal.power, unit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ItemAmmoType extends AmmoType{
|
||||||
|
public @NonNull Item item;
|
||||||
|
|
||||||
|
public ItemAmmoType(Item item){
|
||||||
|
this.item = item;
|
||||||
|
this.color = item.color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemAmmoType(){
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void load(){
|
||||||
|
if(item != null){
|
||||||
|
icon = item.emoji();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,9 +31,6 @@ public class Sector{
|
|||||||
public float baseCoverage;
|
public float baseCoverage;
|
||||||
public boolean generateEnemyBase;
|
public boolean generateEnemyBase;
|
||||||
|
|
||||||
//TODO implement a dynamic launch period
|
|
||||||
public int launchPeriod = 10;
|
|
||||||
|
|
||||||
public Sector(Planet planet, Ptile tile){
|
public Sector(Planet planet, Ptile tile){
|
||||||
this.planet = planet;
|
this.planet = planet;
|
||||||
this.tile = tile;
|
this.tile = tile;
|
||||||
@@ -100,7 +97,7 @@ public class Sector{
|
|||||||
|
|
||||||
public boolean isBeingPlayed(){
|
public boolean isBeingPlayed(){
|
||||||
//after the launch dialog, a sector is no longer considered being played
|
//after the launch dialog, a sector is no longer considered being played
|
||||||
return Vars.state.isGame() && Vars.state.rules.sector == this && !Vars.state.launched && !Vars.state.gameOver;
|
return Vars.state.isGame() && Vars.state.rules.sector == this && !Vars.state.gameOver;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCaptured(){
|
public boolean isCaptured(){
|
||||||
@@ -134,16 +131,6 @@ public class Sector{
|
|||||||
return res % 2 == 0 ? res : res + 1;
|
return res % 2 == 0 ? res : res + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO implement
|
|
||||||
public boolean isLaunchWave(int wave){
|
|
||||||
return metCondition() && wave % launchPeriod == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean metCondition(){
|
|
||||||
//TODO implement
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO this should be stored in a more efficient structure, and be updated each turn
|
//TODO this should be stored in a more efficient structure, and be updated each turn
|
||||||
public ItemSeq getExtraItems(){
|
public ItemSeq getExtraItems(){
|
||||||
return Core.settings.getJson(key("extra-items"), ItemSeq.class, ItemSeq::new);
|
return Core.settings.getJson(key("extra-items"), ItemSeq.class, ItemSeq::new);
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ public class StatusEffect extends MappableContent{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(effect != Fx.none && Mathf.chanceDelta(effectChance)){
|
if(effect != Fx.none && Mathf.chanceDelta(effectChance)){
|
||||||
Tmp.v1.rnd(unit.type().hitsize/2f);
|
Tmp.v1.rnd(unit.type().hitSize /2f);
|
||||||
effect.at(unit.x + Tmp.v1.x, unit.y + Tmp.v1.y);
|
effect.at(unit.x + Tmp.v1.x, unit.y + Tmp.v1.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import mindustry.world.consumers.*;
|
|||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public class UnitType extends UnlockableContent{
|
public class UnitType extends UnlockableContent{
|
||||||
public static final float shadowTX = -12, shadowTY = -13, shadowColor = Color.toFloatBits(0, 0, 0, 0.22f), outlineSpace = 0.01f;
|
public static final float shadowTX = -12, shadowTY = -13, outlineSpace = 0.01f;
|
||||||
private static final Vec2 legOffset = new Vec2();
|
private static final Vec2 legOffset = new Vec2();
|
||||||
|
|
||||||
/** If true, the unit is always at elevation 1. */
|
/** If true, the unit is always at elevation 1. */
|
||||||
@@ -51,6 +51,7 @@ public class UnitType extends UnlockableContent{
|
|||||||
public boolean destructibleWreck = true;
|
public boolean destructibleWreck = true;
|
||||||
public float groundLayer = Layer.groundUnit;
|
public float groundLayer = Layer.groundUnit;
|
||||||
public float payloadCapacity = 8;
|
public float payloadCapacity = 8;
|
||||||
|
public float aimDst = -1f;
|
||||||
public int commandLimit = 24;
|
public int commandLimit = 24;
|
||||||
public float visualElevation = -1f;
|
public float visualElevation = -1f;
|
||||||
public boolean allowLegStep = false;
|
public boolean allowLegStep = false;
|
||||||
@@ -72,7 +73,8 @@ public class UnitType extends UnlockableContent{
|
|||||||
public Color mechLegColor = Pal.darkMetal;
|
public Color mechLegColor = Pal.darkMetal;
|
||||||
|
|
||||||
public int itemCapacity = -1;
|
public int itemCapacity = -1;
|
||||||
public int ammoCapacity = 220;
|
public int ammoCapacity = -1;
|
||||||
|
public AmmoType ammoType = AmmoTypes.copper;
|
||||||
public int mineTier = -1;
|
public int mineTier = -1;
|
||||||
public float buildSpeed = 1f, mineSpeed = 1f;
|
public float buildSpeed = 1f, mineSpeed = 1f;
|
||||||
|
|
||||||
@@ -80,7 +82,7 @@ public class UnitType extends UnlockableContent{
|
|||||||
public boolean canDrown = true;
|
public boolean canDrown = true;
|
||||||
public float engineOffset = 5f, engineSize = 2.5f;
|
public float engineOffset = 5f, engineSize = 2.5f;
|
||||||
public float strafePenalty = 0.5f;
|
public float strafePenalty = 0.5f;
|
||||||
public float hitsize = 6f;
|
public float hitSize = 6f;
|
||||||
public float itemOffsetY = 3f;
|
public float itemOffsetY = 3f;
|
||||||
public float lightRadius = 60f, lightOpacity = 0.6f;
|
public float lightRadius = 60f, lightOpacity = 0.6f;
|
||||||
public Color lightColor = Pal.powerLight;
|
public Color lightColor = Pal.powerLight;
|
||||||
@@ -136,41 +138,6 @@ public class UnitType extends UnlockableContent{
|
|||||||
|
|
||||||
public void update(Unit unit){
|
public void update(Unit unit){
|
||||||
|
|
||||||
if(unit instanceof Mechc && !unit.isFlying()){
|
|
||||||
updateMechEffects(unit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateMechEffects(Unit unit){
|
|
||||||
Mechc mech = (Mechc)unit;
|
|
||||||
|
|
||||||
float extend = walkExtend((Mechc)unit, false);
|
|
||||||
float base = walkExtend((Mechc)unit, true);
|
|
||||||
float extendScl = base % 1f;
|
|
||||||
|
|
||||||
float lastExtend = mech.walkExtension();
|
|
||||||
|
|
||||||
if(extendScl < lastExtend && base % 2f > 1f){
|
|
||||||
int side = -Mathf.sign(extend);
|
|
||||||
float width = hitsize / 2f * side, length = mechStride * 1.35f;
|
|
||||||
|
|
||||||
float cx = unit.x + Angles.trnsx(mech.baseRotation(), length, width),
|
|
||||||
cy = unit.y + Angles.trnsy(mech.baseRotation(), length, width);
|
|
||||||
|
|
||||||
if(mechStepShake > 0){
|
|
||||||
Effect.shake(mechStepShake, mechStepShake, cx, cy);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(mechStepParticles){
|
|
||||||
Tile tile = world.tileWorld(cx, cy);
|
|
||||||
if(tile != null){
|
|
||||||
Color color = tile.floor().mapColor;
|
|
||||||
Fx.unitLand.at(cx, cy, hitsize/8f, color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mech.walkExtension(extendScl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void landed(Unit unit){}
|
public void landed(Unit unit){}
|
||||||
@@ -184,13 +151,13 @@ public class UnitType extends UnlockableContent{
|
|||||||
table.row();
|
table.row();
|
||||||
|
|
||||||
table.table(bars -> {
|
table.table(bars -> {
|
||||||
bars.defaults().growX().height(18f).pad(4);
|
bars.defaults().growX().height(20f).pad(4);
|
||||||
|
|
||||||
bars.add(new Bar("blocks.health", Pal.health, unit::healthf).blink(Color.white));
|
bars.add(new Bar("blocks.health", Pal.health, unit::healthf).blink(Color.white));
|
||||||
bars.row();
|
bars.row();
|
||||||
|
|
||||||
if(state.rules.unitAmmo){
|
if(state.rules.unitAmmo){
|
||||||
bars.add(new Bar("blocks.ammo", Pal.ammo, () -> unit.ammo / ammoCapacity));
|
bars.add(new Bar(ammoType.icon + " " + Core.bundle.get("blocks.ammo"), ammoType.barColor, () -> unit.ammo / ammoCapacity));
|
||||||
bars.row();
|
bars.row();
|
||||||
}
|
}
|
||||||
}).growX();
|
}).growX();
|
||||||
@@ -237,24 +204,28 @@ public class UnitType extends UnlockableContent{
|
|||||||
singleTarget = weapons.size <= 1;
|
singleTarget = weapons.size <= 1;
|
||||||
|
|
||||||
if(itemCapacity < 0){
|
if(itemCapacity < 0){
|
||||||
itemCapacity = Math.max(Mathf.round(hitsize * 7, 20), 20);
|
itemCapacity = Math.max(Mathf.round(hitSize * 7, 20), 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
//set up default range
|
//set up default range
|
||||||
if(range < 0){
|
if(range < 0){
|
||||||
range = Float.MAX_VALUE;
|
range = Float.MAX_VALUE;
|
||||||
for(Weapon weapon : weapons){
|
for(Weapon weapon : weapons){
|
||||||
range = Math.min(range, weapon.bullet.range() + hitsize/2f);
|
range = Math.min(range, weapon.bullet.range() + hitSize /2f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mechStride < 0){
|
if(mechStride < 0){
|
||||||
mechStride = 4f + (hitsize-8f)/2.1f;
|
mechStride = 4f + (hitSize -8f)/2.1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(aimDst < 0){
|
||||||
|
aimDst = weapons.contains(w -> !w.rotate) ? hitSize * 2f : hitSize / 2f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mechStepShake < 0){
|
if(mechStepShake < 0){
|
||||||
mechStepShake = Mathf.round((hitsize - 11f) / 9f);
|
mechStepShake = Mathf.round((hitSize - 11f) / 9f);
|
||||||
mechStepParticles = hitsize > 15f;
|
mechStepParticles = hitSize > 15f;
|
||||||
}
|
}
|
||||||
|
|
||||||
canHeal = weapons.contains(w -> w.bullet instanceof HealBulletType);
|
canHeal = weapons.contains(w -> w.bullet instanceof HealBulletType);
|
||||||
@@ -281,6 +252,15 @@ public class UnitType extends UnlockableContent{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.weapons = mapped;
|
this.weapons = mapped;
|
||||||
|
|
||||||
|
//dynamically create ammo capacity based on firing rate
|
||||||
|
if(ammoCapacity < 0){
|
||||||
|
float shotsPerSecond = weapons.sumf(w -> 60f / w.reload);
|
||||||
|
//duration of continuous fire without reload
|
||||||
|
float targetSeconds = 30;
|
||||||
|
|
||||||
|
ammoCapacity = Math.max(1, (int)(shotsPerSecond * targetSeconds));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@CallSuper
|
@CallSuper
|
||||||
@@ -342,7 +322,7 @@ public class UnitType extends UnlockableContent{
|
|||||||
|
|
||||||
public void draw(Unit unit){
|
public void draw(Unit unit){
|
||||||
Mechc mech = unit instanceof Mechc ? (Mechc)unit : null;
|
Mechc mech = unit instanceof Mechc ? (Mechc)unit : null;
|
||||||
float z = unit.elevation > 0.5f ? (lowAltitude ? Layer.flyingUnitLow : Layer.flyingUnit) : groundLayer + Mathf.clamp(hitsize/4000f, 0, 0.01f);
|
float z = unit.elevation > 0.5f ? (lowAltitude ? Layer.flyingUnitLow : Layer.flyingUnit) : groundLayer + Mathf.clamp(hitSize / 4000f, 0, 0.01f);
|
||||||
|
|
||||||
if(unit.controller().isBeingControlled(player.unit())){
|
if(unit.controller().isBeingControlled(player.unit())){
|
||||||
drawControl(unit);
|
drawControl(unit);
|
||||||
@@ -359,10 +339,10 @@ public class UnitType extends UnlockableContent{
|
|||||||
drawMech(mech);
|
drawMech(mech);
|
||||||
|
|
||||||
//side
|
//side
|
||||||
legOffset.trns(mech.baseRotation(), 0f, Mathf.lerp(Mathf.sin(walkExtend(mech, true), 2f/Mathf.PI, 1) * mechSideSway, 0f, unit.elevation));
|
legOffset.trns(mech.baseRotation(), 0f, Mathf.lerp(Mathf.sin(mech.walkExtend(true), 2f/Mathf.PI, 1) * mechSideSway, 0f, unit.elevation));
|
||||||
|
|
||||||
//front
|
//front
|
||||||
legOffset.add(Tmp.v1.trns(mech.baseRotation() + 90, 0f, Mathf.lerp(Mathf.sin(walkExtend(mech, true), 1f/Mathf.PI, 1) * mechFrontSway, 0f, unit.elevation)));
|
legOffset.add(Tmp.v1.trns(mech.baseRotation() + 90, 0f, Mathf.lerp(Mathf.sin(mech.walkExtend(true), 1f/Mathf.PI, 1) * mechFrontSway, 0f, unit.elevation)));
|
||||||
|
|
||||||
unit.trns(legOffset.x, legOffset.y);
|
unit.trns(legOffset.x, legOffset.y);
|
||||||
}
|
}
|
||||||
@@ -434,7 +414,7 @@ public class UnitType extends UnlockableContent{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void drawShadow(Unit unit){
|
public void drawShadow(Unit unit){
|
||||||
Draw.color(shadowColor);
|
Draw.color(Pal.shadow);
|
||||||
float e = Math.max(unit.elevation, visualElevation);
|
float e = Math.max(unit.elevation, visualElevation);
|
||||||
Draw.rect(shadowRegion, unit.x + shadowTX * e, unit.y + shadowTY * e, unit.rotation - 90);
|
Draw.rect(shadowRegion, unit.x + shadowTX * e, unit.y + shadowTY * e, unit.rotation - 90);
|
||||||
Draw.color();
|
Draw.color();
|
||||||
@@ -619,7 +599,7 @@ public class UnitType extends UnlockableContent{
|
|||||||
if(leg.moving && visualElevation > 0){
|
if(leg.moving && visualElevation > 0){
|
||||||
float scl = visualElevation;
|
float scl = visualElevation;
|
||||||
float elev = Mathf.slope(1f - leg.stage) * scl;
|
float elev = Mathf.slope(1f - leg.stage) * scl;
|
||||||
Draw.color(shadowColor);
|
Draw.color(Pal.shadow);
|
||||||
Draw.rect(footRegion, leg.base.x + shadowTX * elev, leg.base.y + shadowTY * elev, position.angleTo(leg.base));
|
Draw.rect(footRegion, leg.base.x + shadowTX * elev, leg.base.y + shadowTY * elev, position.angleTo(leg.base));
|
||||||
Draw.color();
|
Draw.color();
|
||||||
}
|
}
|
||||||
@@ -656,8 +636,8 @@ public class UnitType extends UnlockableContent{
|
|||||||
|
|
||||||
float e = unit.elevation;
|
float e = unit.elevation;
|
||||||
|
|
||||||
float sin = Mathf.lerp(Mathf.sin(walkExtend(mech, true), 2f / Mathf.PI, 1f), 0f, e);
|
float sin = Mathf.lerp(Mathf.sin(mech.walkExtend(true), 2f / Mathf.PI, 1f), 0f, e);
|
||||||
float extension = Mathf.lerp(walkExtend(mech, false), 0, e);
|
float extension = Mathf.lerp(mech.walkExtend(false), 0, e);
|
||||||
float boostTrns = e * 2f;
|
float boostTrns = e * 2f;
|
||||||
|
|
||||||
Floor floor = unit.isFlying() ? Blocks.air.asFloor() : unit.floorOn();
|
Floor floor = unit.isFlying() ? Blocks.air.asFloor() : unit.floorOn();
|
||||||
@@ -690,20 +670,6 @@ public class UnitType extends UnlockableContent{
|
|||||||
Draw.mixcol();
|
Draw.mixcol();
|
||||||
}
|
}
|
||||||
|
|
||||||
public float walkExtend(Mechc mech, boolean scaled){
|
|
||||||
|
|
||||||
//now ranges from -maxExtension to maxExtension*3
|
|
||||||
float raw = mech.walkTime() % (mechStride * 4);
|
|
||||||
|
|
||||||
if(scaled) return raw / mechStride;
|
|
||||||
|
|
||||||
if(raw > mechStride*3) raw = raw - mechStride * 4;
|
|
||||||
else if(raw > mechStride*2) raw = mechStride * 2 - raw;
|
|
||||||
else if(raw > mechStride) raw = mechStride * 2 - raw;
|
|
||||||
|
|
||||||
return raw;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void applyColor(Unit unit){
|
public void applyColor(Unit unit){
|
||||||
Draw.color();
|
Draw.color();
|
||||||
Draw.mixcol(Color.white, unit.hitTime);
|
Draw.mixcol(Color.white, unit.hitTime);
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ import static mindustry.Vars.*;
|
|||||||
|
|
||||||
public abstract class Weather extends UnlockableContent{
|
public abstract class Weather extends UnlockableContent{
|
||||||
/** Default duration of this weather event in ticks. */
|
/** Default duration of this weather event in ticks. */
|
||||||
public float duration = 9f * Time.toMinutes;
|
public float duration = 8f * Time.toMinutes;
|
||||||
|
public float opacityMultiplier = 1f;
|
||||||
public Attributes attrs = new Attributes();
|
public Attributes attrs = new Attributes();
|
||||||
|
|
||||||
//internals
|
//internals
|
||||||
@@ -122,7 +123,7 @@ public abstract class Weather extends UnlockableContent{
|
|||||||
|
|
||||||
/** Creates a weather entry with some approximate weather values. */
|
/** Creates a weather entry with some approximate weather values. */
|
||||||
public WeatherEntry(Weather weather){
|
public WeatherEntry(Weather weather){
|
||||||
this(weather, weather.duration * 1f, weather.duration * 3f, weather.duration / 2f, weather.duration * 1.5f);
|
this(weather, weather.duration * 3f, weather.duration * 6f, weather.duration / 2f, weather.duration * 1.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public WeatherEntry(Weather weather, float minFrequency, float maxFrequency, float minDuration, float maxDuration){
|
public WeatherEntry(Weather weather, float minFrequency, float maxFrequency, float minDuration, float maxDuration){
|
||||||
@@ -177,14 +178,14 @@ public abstract class Weather extends UnlockableContent{
|
|||||||
if(renderer.weatherAlpha() > 0.0001f){
|
if(renderer.weatherAlpha() > 0.0001f){
|
||||||
Draw.draw(Layer.weather, () -> {
|
Draw.draw(Layer.weather, () -> {
|
||||||
weather.rand.setSeed(0);
|
weather.rand.setSeed(0);
|
||||||
Draw.alpha(renderer.weatherAlpha() * opacity);
|
Draw.alpha(renderer.weatherAlpha() * opacity * weather.opacityMultiplier);
|
||||||
weather.drawOver(self());
|
weather.drawOver(self());
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
});
|
});
|
||||||
|
|
||||||
Draw.draw(Layer.debris, () -> {
|
Draw.draw(Layer.debris, () -> {
|
||||||
weather.rand.setSeed(0);
|
weather.rand.setSeed(0);
|
||||||
Draw.alpha(renderer.weatherAlpha() * opacity);
|
Draw.alpha(renderer.weatherAlpha() * opacity * weather.opacityMultiplier);
|
||||||
weather.drawUnder(self());
|
weather.drawUnder(self());
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public class Bar extends Element{
|
|||||||
|
|
||||||
public Bar(String name, Color color, Floatp fraction){
|
public Bar(String name, Color color, Floatp fraction){
|
||||||
this.fraction = fraction;
|
this.fraction = fraction;
|
||||||
this.name = Core.bundle.get(name);
|
this.name = Core.bundle.get(name, name);
|
||||||
this.blinkColor.set(color);
|
this.blinkColor.set(color);
|
||||||
lastValue = value = fraction.get();
|
lastValue = value = fraction.get();
|
||||||
setColor(color);
|
setColor(color);
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ public class ContentDisplay{
|
|||||||
|
|
||||||
public static void displayUnit(Table table, UnitType unit){
|
public static void displayUnit(Table table, UnitType unit){
|
||||||
table.table(title -> {
|
table.table(title -> {
|
||||||
title.image(unit.icon(Cicon.xlarge));
|
title.image(unit.icon(Cicon.xlarge)).size(8 * 6).scaling(Scaling.fit);
|
||||||
title.add("[accent]" + unit.localizedName).padLeft(5);
|
title.add("[accent]" + unit.localizedName).padLeft(5);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ public class GameOverDialog extends BaseDialog{
|
|||||||
}
|
}
|
||||||
|
|
||||||
void rebuild(){
|
void rebuild(){
|
||||||
title.setText(state.launched ? "@launch.title" : "@gameover");
|
title.setText("@gameover");
|
||||||
buttons.clear();
|
buttons.clear();
|
||||||
cont.clear();
|
cont.clear();
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ public class GameOverDialog extends BaseDialog{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(state.hasSector()){
|
if(state.hasSector()){
|
||||||
RankResult result = state.stats.calculateRank(state.getSector(), state.launched);
|
RankResult result = state.stats.calculateRank(state.getSector(), true);
|
||||||
t.add(Core.bundle.format("stat.rank", result.rank + result.modifier));
|
t.add(Core.bundle.format("stat.rank", result.rank + result.modifier));
|
||||||
t.row();
|
t.row();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ public class JoinDialog extends BaseDialog{
|
|||||||
Table global = new Table();
|
Table global = new Table();
|
||||||
Table hosts = new Table();
|
Table hosts = new Table();
|
||||||
int totalHosts;
|
int totalHosts;
|
||||||
|
int refreshes;
|
||||||
|
|
||||||
public JoinDialog(){
|
public JoinDialog(){
|
||||||
super("@joingame");
|
super("@joingame");
|
||||||
@@ -95,6 +96,8 @@ public class JoinDialog extends BaseDialog{
|
|||||||
}
|
}
|
||||||
|
|
||||||
void refreshAll(){
|
void refreshAll(){
|
||||||
|
refreshes ++;
|
||||||
|
|
||||||
refreshLocal();
|
refreshLocal();
|
||||||
refreshRemote();
|
refreshRemote();
|
||||||
refreshGlobal();
|
refreshGlobal();
|
||||||
@@ -327,12 +330,15 @@ public class JoinDialog extends BaseDialog{
|
|||||||
}
|
}
|
||||||
|
|
||||||
void refreshGlobal(){
|
void refreshGlobal(){
|
||||||
|
int cur = refreshes;
|
||||||
|
|
||||||
global.clear();
|
global.clear();
|
||||||
global.background(null);
|
global.background(null);
|
||||||
for(String host : defaultServers){
|
for(String host : defaultServers){
|
||||||
String resaddress = host.contains(":") ? host.split(":")[0] : host;
|
String resaddress = host.contains(":") ? host.split(":")[0] : host;
|
||||||
int resport = host.contains(":") ? Strings.parseInt(host.split(":")[1]) : port;
|
int resport = host.contains(":") ? Strings.parseInt(host.split(":")[1]) : port;
|
||||||
net.pingHost(resaddress, resport, res -> {
|
net.pingHost(resaddress, resport, res -> {
|
||||||
|
if(refreshes != cur) return;
|
||||||
res.port = resport;
|
res.port = resport;
|
||||||
addGlobalHost(res);
|
addGlobalHost(res);
|
||||||
}, e -> {});
|
}, e -> {});
|
||||||
|
|||||||
@@ -163,6 +163,19 @@ public class ResearchDialog extends BaseDialog{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dialog show(){
|
||||||
|
Core.app.post(() -> {
|
||||||
|
if(net.client()){
|
||||||
|
//TODO make this not display every time
|
||||||
|
//TODO rework this in the future
|
||||||
|
ui.showInfo("@campaign.multiplayer");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return super.show();
|
||||||
|
}
|
||||||
|
|
||||||
void treeLayout(){
|
void treeLayout(){
|
||||||
float spacing = 20f;
|
float spacing = 20f;
|
||||||
LayoutNode node = new LayoutNode(root, null);
|
LayoutNode node = new LayoutNode(root, null);
|
||||||
|
|||||||