1
0
mirror of https://github.com/Anuken/Mindustry.git synced 2024-11-13 07:15:28 +03:00

it never ends

This commit is contained in:
Anuken 2020-02-05 13:03:22 -05:00
parent a7b39e56bd
commit da97aee8e4
111 changed files with 1327 additions and 1644 deletions

View File

@ -6,7 +6,7 @@ public class Annotations{
//region entity interfaces
/** Indicates that a component field is read-only. */
@Target(ElementType.FIELD)
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.SOURCE)
public @interface ReadOnly{
}

View File

@ -10,6 +10,7 @@ import mindustry.annotations.util.*;
import javax.annotation.processing.*;
import javax.lang.model.*;
import javax.lang.model.element.*;
import javax.lang.model.type.*;
import javax.lang.model.util.*;
import javax.tools.Diagnostic.*;
import javax.tools.*;
@ -42,6 +43,22 @@ public abstract class BaseProcessor extends AbstractProcessor{
|| type.equals("long") || type.equals("float") || type.equals("double") || type.equals("char");
}
public static String simpleName(String str){
return str.contains(".") ? str.substring(str.lastIndexOf('.') + 1) : str;
}
public static TypeVariableName getTVN(TypeParameterElement element) {
String name = element.getSimpleName().toString();
List<? extends TypeMirror> boundsMirrors = element.getBounds();
List<TypeName> boundsTypeNames = new ArrayList<>();
for (TypeMirror typeMirror : boundsMirrors) {
boundsTypeNames.add(TypeName.get(typeMirror));
}
return TypeVariableName.get(name, boundsTypeNames.toArray(new TypeName[0]));
}
public static void write(TypeSpec.Builder builder) throws Exception{
write(builder, null);
}
@ -87,12 +104,12 @@ public abstract class BaseProcessor extends AbstractProcessor{
.map(e -> new Smethod((ExecutableElement)e));
}
public void err(String message){
public static void err(String message){
messager.printMessage(Kind.ERROR, message);
Log.err("[CODEGEN ERROR] " +message);
}
public void err(String message, Element elem){
public static void err(String message, Element elem){
messager.printMessage(Kind.ERROR, message, elem);
Log.err("[CODEGEN ERROR] " + message + ": " + elem);
}

View File

@ -11,7 +11,6 @@ import mindustry.annotations.*;
import javax.annotation.processing.*;
import javax.lang.model.*;
import javax.lang.model.element.*;
import javax.tools.Diagnostic.*;
import java.util.*;
@SupportedAnnotationTypes("mindustry.annotations.Annotations.StyleDefaults")
@ -98,7 +97,7 @@ public class AssetsProcess extends BaseProcessor{
String name = p.nameWithoutExtension();
if(names.contains(name)){
BaseProcessor.messager.printMessage(Kind.ERROR, "Duplicate file name: " + p.toString() + "!");
BaseProcessor.err("Duplicate file name: " + p.toString() + "!");
}else{
names.add(name);
}

View File

@ -63,7 +63,6 @@ public class EntityProcess extends BaseProcessor{
//create component interfaces
for(Stype component : allComponents){
Log.info("&yGenerating interface for " + component);
TypeSpec.Builder inter = TypeSpec.interfaceBuilder(interfaceName(component)).addModifiers(Modifier.PUBLIC).addAnnotation(EntityInterface.class);
//implement extra interfaces these components may have, e.g. position
@ -77,22 +76,16 @@ public class EntityProcess extends BaseProcessor{
inter.addSuperinterface(ClassName.get(packageName, interfaceName(type)));
}
for(Svar field : component.fields().select(e -> !e.is(Modifier.STATIC) && !e.is(Modifier.PRIVATE) && !e.is(Modifier.TRANSIENT))){
String cname = field.name();
//getter
inter.addMethod(MethodSpec.methodBuilder(cname).addModifiers(Modifier.ABSTRACT, Modifier.PUBLIC).returns(field.tname()).build());
//setter
if(!field.is(Modifier.FINAL) && !field.annotations().contains(f -> f.toString().equals("@mindustry.annotations.Annotations.ReadOnly"))){
inter.addMethod(MethodSpec.methodBuilder(cname).addModifiers(Modifier.ABSTRACT, Modifier.PUBLIC).addParameter(field.tname(), field.name()).build());
}
}
ObjectSet<String> signatures = new ObjectSet<>();
//add utility methods to interface
for(Smethod method : component.methods()){
//skip private methods, those are for internal use.
if(method.is(Modifier.PRIVATE)) continue;
//keep track of signatures used to prevent dupes
signatures.add(method.e.toString());
inter.addMethod(MethodSpec.methodBuilder(method.name())
.addExceptions(method.thrownt())
.addTypeVariables(method.typeVariables().map(TypeVariableName::get))
@ -101,7 +94,42 @@ public class EntityProcess extends BaseProcessor{
.build())).addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT).build());
}
for(Svar field : component.fields().select(e -> !e.is(Modifier.STATIC) && !e.is(Modifier.PRIVATE) && !e.is(Modifier.TRANSIENT))){
String cname = field.name();
//getter
if(!signatures.contains(cname + "()")){
inter.addMethod(MethodSpec.methodBuilder(cname).addModifiers(Modifier.ABSTRACT, Modifier.PUBLIC)
.addAnnotations(Array.with(field.annotations()).select(a -> a.toString().contains("Null")).map(AnnotationSpec::get))
.returns(field.tname()).build());
}
//setter
if(!field.is(Modifier.FINAL) && !signatures.contains(cname + "(" + field.mirror().toString() + ")") &&
!field.annotations().contains(f -> f.toString().equals("@mindustry.annotations.Annotations.ReadOnly"))){
inter.addMethod(MethodSpec.methodBuilder(cname).addModifiers(Modifier.ABSTRACT, Modifier.PUBLIC)
.addParameter(ParameterSpec.builder(field.tname(), field.name())
.addAnnotations(Array.with(field.annotations())
.select(a -> a.toString().contains("Null")).map(AnnotationSpec::get)).build()).build());
}
}
write(inter);
//LOGGING
Log.info("&gGenerating interface for " + component.name());
for(TypeName tn : inter.superinterfaces){
Log.info("&g> &lbextends {0}", simpleName(tn.toString()));
}
//log methods generated
for(MethodSpec spec : inter.methodSpecs){
Log.info("&g> > &c{0} {1}({2})", simpleName(spec.returnType.toString()), spec.name, Array.with(spec.parameters).toString(", ", p -> simpleName(p.type.toString()) + " " + p.name));
}
Log.info("");
}
//look at each definition
@ -134,7 +162,7 @@ public class EntityProcess extends BaseProcessor{
fbuilder.initializer(tree.getInitializer().toString());
}
builder.addAnnotations(f.annotations().map(AnnotationSpec::get));
fbuilder.addAnnotations(f.annotations().map(AnnotationSpec::get));
builder.addField(fbuilder.build());
}
@ -150,6 +178,12 @@ public class EntityProcess extends BaseProcessor{
//representative method
Smethod first = entry.value.first();
//skip internal impl
if(first.has(InternalImpl.class)){
continue;
}
//build method using same params/returns
MethodSpec.Builder mbuilder = MethodSpec.methodBuilder(first.name()).addModifiers(first.is(Modifier.PRIVATE) ? Modifier.PRIVATE : Modifier.PUBLIC, Modifier.FINAL);
mbuilder.addTypeVariables(first.typeVariables().map(TypeVariableName::get));
@ -232,6 +266,18 @@ public class EntityProcess extends BaseProcessor{
//write the groups
groupsBuilder.addMethod(groupInit.build());
MethodSpec.Builder groupResize = MethodSpec.methodBuilder("resize")
.addParameter(TypeName.FLOAT, "x").addParameter(TypeName.FLOAT, "y").addParameter(TypeName.FLOAT, "w").addParameter(TypeName.FLOAT, "h")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC);
for(GroupDefinition group : groupDefs){
if(group.def.spatial()){
groupResize.addStatement("$L.resize(x, y, w, h)", group.name);
}
}
groupsBuilder.addMethod(groupResize.build());
write(groupsBuilder);
//load map of sync IDs
@ -302,16 +348,16 @@ public class EntityProcess extends BaseProcessor{
String var = method.name();
FieldSpec field = Array.with(def.builder.fieldSpecs).find(f -> f.name.equals(var));
//make sure it's a real variable AND that the component doesn't already implement it with custom logic
if(field == null || comp.methods().contains(m -> m.name().equals(method.name()))) continue;
if(field == null || comp.methods().contains(m -> m.simpleString().equals(method.simpleString()))) continue;
//getter
if(!method.isVoid()){
def.builder.addMethod(MethodSpec.overriding(method.e).addStatement("return " + var).build());
def.builder.addMethod(MethodSpec.overriding(method.e).addStatement("return " + var).addModifiers(Modifier.FINAL).build());
}
//setter
if(method.isVoid() && !Array.with(field.annotations).contains(f -> f.type.toString().equals("@mindustry.annotations.Annotations.ReadOnly"))){
def.builder.addMethod(MethodSpec.overriding(method.e).addStatement("this." + var + " = " + var).build());
def.builder.addMethod(MethodSpec.overriding(method.e).addModifiers(Modifier.FINAL).addStatement("this." + var + " = " + var).build());
}
}
}

View File

@ -29,7 +29,7 @@ public class StructProcess extends BaseProcessor{
for(TypeElement elem : elements){
if(!elem.getSimpleName().toString().endsWith("Struct")){
BaseProcessor.messager.printMessage(Kind.ERROR, "All classes annotated with @Struct must have their class names end in 'Struct'.", elem);
BaseProcessor.err("All classes annotated with @Struct must have their class names end in 'Struct'.", elem);
continue;
}
@ -45,7 +45,7 @@ public class StructProcess extends BaseProcessor{
int structTotalSize = (structSize <= 8 ? 8 : structSize <= 16 ? 16 : structSize <= 32 ? 32 : 64);
if(variables.size() == 0){
BaseProcessor.messager.printMessage(Kind.ERROR, "making a struct with no fields is utterly pointles.", elem);
BaseProcessor.err("making a struct with no fields is utterly pointles.", elem);
continue;
}
@ -133,7 +133,7 @@ public class StructProcess extends BaseProcessor{
JavaFile.builder(packageName, classBuilder.build()).build().writeTo(BaseProcessor.filer);
}catch(IllegalArgumentException e){
e.printStackTrace();
BaseProcessor.messager.printMessage(Kind.ERROR, e.getMessage(), elem);
BaseProcessor.err(e.getMessage(), elem);
}
}

View File

@ -1,15 +1,12 @@
package mindustry.annotations.remote;
import mindustry.annotations.Annotations.*;
import mindustry.annotations.*;
import mindustry.annotations.Annotations.ReadClass;
import mindustry.annotations.Annotations.WriteClass;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.type.MirroredTypeException;
import javax.tools.Diagnostic.Kind;
import java.util.HashMap;
import java.util.Set;
import javax.annotation.processing.*;
import javax.lang.model.element.*;
import javax.lang.model.type.*;
import java.util.*;
/**
* This class finds reader and writer methods annotated by the {@link WriteClass}
@ -35,15 +32,15 @@ public class IOFinder{
//make sure there's only one read method
if(readers.stream().filter(elem -> getValue(elem.getAnnotation(ReadClass.class)).equals(typeName)).count() > 1){
BaseProcessor.messager.printMessage(Kind.ERROR, "Multiple writer methods for type '" + typeName + "'", writer);
BaseProcessor.err("Multiple writer methods for type '" + typeName + "'", writer);
}
//make sure there's only one write method
long count = readers.stream().filter(elem -> getValue(elem.getAnnotation(ReadClass.class)).equals(typeName)).count();
if(count == 0){
BaseProcessor.messager.printMessage(Kind.ERROR, "Writer method does not have an accompanying reader: ", writer);
BaseProcessor.err("Writer method does not have an accompanying reader: ", writer);
}else if(count > 1){
BaseProcessor.messager.printMessage(Kind.ERROR, "Writer method has multiple reader for type: ", writer);
BaseProcessor.err("Writer method has multiple reader for type: ", writer);
}
Element reader = readers.stream().filter(elem -> getValue(elem.getAnnotation(ReadClass.class)).equals(typeName)).findFirst().get();

View File

@ -2,16 +2,13 @@ package mindustry.annotations.remote;
import com.squareup.javapoet.*;
import mindustry.annotations.*;
import mindustry.annotations.remote.IOFinder.ClassSerializer;
import mindustry.annotations.remote.IOFinder.*;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.*;
import javax.tools.Diagnostic.Kind;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.List;
import java.lang.reflect.*;
import java.nio.*;
import java.util.*;
/** Generates code for reading remote invoke packets on the client and server. */
public class RemoteReadGenerator{
@ -29,8 +26,7 @@ public class RemoteReadGenerator{
* @param packageName Full target package name.
* @param needsPlayer Whether this read method requires a reference to the player sender.
*/
public void generateFor(List<MethodEntry> entries, String className, String packageName, boolean needsPlayer)
throws IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException, IOException{
public void generateFor(List<MethodEntry> entries, String className, String packageName, boolean needsPlayer) throws Exception{
TypeSpec.Builder classBuilder = TypeSpec.classBuilder(className).addModifiers(Modifier.PUBLIC);
classBuilder.addJavadoc(RemoteProcess.autogenWarning);
@ -48,7 +44,7 @@ public class RemoteReadGenerator{
Constructor<TypeName> cons = TypeName.class.getDeclaredConstructor(String.class);
cons.setAccessible(true);
TypeName playerType = cons.newInstance("mindustry.entities.type.Player");
TypeName playerType = cons.newInstance("mindustry.gen.Playerc");
//add player parameter
readMethod.addParameter(playerType, "player");
}
@ -91,10 +87,10 @@ public class RemoteReadGenerator{
}
}else{
//else, try and find a serializer
ClassSerializer ser = serializers.get(typeName);
ClassSerializer ser = serializers.getOrDefault(typeName, SerializerResolver.locate(entry.element, var.asType()));
if(ser == null){ //make sure a serializer exists!
BaseProcessor.messager.printMessage(Kind.ERROR, "No @ReadClass method to read class type: '" + typeName + "'", var);
BaseProcessor.err("No @ReadClass method to read class type '" + typeName + "' in method " + entry.targetMethod, var);
return;
}
@ -119,7 +115,7 @@ public class RemoteReadGenerator{
if(entry.forward && entry.where.isServer && needsPlayer){
//call forwarded method
readBlock.addStatement(packageName + "." + entry.className + "." + entry.element.getSimpleName() +
"__forward(player.con" + (varResult.length() == 0 ? "" : ", ") + varResult.toString() + ")");
"__forward(player.con()" + (varResult.length() == 0 ? "" : ", ") + varResult.toString() + ")");
}
readBlock.nextControlFlow("catch (java.lang.Exception e)");

View File

@ -1,16 +1,15 @@
package mindustry.annotations.remote;
import arc.struct.*;
import com.squareup.javapoet.*;
import mindustry.annotations.Annotations.*;
import mindustry.annotations.*;
import mindustry.annotations.Annotations.Loc;
import mindustry.annotations.remote.IOFinder.ClassSerializer;
import mindustry.annotations.remote.IOFinder.*;
import javax.lang.model.element.*;
import javax.tools.Diagnostic.Kind;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.List;
import java.io.*;
import java.nio.*;
import java.util.*;
/** Generates code for writing remote invoke packets on the client and server. */
public class RemoteWriteGenerator{
@ -74,12 +73,12 @@ public class RemoteWriteGenerator{
//validate client methods to make sure
if(methodEntry.where.isClient){
if(elem.getParameters().isEmpty()){
BaseProcessor.messager.printMessage(Kind.ERROR, "Client invoke methods must have a first parameter of type Player.", elem);
BaseProcessor.err("Client invoke methods must have a first parameter of type Player", elem);
return;
}
if(!elem.getParameters().get(0).asType().toString().equals("mindustry.entities.type.Player")){
BaseProcessor.messager.printMessage(Kind.ERROR, "Client invoke methods should have a first parameter of type Player.", elem);
if(!elem.getParameters().get(0).asType().toString().equals("Playerc")){
BaseProcessor.err("Client invoke methods should have a first parameter of type Playerc", elem);
return;
}
}
@ -138,6 +137,8 @@ public class RemoteWriteGenerator{
//rewind buffer
method.addStatement("TEMP_BUFFER.position(0)");
method.addTypeVariables(Array.with(elem.getTypeParameters()).map(BaseProcessor::getTVN));
for(int i = 0; i < elem.getParameters().size(); i++){
//first argument is skipped as it is always the player caller
if((!methodEntry.where.isServer/* || methodEntry.mode == Loc.both*/) && i == 0){
@ -176,10 +177,10 @@ public class RemoteWriteGenerator{
}
}else{
//else, try and find a serializer
ClassSerializer ser = serializers.get(typeName);
ClassSerializer ser = serializers.getOrDefault(typeName, SerializerResolver.locate(elem, var.asType()));
if(ser == null){ //make sure a serializer exists!
BaseProcessor.messager.printMessage(Kind.ERROR, "No @WriteClass method to write class type: '" + typeName + "'", var);
BaseProcessor.err("No @WriteClass method to write class type: '" + typeName + "'", var);
return;
}

View File

@ -0,0 +1,29 @@
package mindustry.annotations.remote;
import arc.struct.*;
import mindustry.annotations.remote.IOFinder.*;
import javax.lang.model.element.*;
import javax.lang.model.type.*;
public class SerializerResolver{
private static final ClassSerializer entitySerializer = new ClassSerializer("mindustry.io.TypeIO.readEntity", "mindustry.io.TypeIO.writeEntity", "Entityc");
public static ClassSerializer locate(ExecutableElement elem, TypeMirror mirror){
//generic type
if(mirror.toString().equals("T")){
TypeParameterElement param = elem.getTypeParameters().get(0);
if(Array.with(param.getBounds()).contains(SerializerResolver::isEntity)){
return entitySerializer;
}
}
if(isEntity(mirror)){
return entitySerializer;
}
return null;
}
private static boolean isEntity(TypeMirror mirror){
return !mirror.toString().contains(".") && mirror.toString().endsWith("c");
}
}

View File

@ -49,4 +49,8 @@ public class Smethod extends Selement<ExecutableElement>{
public MethodTree tree(){
return BaseProcessor.trees.getTree(e);
}
public String simpleString(){
return name() + "(" + params().toString(", ", p -> BaseProcessor.simpleName(p.mirror().toString())) + ")";
}
}

View File

@ -1,5 +1,5 @@
#Maps entity names to IDs. Autogenerated.
#Tue Feb 04 17:41:17 EST 2020
#Wed Feb 05 12:35:36 EST 2020
mindustry.entities.def.EntityDefs.DecalDef=1
mindustry.entities.def.EntityDefs.EffectDef=2

View File

@ -1,11 +1,12 @@
package mindustry.gen;
import arc.graphics.Color;
import java.lang.String;
import java.nio.ByteBuffer;
import mindustry.entities.bullet.BulletType;
import mindustry.entities.units.BuildRequest;
import mindustry.game.Rules;
import mindustry.game.Team;
import mindustry.net.Administration;
import mindustry.net.NetConnection;
import mindustry.net.Packets;
import mindustry.type.Item;
@ -18,6 +19,46 @@ import mindustry.world.Tile;
public class Call {
private static final ByteBuffer TEMP_BUFFER = ByteBuffer.allocate(4096);
public static synchronized <T extends Posc & Itemsc> void transferItemEffect(Item item, float x,
float y, T to) {
if(mindustry.Vars.net.server() || !mindustry.Vars.net.active()) {
mindustry.input.InputHandler.transferItemEffect(item, x, y, to);
}
if(mindustry.Vars.net.server()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)0;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeItem(TEMP_BUFFER, item);
TEMP_BUFFER.putFloat(x);
TEMP_BUFFER.putFloat(y);
mindustry.io.TypeIO.writeEntity(TEMP_BUFFER, to);
packet.writeLength = TEMP_BUFFER.position();
mindustry.Vars.net.send(packet, mindustry.net.Net.SendMode.udp);
}
}
public static synchronized <T extends Posc & Itemsc> void transferItemToUnit(Item item, float x,
float y, T to) {
if(mindustry.Vars.net.server() || !mindustry.Vars.net.active()) {
mindustry.input.InputHandler.transferItemToUnit(item, x, y, to);
}
if(mindustry.Vars.net.server()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)1;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeItem(TEMP_BUFFER, item);
TEMP_BUFFER.putFloat(x);
TEMP_BUFFER.putFloat(y);
mindustry.io.TypeIO.writeEntity(TEMP_BUFFER, to);
packet.writeLength = TEMP_BUFFER.position();
mindustry.Vars.net.send(packet, mindustry.net.Net.SendMode.udp);
}
}
public static synchronized void beginBreak(Team team, int x, int y) {
if(mindustry.Vars.net.server() || !mindustry.Vars.net.active()) {
mindustry.world.Build.beginBreak(team, x, y);
@ -26,7 +67,7 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)0;
packet.type = (byte)2;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeTeam(TEMP_BUFFER, team);
TEMP_BUFFER.putInt(x);
@ -44,7 +85,7 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)1;
packet.type = (byte)3;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeTeam(TEMP_BUFFER, team);
TEMP_BUFFER.putInt(x);
@ -56,22 +97,35 @@ public class Call {
}
}
public static synchronized void connectConfirm() {
if(mindustry.Vars.net.client()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)4;
TEMP_BUFFER.position(0);
packet.writeLength = TEMP_BUFFER.position();
mindustry.Vars.net.send(packet, mindustry.net.Net.SendMode.tcp);
}
}
public static synchronized void createBullet(BulletType type, Team team, float x, float y,
float angle, float velocityScl, float lifetimeScl) {
float angle, float damage, float velocityScl, float lifetimeScl) {
if(mindustry.Vars.net.server() || !mindustry.Vars.net.active()) {
mindustry.entities.bullet.BulletType.createBullet(type, team, x, y, angle, velocityScl, lifetimeScl);
mindustry.entities.bullet.BulletType.createBullet(type, team, x, y, angle, damage, velocityScl, lifetimeScl);
}
if(mindustry.Vars.net.server()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)3;
packet.type = (byte)5;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeBulletType(TEMP_BUFFER, type);
mindustry.io.TypeIO.writeTeam(TEMP_BUFFER, team);
TEMP_BUFFER.putFloat(x);
TEMP_BUFFER.putFloat(y);
TEMP_BUFFER.putFloat(angle);
TEMP_BUFFER.putFloat(damage);
TEMP_BUFFER.putFloat(velocityScl);
TEMP_BUFFER.putFloat(lifetimeScl);
packet.writeLength = TEMP_BUFFER.position();
@ -79,27 +133,19 @@ public class Call {
}
}
public static synchronized void createLighting(int seed, Team team, Color color, float damage,
float x, float y, float rotation, int length) {
public static synchronized void dropItem(float angle) {
if(mindustry.Vars.net.server() || !mindustry.Vars.net.active()) {
mindustry.entities.effect.Lightning.createLighting(seed, team, color, damage, x, y, rotation, length);
mindustry.input.InputHandler.dropItem(mindustry.Vars.player, angle);
}
if(mindustry.Vars.net.server()) {
if(mindustry.Vars.net.client()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)4;
packet.type = (byte)6;
TEMP_BUFFER.position(0);
TEMP_BUFFER.putInt(seed);
mindustry.io.TypeIO.writeTeam(TEMP_BUFFER, team);
mindustry.io.TypeIO.writeColor(TEMP_BUFFER, color);
TEMP_BUFFER.putFloat(damage);
TEMP_BUFFER.putFloat(x);
TEMP_BUFFER.putFloat(y);
TEMP_BUFFER.putFloat(rotation);
TEMP_BUFFER.putInt(length);
TEMP_BUFFER.putFloat(angle);
packet.writeLength = TEMP_BUFFER.position();
mindustry.Vars.net.send(packet, mindustry.net.Net.SendMode.udp);
mindustry.Vars.net.send(packet, mindustry.net.Net.SendMode.tcp);
}
}
@ -109,19 +155,36 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)6;
packet.type = (byte)7;
TEMP_BUFFER.position(0);
packet.writeLength = TEMP_BUFFER.position();
mindustry.Vars.net.send(packet, mindustry.net.Net.SendMode.tcp);
}
}
public static synchronized void onAdminRequest(Playerc other, Packets.AdminAction action) {
if(mindustry.Vars.net.server() || !mindustry.Vars.net.active()) {
mindustry.core.NetServer.onAdminRequest(mindustry.Vars.player, other, action);
}
if(mindustry.Vars.net.client()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)8;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeEntity(TEMP_BUFFER, other);
mindustry.io.TypeIO.writeAction(TEMP_BUFFER, action);
packet.writeLength = TEMP_BUFFER.position();
mindustry.Vars.net.send(packet, mindustry.net.Net.SendMode.tcp);
}
}
public static synchronized void onBlockSnapshot(short amount, short dataLen, byte[] data) {
if(mindustry.Vars.net.server()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)2;
packet.type = (byte)8;
packet.type = (byte)9;
TEMP_BUFFER.position(0);
TEMP_BUFFER.putShort(amount);
TEMP_BUFFER.putShort(dataLen);
@ -137,7 +200,7 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)2;
packet.type = (byte)8;
packet.type = (byte)9;
TEMP_BUFFER.position(0);
TEMP_BUFFER.putShort(amount);
TEMP_BUFFER.putShort(dataLen);
@ -147,6 +210,40 @@ public class Call {
}
}
public static synchronized void onClientShapshot(int snapshotID, float x, float y, float pointerX,
float pointerY, float rotation, float baseRotation, float xVelocity, float yVelocity,
Tile mining, boolean boosting, boolean shooting, boolean chatting, boolean building,
BuildRequest[] requests, float viewX, float viewY, float viewWidth, float viewHeight) {
if(mindustry.Vars.net.client()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)10;
TEMP_BUFFER.position(0);
TEMP_BUFFER.putInt(snapshotID);
TEMP_BUFFER.putFloat(x);
TEMP_BUFFER.putFloat(y);
TEMP_BUFFER.putFloat(pointerX);
TEMP_BUFFER.putFloat(pointerY);
TEMP_BUFFER.putFloat(rotation);
TEMP_BUFFER.putFloat(baseRotation);
TEMP_BUFFER.putFloat(xVelocity);
TEMP_BUFFER.putFloat(yVelocity);
mindustry.io.TypeIO.writeTile(TEMP_BUFFER, mining);
TEMP_BUFFER.put(boosting ? (byte)1 : 0);
TEMP_BUFFER.put(shooting ? (byte)1 : 0);
TEMP_BUFFER.put(chatting ? (byte)1 : 0);
TEMP_BUFFER.put(building ? (byte)1 : 0);
mindustry.io.TypeIO.writeRequests(TEMP_BUFFER, requests);
TEMP_BUFFER.putFloat(viewX);
TEMP_BUFFER.putFloat(viewY);
TEMP_BUFFER.putFloat(viewWidth);
TEMP_BUFFER.putFloat(viewHeight);
packet.writeLength = TEMP_BUFFER.position();
mindustry.Vars.net.send(packet, mindustry.net.Net.SendMode.udp);
}
}
public static synchronized void onConnect(NetConnection playerConnection, String ip, int port) {
if(mindustry.Vars.net.client() || !mindustry.Vars.net.active()) {
mindustry.core.NetClient.onConnect(ip, port);
@ -155,7 +252,7 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)10;
packet.type = (byte)11;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeString(TEMP_BUFFER, ip);
TEMP_BUFFER.putInt(port);
@ -173,7 +270,7 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)11;
packet.type = (byte)12;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeTile(TEMP_BUFFER, tile);
mindustry.io.TypeIO.writeBlock(TEMP_BUFFER, block);
@ -194,7 +291,7 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)12;
packet.type = (byte)13;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeTile(TEMP_BUFFER, tile);
mindustry.io.TypeIO.writeBlock(TEMP_BUFFER, block);
@ -204,13 +301,31 @@ public class Call {
}
}
public static synchronized void onDoorToggle(Playerc player, Tile tile, boolean open) {
if(mindustry.Vars.net.server() || !mindustry.Vars.net.active()) {
mindustry.world.blocks.defense.Door.onDoorToggle(player, tile, open);
}
if(mindustry.Vars.net.server()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)14;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeEntity(TEMP_BUFFER, player);
mindustry.io.TypeIO.writeTile(TEMP_BUFFER, tile);
TEMP_BUFFER.put(open ? (byte)1 : 0);
packet.writeLength = TEMP_BUFFER.position();
mindustry.Vars.net.send(packet, mindustry.net.Net.SendMode.tcp);
}
}
public static synchronized void onEntitySnapshot(NetConnection playerConnection, short amount,
short dataLen, byte[] data) {
if(mindustry.Vars.net.server()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)2;
packet.type = (byte)14;
packet.type = (byte)15;
TEMP_BUFFER.position(0);
TEMP_BUFFER.putShort(amount);
TEMP_BUFFER.putShort(dataLen);
@ -226,7 +341,7 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)15;
packet.type = (byte)16;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeTeam(TEMP_BUFFER, winner);
packet.writeLength = TEMP_BUFFER.position();
@ -239,7 +354,7 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)16;
packet.type = (byte)17;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeString(TEMP_BUFFER, message);
packet.writeLength = TEMP_BUFFER.position();
@ -252,7 +367,7 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)16;
packet.type = (byte)17;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeString(TEMP_BUFFER, message);
packet.writeLength = TEMP_BUFFER.position();
@ -266,7 +381,7 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)17;
packet.type = (byte)18;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeString(TEMP_BUFFER, message);
TEMP_BUFFER.putFloat(duration);
@ -286,7 +401,7 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)17;
packet.type = (byte)18;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeString(TEMP_BUFFER, message);
TEMP_BUFFER.putFloat(duration);
@ -305,7 +420,7 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)18;
packet.type = (byte)19;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeString(TEMP_BUFFER, message);
TEMP_BUFFER.putFloat(duration);
@ -320,7 +435,7 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)18;
packet.type = (byte)19;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeString(TEMP_BUFFER, message);
TEMP_BUFFER.putFloat(duration);
@ -334,7 +449,7 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)1;
packet.type = (byte)19;
packet.type = (byte)20;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeString(TEMP_BUFFER, reason);
packet.writeLength = TEMP_BUFFER.position();
@ -348,7 +463,7 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)1;
packet.type = (byte)20;
packet.type = (byte)21;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeKick(TEMP_BUFFER, reason);
packet.writeLength = TEMP_BUFFER.position();
@ -361,7 +476,7 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)21;
packet.type = (byte)22;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeString(TEMP_BUFFER, info);
TEMP_BUFFER.putFloat(duration);
@ -378,7 +493,7 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)21;
packet.type = (byte)22;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeString(TEMP_BUFFER, info);
TEMP_BUFFER.putFloat(duration);
@ -397,7 +512,7 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)22;
packet.type = (byte)23;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeTile(TEMP_BUFFER, tile);
packet.writeLength = TEMP_BUFFER.position();
@ -405,12 +520,44 @@ public class Call {
}
}
public static synchronized void onMechFactoryTap(Playerc player, Tile tile) {
if(mindustry.Vars.net.server() || !mindustry.Vars.net.active()) {
mindustry.world.blocks.units.MechPad.onMechFactoryTap(player, tile);
}
if(mindustry.Vars.net.server() || mindustry.Vars.net.client()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)24;
TEMP_BUFFER.position(0);
if(mindustry.Vars.net.server()) {
mindustry.io.TypeIO.writeEntity(TEMP_BUFFER, player);
}
mindustry.io.TypeIO.writeTile(TEMP_BUFFER, tile);
packet.writeLength = TEMP_BUFFER.position();
mindustry.Vars.net.send(packet, mindustry.net.Net.SendMode.tcp);
}
}
public static synchronized void onPing(long time) {
if(mindustry.Vars.net.client()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)25;
TEMP_BUFFER.position(0);
TEMP_BUFFER.putLong(time);
packet.writeLength = TEMP_BUFFER.position();
mindustry.Vars.net.send(packet, mindustry.net.Net.SendMode.tcp);
}
}
public static synchronized void onPingResponse(NetConnection playerConnection, long time) {
if(mindustry.Vars.net.server()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)25;
packet.type = (byte)26;
TEMP_BUFFER.position(0);
TEMP_BUFFER.putLong(time);
packet.writeLength = TEMP_BUFFER.position();
@ -423,7 +570,7 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)26;
packet.type = (byte)27;
TEMP_BUFFER.position(0);
TEMP_BUFFER.putInt(playerid);
packet.writeLength = TEMP_BUFFER.position();
@ -436,7 +583,7 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)27;
packet.type = (byte)28;
TEMP_BUFFER.position(0);
TEMP_BUFFER.putFloat(x);
TEMP_BUFFER.putFloat(y);
@ -445,41 +592,12 @@ public class Call {
}
}
public static synchronized void onPuddleRemoved(int puddleid) {
if(mindustry.Vars.net.server() || !mindustry.Vars.net.active()) {
mindustry.entities.effect.Puddle.onPuddleRemoved(puddleid);
}
if(mindustry.Vars.net.server()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)28;
TEMP_BUFFER.position(0);
TEMP_BUFFER.putInt(puddleid);
packet.writeLength = TEMP_BUFFER.position();
mindustry.Vars.net.send(packet, mindustry.net.Net.SendMode.tcp);
}
}
public static synchronized void onRemoveFire(int fid) {
if(mindustry.Vars.net.server()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)29;
TEMP_BUFFER.position(0);
TEMP_BUFFER.putInt(fid);
packet.writeLength = TEMP_BUFFER.position();
mindustry.Vars.net.send(packet, mindustry.net.Net.SendMode.tcp);
}
}
public static synchronized void onSetRules(Rules rules) {
if(mindustry.Vars.net.server()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)30;
packet.type = (byte)29;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeRules(TEMP_BUFFER, rules);
packet.writeLength = TEMP_BUFFER.position();
@ -492,7 +610,7 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)30;
packet.type = (byte)29;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeRules(TEMP_BUFFER, rules);
packet.writeLength = TEMP_BUFFER.position();
@ -506,7 +624,7 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)2;
packet.type = (byte)31;
packet.type = (byte)30;
TEMP_BUFFER.position(0);
TEMP_BUFFER.putFloat(waveTime);
TEMP_BUFFER.putInt(wave);
@ -518,6 +636,42 @@ public class Call {
}
}
public static synchronized void onTileConfig(Playerc player, Tile tile, int value) {
mindustry.input.InputHandler.onTileConfig(player, tile, value);
if(mindustry.Vars.net.server() || mindustry.Vars.net.client()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)31;
TEMP_BUFFER.position(0);
if(mindustry.Vars.net.server()) {
mindustry.io.TypeIO.writeEntity(TEMP_BUFFER, player);
}
mindustry.io.TypeIO.writeTile(TEMP_BUFFER, tile);
TEMP_BUFFER.putInt(value);
packet.writeLength = TEMP_BUFFER.position();
mindustry.Vars.net.send(packet, mindustry.net.Net.SendMode.tcp);
}
}
static synchronized void onTileConfig__forward(NetConnection exceptConnection, Playerc player,
Tile tile, int value) {
if(mindustry.Vars.net.server() || mindustry.Vars.net.client()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)31;
TEMP_BUFFER.position(0);
if(mindustry.Vars.net.server()) {
mindustry.io.TypeIO.writeEntity(TEMP_BUFFER, player);
}
mindustry.io.TypeIO.writeTile(TEMP_BUFFER, tile);
TEMP_BUFFER.putInt(value);
packet.writeLength = TEMP_BUFFER.position();
mindustry.Vars.net.sendExcept(exceptConnection, packet, mindustry.net.Net.SendMode.tcp);
}
}
public static synchronized void onTileDamage(Tile tile, float health) {
if(mindustry.Vars.net.server() || !mindustry.Vars.net.active()) {
mindustry.world.Tile.onTileDamage(tile, health);
@ -526,7 +680,7 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)33;
packet.type = (byte)32;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeTile(TEMP_BUFFER, tile);
TEMP_BUFFER.putFloat(health);
@ -543,7 +697,7 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)34;
packet.type = (byte)33;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeTile(TEMP_BUFFER, tile);
packet.writeLength = TEMP_BUFFER.position();
@ -551,6 +705,57 @@ public class Call {
}
}
public static synchronized void onTileTapped(Playerc player, Tile tile) {
if(mindustry.Vars.net.server() || !mindustry.Vars.net.active()) {
mindustry.input.InputHandler.onTileTapped(player, tile);
}
if(mindustry.Vars.net.server() || mindustry.Vars.net.client()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)34;
TEMP_BUFFER.position(0);
if(mindustry.Vars.net.server()) {
mindustry.io.TypeIO.writeEntity(TEMP_BUFFER, player);
}
mindustry.io.TypeIO.writeTile(TEMP_BUFFER, tile);
packet.writeLength = TEMP_BUFFER.position();
mindustry.Vars.net.send(packet, mindustry.net.Net.SendMode.tcp);
}
}
static synchronized void onTileTapped__forward(NetConnection exceptConnection, Playerc player,
Tile tile) {
if(mindustry.Vars.net.server() || mindustry.Vars.net.client()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)34;
TEMP_BUFFER.position(0);
if(mindustry.Vars.net.server()) {
mindustry.io.TypeIO.writeEntity(TEMP_BUFFER, player);
}
mindustry.io.TypeIO.writeTile(TEMP_BUFFER, tile);
packet.writeLength = TEMP_BUFFER.position();
mindustry.Vars.net.send(packet, mindustry.net.Net.SendMode.tcp);
}
}
public static synchronized void onTraceInfo(NetConnection playerConnection, Playerc player,
Administration.TraceInfo info) {
if(mindustry.Vars.net.server()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)35;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeEntity(TEMP_BUFFER, player);
mindustry.io.TypeIO.writeTraceInfo(TEMP_BUFFER, info);
packet.writeLength = TEMP_BUFFER.position();
playerConnection.send(packet, mindustry.net.Net.SendMode.tcp);
}
}
public static synchronized void onUnitFactorySpawn(Tile tile, int spawns) {
if(mindustry.Vars.net.server() || !mindustry.Vars.net.active()) {
mindustry.world.blocks.units.UnitFactory.onUnitFactorySpawn(tile, spawns);
@ -559,7 +764,7 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)37;
packet.type = (byte)36;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeTile(TEMP_BUFFER, tile);
TEMP_BUFFER.putInt(spawns);
@ -568,12 +773,29 @@ public class Call {
}
}
public static synchronized void onUnitRespawn(Tile tile, Playerc player) {
if(mindustry.Vars.net.server() || !mindustry.Vars.net.active()) {
mindustry.world.blocks.storage.CoreBlock.onUnitRespawn(tile, player);
}
if(mindustry.Vars.net.server()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)37;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeTile(TEMP_BUFFER, tile);
mindustry.io.TypeIO.writeEntity(TEMP_BUFFER, player);
packet.writeLength = TEMP_BUFFER.position();
mindustry.Vars.net.send(packet, mindustry.net.Net.SendMode.tcp);
}
}
public static synchronized void onWorldDataBegin() {
if(mindustry.Vars.net.server()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)39;
packet.type = (byte)38;
TEMP_BUFFER.position(0);
packet.writeLength = TEMP_BUFFER.position();
mindustry.Vars.net.send(packet, mindustry.net.Net.SendMode.tcp);
@ -585,7 +807,7 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)39;
packet.type = (byte)38;
TEMP_BUFFER.position(0);
packet.writeLength = TEMP_BUFFER.position();
playerConnection.send(packet, mindustry.net.Net.SendMode.tcp);
@ -598,7 +820,7 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)40;
packet.type = (byte)39;
TEMP_BUFFER.position(0);
TEMP_BUFFER.putInt(x);
TEMP_BUFFER.putInt(y);
@ -616,7 +838,7 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)41;
packet.type = (byte)40;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeTile(TEMP_BUFFER, tile);
packet.writeLength = TEMP_BUFFER.position();
@ -624,6 +846,100 @@ public class Call {
}
}
public static synchronized void requestItem(Playerc player, Tile tile, Item item, int amount) {
if(mindustry.Vars.net.server() || !mindustry.Vars.net.active()) {
mindustry.ui.fragments.BlockInventoryFragment.requestItem(player, tile, item, amount);
}
if(mindustry.Vars.net.server() || mindustry.Vars.net.client()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)41;
TEMP_BUFFER.position(0);
if(mindustry.Vars.net.server()) {
mindustry.io.TypeIO.writeEntity(TEMP_BUFFER, player);
}
mindustry.io.TypeIO.writeTile(TEMP_BUFFER, tile);
mindustry.io.TypeIO.writeItem(TEMP_BUFFER, item);
TEMP_BUFFER.putInt(amount);
packet.writeLength = TEMP_BUFFER.position();
mindustry.Vars.net.send(packet, mindustry.net.Net.SendMode.tcp);
}
}
static synchronized void requestItem__forward(NetConnection exceptConnection, Playerc player,
Tile tile, Item item, int amount) {
if(mindustry.Vars.net.server() || mindustry.Vars.net.client()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)41;
TEMP_BUFFER.position(0);
if(mindustry.Vars.net.server()) {
mindustry.io.TypeIO.writeEntity(TEMP_BUFFER, player);
}
mindustry.io.TypeIO.writeTile(TEMP_BUFFER, tile);
mindustry.io.TypeIO.writeItem(TEMP_BUFFER, item);
TEMP_BUFFER.putInt(amount);
packet.writeLength = TEMP_BUFFER.position();
mindustry.Vars.net.send(packet, mindustry.net.Net.SendMode.tcp);
}
}
public static synchronized void rotateBlock(Playerc player, Tile tile, boolean direction) {
if(mindustry.Vars.net.server() || !mindustry.Vars.net.active()) {
mindustry.input.InputHandler.rotateBlock(player, tile, direction);
}
if(mindustry.Vars.net.server() || mindustry.Vars.net.client()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)42;
TEMP_BUFFER.position(0);
if(mindustry.Vars.net.server()) {
mindustry.io.TypeIO.writeEntity(TEMP_BUFFER, player);
}
mindustry.io.TypeIO.writeTile(TEMP_BUFFER, tile);
TEMP_BUFFER.put(direction ? (byte)1 : 0);
packet.writeLength = TEMP_BUFFER.position();
mindustry.Vars.net.send(packet, mindustry.net.Net.SendMode.udp);
}
}
static synchronized void rotateBlock__forward(NetConnection exceptConnection, Playerc player,
Tile tile, boolean direction) {
if(mindustry.Vars.net.server() || mindustry.Vars.net.client()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)42;
TEMP_BUFFER.position(0);
if(mindustry.Vars.net.server()) {
mindustry.io.TypeIO.writeEntity(TEMP_BUFFER, player);
}
mindustry.io.TypeIO.writeTile(TEMP_BUFFER, tile);
TEMP_BUFFER.put(direction ? (byte)1 : 0);
packet.writeLength = TEMP_BUFFER.position();
mindustry.Vars.net.send(packet, mindustry.net.Net.SendMode.udp);
}
}
public static synchronized void sendChatMessage(String message) {
if(mindustry.Vars.net.server() || !mindustry.Vars.net.active()) {
mindustry.core.NetClient.sendChatMessage(mindustry.Vars.player, message);
}
if(mindustry.Vars.net.client()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)43;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeString(TEMP_BUFFER, message);
packet.writeLength = TEMP_BUFFER.position();
mindustry.Vars.net.send(packet, mindustry.net.Net.SendMode.tcp);
}
}
public static synchronized void sendMessage(String message) {
if(mindustry.Vars.net.server() || !mindustry.Vars.net.active()) {
mindustry.core.NetClient.sendMessage(message);
@ -632,7 +948,7 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)46;
packet.type = (byte)44;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeString(TEMP_BUFFER, message);
packet.writeLength = TEMP_BUFFER.position();
@ -640,6 +956,107 @@ public class Call {
}
}
public static synchronized void sendMessage(String message, String sender, Playerc playersender) {
if(mindustry.Vars.net.server()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)45;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeString(TEMP_BUFFER, message);
mindustry.io.TypeIO.writeString(TEMP_BUFFER, sender);
mindustry.io.TypeIO.writeEntity(TEMP_BUFFER, playersender);
packet.writeLength = TEMP_BUFFER.position();
mindustry.Vars.net.send(packet, mindustry.net.Net.SendMode.tcp);
}
}
public static synchronized void sendMessage(NetConnection playerConnection, String message,
String sender, Playerc playersender) {
if(mindustry.Vars.net.server()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)45;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeString(TEMP_BUFFER, message);
mindustry.io.TypeIO.writeString(TEMP_BUFFER, sender);
mindustry.io.TypeIO.writeEntity(TEMP_BUFFER, playersender);
packet.writeLength = TEMP_BUFFER.position();
playerConnection.send(packet, mindustry.net.Net.SendMode.tcp);
}
}
public static synchronized void setMessageBlockText(Playerc player, Tile tile, String text) {
mindustry.world.blocks.logic.MessageBlock.setMessageBlockText(player, tile, text);
if(mindustry.Vars.net.server() || mindustry.Vars.net.client()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)46;
TEMP_BUFFER.position(0);
if(mindustry.Vars.net.server()) {
mindustry.io.TypeIO.writeEntity(TEMP_BUFFER, player);
}
mindustry.io.TypeIO.writeTile(TEMP_BUFFER, tile);
mindustry.io.TypeIO.writeString(TEMP_BUFFER, text);
packet.writeLength = TEMP_BUFFER.position();
mindustry.Vars.net.send(packet, mindustry.net.Net.SendMode.tcp);
}
}
static synchronized void setMessageBlockText__forward(NetConnection exceptConnection,
Playerc player, Tile tile, String text) {
if(mindustry.Vars.net.server() || mindustry.Vars.net.client()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)46;
TEMP_BUFFER.position(0);
if(mindustry.Vars.net.server()) {
mindustry.io.TypeIO.writeEntity(TEMP_BUFFER, player);
}
mindustry.io.TypeIO.writeTile(TEMP_BUFFER, tile);
mindustry.io.TypeIO.writeString(TEMP_BUFFER, text);
packet.writeLength = TEMP_BUFFER.position();
mindustry.Vars.net.sendExcept(exceptConnection, packet, mindustry.net.Net.SendMode.tcp);
}
}
public static synchronized void setPlayerTeamEditor(Playerc player, Team team) {
mindustry.ui.fragments.HudFragment.setPlayerTeamEditor(player, team);
if(mindustry.Vars.net.server() || mindustry.Vars.net.client()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)47;
TEMP_BUFFER.position(0);
if(mindustry.Vars.net.server()) {
mindustry.io.TypeIO.writeEntity(TEMP_BUFFER, player);
}
mindustry.io.TypeIO.writeTeam(TEMP_BUFFER, team);
packet.writeLength = TEMP_BUFFER.position();
mindustry.Vars.net.send(packet, mindustry.net.Net.SendMode.tcp);
}
}
static synchronized void setPlayerTeamEditor__forward(NetConnection exceptConnection,
Playerc player, Team team) {
if(mindustry.Vars.net.server() || mindustry.Vars.net.client()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)47;
TEMP_BUFFER.position(0);
if(mindustry.Vars.net.server()) {
mindustry.io.TypeIO.writeEntity(TEMP_BUFFER, player);
}
mindustry.io.TypeIO.writeTeam(TEMP_BUFFER, team);
packet.writeLength = TEMP_BUFFER.position();
mindustry.Vars.net.sendExcept(exceptConnection, packet, mindustry.net.Net.SendMode.tcp);
}
}
public static synchronized void setTile(Tile tile, Block block, Team team, int rotation) {
if(mindustry.Vars.net.server() || !mindustry.Vars.net.active()) {
mindustry.world.Tile.setTile(tile, block, team, rotation);
@ -648,7 +1065,7 @@ public class Call {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)50;
packet.type = (byte)48;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeTile(TEMP_BUFFER, tile);
mindustry.io.TypeIO.writeBlock(TEMP_BUFFER, block);
@ -659,16 +1076,52 @@ public class Call {
}
}
public static synchronized void transferInventory(Playerc player, Tile tile) {
if(mindustry.Vars.net.server() || !mindustry.Vars.net.active()) {
mindustry.input.InputHandler.transferInventory(player, tile);
}
if(mindustry.Vars.net.server() || mindustry.Vars.net.client()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)49;
TEMP_BUFFER.position(0);
if(mindustry.Vars.net.server()) {
mindustry.io.TypeIO.writeEntity(TEMP_BUFFER, player);
}
mindustry.io.TypeIO.writeTile(TEMP_BUFFER, tile);
packet.writeLength = TEMP_BUFFER.position();
mindustry.Vars.net.send(packet, mindustry.net.Net.SendMode.tcp);
}
}
static synchronized void transferInventory__forward(NetConnection exceptConnection,
Playerc player, Tile tile) {
if(mindustry.Vars.net.server() || mindustry.Vars.net.client()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)49;
TEMP_BUFFER.position(0);
if(mindustry.Vars.net.server()) {
mindustry.io.TypeIO.writeEntity(TEMP_BUFFER, player);
}
mindustry.io.TypeIO.writeTile(TEMP_BUFFER, tile);
packet.writeLength = TEMP_BUFFER.position();
mindustry.Vars.net.send(packet, mindustry.net.Net.SendMode.tcp);
}
}
public static synchronized void transferItemTo(Item item, int amount, float x, float y,
Tile tile) {
if(mindustry.Vars.net.server() || !mindustry.Vars.net.active()) {
mindustry.entities.effect.ItemTransfer.transferItemTo(item, amount, x, y, tile);
mindustry.input.InputHandler.transferItemTo(item, amount, x, y, tile);
}
if(mindustry.Vars.net.server()) {
mindustry.net.Packets.InvokePacket packet = arc.util.pooling.Pools.obtain(mindustry.net.Packets.InvokePacket.class, mindustry.net.Packets.InvokePacket::new);
packet.writeBuffer = TEMP_BUFFER;
packet.priority = (byte)0;
packet.type = (byte)54;
packet.type = (byte)50;
TEMP_BUFFER.position(0);
mindustry.io.TypeIO.writeItem(TEMP_BUFFER, item);
TEMP_BUFFER.putInt(amount);

View File

@ -122,7 +122,7 @@ public class BlockIndexer{
for(int x = 0; x < world.width(); x++){
for(int y = 0; y < world.height(); y++){
Tile tile = world.tile(x, y);
if(tile.getTeam() == team){
if(tile.team() == team){
int quadrantX = tile.x / quadrantSize;
int quadrantY = tile.y / quadrantSize;
structQuadrant(team).set(quadrantX, quadrantY);
@ -185,7 +185,7 @@ public class BlockIndexer{
if(other == null) continue;
if(other.getTeam() == team && !intSet.contains(other.pos()) && other.entity != null && pred.get(other)){
if(other.team() == team && !intSet.contains(other.pos()) && other.entity != null && pred.get(other)){
cons.get(other);
any = true;
intSet.add(other.pos());
@ -254,7 +254,7 @@ public class BlockIndexer{
if(other == null) continue;
if(other.entity == null || other.getTeam() != team || !pred.get(other) || !other.block().targetable)
if(other.entity == null || other.team() != team || !pred.get(other) || !other.block().targetable)
continue;
Tilec e = other.entity;
@ -305,8 +305,8 @@ public class BlockIndexer{
}
private void process(Tile tile){
if(tile.block().flags.size() > 0 && tile.getTeam() != Team.derelict){
ObjectSet<Tile>[] map = getFlagged(tile.getTeam());
if(tile.block().flags.size() > 0 && tile.team() != Team.derelict){
ObjectSet<Tile>[] map = getFlagged(tile.team());
for(BlockFlag flag : tile.block().flags){
@ -316,9 +316,9 @@ public class BlockIndexer{
map[flag.ordinal()] = arr;
}
typeMap.put(tile.pos(), new TileIndex(tile.block().flags, tile.getTeam()));
typeMap.put(tile.pos(), new TileIndex(tile.block().flags, tile.team()));
}
activeTeams.add(tile.getTeam());
activeTeams.add(tile.team());
if(ores == null) return;
@ -362,7 +362,7 @@ public class BlockIndexer{
GridBits bits = structQuadrant(team);
//fast-set this quadrant to 'occupied' if the tile just placed is already of this team
if(tile.getTeam() == team && tile.entity != null && tile.block().targetable){
if(tile.team() == team && tile.entity != null && tile.block().targetable){
bits.set(quadrantX, quadrantY);
continue; //no need to process futher
}
@ -374,7 +374,7 @@ public class BlockIndexer{
for(int y = quadrantY * quadrantSize; y < world.height() && y < (quadrantY + 1) * quadrantSize; y++){
Tile result = world.ltile(x, y);
//when a targetable block is found, mark this quadrant as occupied and stop searching
if(result.entity != null && result.getTeam() == team){
if(result.entity != null && result.team() == team){
bits.set(quadrantX, quadrantY);
break outer;
}

View File

@ -7,7 +7,6 @@ import arc.util.*;
import mindustry.ctype.*;
import mindustry.entities.*;
import mindustry.entities.bullet.*;
import mindustry.entities.effect.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.world.*;

View File

@ -4,6 +4,8 @@ import arc.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.math.geom.*;
import arc.struct.*;
import arc.util.*;
import mindustry.entities.*;
import mindustry.gen.*;
@ -34,6 +36,38 @@ public class Fx{
}),
itemTransfer = new Effect(30f, e -> {
if(!(e.data instanceof Position)) return;
Position to = e.data();
Tmp.v1.set(e.x, e.y).interpolate(Tmp.v2.set(to), e.fin(), Interpolation.pow3)
.add(Tmp.v2.sub(e.x, e.y).nor().rotate90(1).scl(Mathf.randomSeedRange(e.id, 1f) * e.fslope() * 10f));
float x = Tmp.v1.x, y = Tmp.v1.y;
stroke(e.fslope() * 2f, Pal.accent);
Lines.circle(x, y, e.fslope() * 2f);
color(e.color);
Fill.circle(x, y, e.fslope() * 1.5f);
}),
lightning = new Effect(10f, 500f, e -> {
if(!(e.data instanceof Array)) return;
Array<Vec2> lines = e.data();
stroke(3f * e.fout());
color(e.color, Color.white, e.fin());
beginLine();
linePoint(e.x, e.y);
lines.each(Lines::linePoint);
endLine();
int i = 0;
for(Vec2 p : lines){
Fill.square(p.x, p.y, (5f - (float)i++ / lines.size * 2f) * e.fout(), 45);
}
}),
commandSend = new Effect(28, e -> {
color(Pal.command);
stroke(e.fout() * 2f);

View File

@ -29,12 +29,10 @@ public class ContentLoader{
private @Nullable Content lastAdded;
private ObjectSet<Cons<Content>> initialization = new ObjectSet<>();
private ContentList[] content = {
new Fx(),
new Items(),
new StatusEffects(),
new Liquids(),
new Bullets(),
new Mechs(),
new UnitTypes(),
new Blocks(),
new Loadouts(),

View File

@ -3,20 +3,19 @@ package mindustry.core;
import arc.*;
import arc.assets.*;
import arc.audio.*;
import arc.struct.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.input.*;
import arc.math.geom.*;
import arc.scene.ui.*;
import arc.struct.*;
import arc.util.*;
import mindustry.content.*;
import mindustry.core.GameState.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.gen.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.input.*;
import mindustry.maps.Map;
import mindustry.type.*;
@ -63,21 +62,19 @@ public class Control implements ApplicationListener, Loadable{
});
Events.on(PlayEvent.class, event -> {
player.team(netServer.assignTeam(player, Groups.player.all()));
player.dead(true);
player.team(netServer.assignTeam(player));
player.add();
state.set(State.playing);
});
Events.on(WorldLoadEvent.class, event -> {
Core.app.post(() -> Core.app.post(() -> {
if(net.active() && player.closestCore() != null){
//set to closest core since that's where the player will probably respawn; prevents camera jumps
Core.camera.position.set(player.dead() ? player.closestCore() : player);
}else{
//locally, set to player position since respawning occurs immediately
Core.camera.position.set(player);
//TODO test this
app.post(() -> app.post(() -> {
//TODO 0,0 seems like a bad choice?
Tilec core = state.teams.closestCore(0, 0, player.team());
if(core != null){
camera.position.set(core);
}
}));
});
@ -118,7 +115,7 @@ public class Control implements ApplicationListener, Loadable{
if(state.rules.pvp && !net.active()){
try{
net.host(port);
player.isAdmin = true;
player.admin(true);
}catch(IOException e){
ui.showException("$server.error", e);
Core.app.post(() -> state.set(State.menu));
@ -139,7 +136,7 @@ public class Control implements ApplicationListener, Loadable{
});
Events.on(BlockDestroyEvent.class, e -> {
if(e.tile.getTeam() == player.team()){
if(e.tile.team() == player.team()){
state.stats.buildingsDestroyed++;
}
});
@ -178,7 +175,7 @@ public class Control implements ApplicationListener, Loadable{
Events.on(UnitDestroyEvent.class, e -> {
if(world.isZone()){
data.unlockContent(e.unit.getType());
data.unlockContent(e.unit.type());
}
});
}
@ -204,11 +201,9 @@ public class Control implements ApplicationListener, Loadable{
}
void createPlayer(){
player = new Playerc();
player.name = Core.settings.getString("name");
player.color.set(Core.settings.getInt("color-0"));
player.isLocal() = true;
player.isMobile = mobile;
//player = new Playerc();
player.name(Core.settings.getString("name"));
player.color().set(Core.settings.getInt("color-0"));
if(mobile){
input = new MobileInput();
@ -304,14 +299,14 @@ public class Control implements ApplicationListener, Loadable{
}
}
Geometry.circle(coreb.x(), coreb.y(), 10, (cx, cy) -> {
Geometry.circle(coreb.x, coreb.y, 10, (cx, cy) -> {
Tile tile = world.ltile(cx, cy);
if(tile != null && tile.getTeam() == state.rules.defaultTeam && !(tile.block() instanceof CoreBlock)){
if(tile != null && tile.team() == state.rules.defaultTeam && !(tile.block() instanceof CoreBlock)){
tile.remove();
}
});
Geometry.circle(coreb.x(), coreb.y(), 5, (cx, cy) -> world.tile(cx, cy).clearOverlay());
Geometry.circle(coreb.x, coreb.y, 5, (cx, cy) -> world.tile(cx, cy).clearOverlay());
world.endMapLoad();

View File

@ -56,7 +56,7 @@ public class Logic implements ApplicationListener{
}
}
TeamData data = state.teams.get(tile.getTeam());
TeamData data = state.teams.get(tile.team());
//remove existing blocks that have been placed here.
//painful O(n) iteration + copy
@ -78,7 +78,7 @@ public class Logic implements ApplicationListener{
while(it.hasNext()){
BrokenBlock b = it.next();
Block block = content.block(b.block);
if(event.tile.block().bounds(event.tile.x, event.tile.y, Tmp.r1).overlaps(block.bounds(b.x(), b.y(), Tmp.r2))){
if(event.tile.block().bounds(event.tile.x, event.tile.y, Tmp.r1).overlaps(block.bounds(b.x, b.y, Tmp.r2))){
it.remove();
}
}
@ -120,7 +120,7 @@ public class Logic implements ApplicationListener{
state.rules = new Rules();
state.stats = new Stats();
entities.clear();
Groups.all.clear();
Time.clear();
Events.fire(new ResetEvent());
}
@ -205,7 +205,7 @@ public class Logic implements ApplicationListener{
if(!state.is(State.menu)){
if(!net.client()){
//TODO
//state.enemies = Groups.unit.count(b -> b.getTeam() == state.rules.waveTeam && b.countsAsEnemy());
//state.enemies = Groups.unit.count(b -> b.team() == state.rules.waveTeam && b.countsAsEnemy());
}
if(!state.isPaused()){

View File

@ -11,10 +11,6 @@ import arc.util.serialization.*;
import mindustry.*;
import mindustry.annotations.Annotations.*;
import mindustry.core.GameState.*;
import mindustry.ctype.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.entities.units.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.gen.*;
@ -22,7 +18,6 @@ import mindustry.net.Administration.*;
import mindustry.net.Net.*;
import mindustry.net.*;
import mindustry.net.Packets.*;
import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.modules.*;
@ -127,7 +122,8 @@ public class NetClient implements ApplicationListener{
net.handleClient(InvokePacket.class, packet -> {
packet.writeBuffer.position(0);
RemoteReadClient.readPacket(packet.writeBuffer, packet.type);
//TODO fix remote read client
// RemoteReadClient.readPacket(packet.writeBuffer, packet.type);
});
}
@ -180,7 +176,8 @@ public class NetClient implements ApplicationListener{
//invoke event for all clients but also locally
//this is required so other clients get the correct name even if they don't know who's sending it yet
Call.sendMessage(message, colorizeName(player.id(), player.name()), player);
//TODO uncomment when it works
//Call.sendMessage(message, colorizeName(player.id(), player.name()), player);
}else{
//log command to console but with brackets
Log.info("<&y{0}: &lm{1}&lg>", player.name(), message);
@ -298,7 +295,7 @@ public class NetClient implements ApplicationListener{
@Remote(variants = Variant.both)
public static void onWorldDataBegin(){
entities.clear();
Groups.all.clear();
netClient.removed.clear();
logic.reset();
@ -457,7 +454,8 @@ public class NetClient implements ApplicationListener{
connecting = false;
ui.join.hide();
net.setClientLoaded(true);
Core.app.post(Call::connectConfirm);
//TODO connect confirm
//Core.app.post(Call::connectConfirm);
Time.runTask(40f, platform::updateRPC);
Core.app.post(() -> ui.loadfrag.hide());
}
@ -471,7 +469,7 @@ public class NetClient implements ApplicationListener{
quiet = false;
lastSent = 0;
entities.clear();
Groups.all.clear();
ui.chatfrag.clearMessages();
}
@ -505,7 +503,8 @@ public class NetClient implements ApplicationListener{
}
void sync(){
//TODO implement
/*
if(timer.get(0, playerSyncTime)){
BuildRequest[] requests;
//limit to 10 to prevent buffer overflows
@ -528,7 +527,7 @@ public class NetClient implements ApplicationListener{
if(timer.get(1, 60)){
Call.onPing(Time.millis());
}
}*/
}
String getUsid(String ip){

View File

@ -9,16 +9,12 @@ import arc.util.*;
import arc.util.CommandHandler.*;
import arc.util.io.*;
import mindustry.annotations.Annotations.*;
import mindustry.content.*;
import mindustry.core.GameState.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.gen.*;
import mindustry.entities.units.*;
import mindustry.net.Administration;
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.game.Teams.*;
import mindustry.gen.*;
import mindustry.net.*;
import mindustry.net.Administration.*;
import mindustry.net.Packets.*;
@ -161,16 +157,14 @@ public class NetServer implements ApplicationListener{
boolean preventDuplicates = headless && netServer.admins.getStrict();
if(preventDuplicates){
for(Playerc player : Groups.player.all()){
if(player.name.trim().equalsIgnoreCase(packet.name.trim())){
con.kick(KickReason.nameInUse);
return;
}
if(Groups.player.contains(p -> p.name().trim().equalsIgnoreCase(packet.name.trim()))){
con.kick(KickReason.nameInUse);
return;
}
if(player.uuid != null && player.usid != null && (player.uuid.equals(packet.uuid) || player.usid.equals(packet.usid))){
con.kick(KickReason.idInUse);
return;
}
if(Groups.player.contains(player -> player.uuid().equals(packet.uuid) || player.usid().equals(packet.usid))){
con.kick(KickReason.idInUse);
return;
}
}
@ -194,17 +188,15 @@ public class NetServer implements ApplicationListener{
con.modclient = true;
}
Playerc player = new Playerc();
player.isAdmin = admins.isAdmin(uuid, packet.usid);
player.con = con;
player.usid = packet.usid;
player.name = packet.name;
player.uuid = uuid;
player.isMobile = packet.mobile;
player.dead = true;
player.setNet(player.x, player.y);
player.color.set(packet.color);
player.color.a = 1f;
//TODO place instance of player here
Playerc player = null;//new Playerc();
player.admin(admins.isAdmin(uuid, packet.usid));
player.con(con);
player.con().usid = packet.usid;
player.con().uuid = uuid;
player.con().mobile = packet.mobile;
player.name(packet.name);
player.color().set(packet.color).a(1f);
try{
writeBuffer.position(0);
@ -218,7 +210,7 @@ public class NetServer implements ApplicationListener{
con.player = player;
//playing in pvp mode automatically assigns players to teams
player.team(assignTeam(player, Groups.player.all()));
player.team(assignTeam(player));
sendWorldData(player);
@ -230,7 +222,8 @@ public class NetServer implements ApplicationListener{
net.handleServer(InvokePacket.class, (con, packet) -> {
if(con.player == null) return;
try{
RemoteReadServer.readPacket(packet.writeBuffer, packet.type, con.player);
//TODO uncomment when compilation works
//RemoteReadServer.readPacket(packet.writeBuffer, packet.type, con.player);
}catch(ValidateException e){
Log.debug("Validation failed for '{0}': {1}", e.player, e.getMessage());
}catch(RuntimeException e){
@ -279,7 +272,7 @@ public class NetServer implements ApplicationListener{
});
clientCommands.<Playerc>register("t", "<message...>", "Send a message only to your teammates.", (args, player) -> {
Groups.player.all().each(p -> p.getTeam() == player.team(), o -> o.sendMessage(args[0], player, "[#" + player.team().color.toString() + "]<T>" + NetClient.colorizeName(player.id, player.name())));
Groups.player.each(p -> p.team() == player.team(), o -> o.sendMessage(args[0], player, "[#" + player.team().color.toString() + "]<T>" + NetClient.colorizeName(player.id(), player.name())));
});
//duration of a a kick in seconds
@ -301,7 +294,7 @@ public class NetServer implements ApplicationListener{
this.map = map;
this.task = Timer.schedule(() -> {
if(!checkPass()){
Call.sendMessage(Strings.format("[lightgray]Vote failed. Not enough votes to kick[orange] {0}[lightgray].", target.name));
Call.sendMessage(Strings.format("[lightgray]Vote failed. Not enough votes to kick[orange] {0}[lightgray].", target.name()));
map[0] = null;
task.cancel();
}
@ -310,17 +303,17 @@ public class NetServer implements ApplicationListener{
void vote(Playerc player, int d){
votes += d;
voted.addAll(player.uuid, admins.getInfo(player.uuid).lastIP);
voted.addAll(player.uuid(), admins.getInfo(player.uuid()).lastIP);
Call.sendMessage(Strings.format("[orange]{0}[lightgray] has voted to kick[orange] {1}[].[accent] ({2}/{3})\n[lightgray]Type[orange] /vote <y/n>[] to agree.",
player.name(), target.name, votes, votesRequired()));
player.name(), target.name(), votes, votesRequired()));
}
boolean checkPass(){
if(votes >= votesRequired()){
Call.sendMessage(Strings.format("[orange]Vote passed.[scarlet] {0}[orange] will be banned from the server for {1} minutes.", target.name, (kickDuration/60)));
Call.sendMessage(Strings.format("[orange]Vote passed.[scarlet] {0}[orange] will be banned from the server for {1} minutes.", target.name(), (kickDuration/60)));
target.getInfo().lastKicked = Time.millis() + kickDuration*1000;
Groups.player.all().each(p -> p.uuid != null && p.uuid.equals(target.uuid), p -> p.con.kick(KickReason.vote));
Groups.player.each(p -> p.uuid().equals(target.uuid()), p -> p.kick(KickReason.vote));
map[0] = null;
task.cancel();
return true;
@ -352,25 +345,24 @@ public class NetServer implements ApplicationListener{
if(args.length == 0){
StringBuilder builder = new StringBuilder();
builder.append("[orange]Players to kick: \n");
for(Playerc p : Groups.player.all()){
if(p.isAdmin || p.con == null || p == player) continue;
builder.append("[lightgray] ").append(p.name).append("[accent] (#").append(p.id).append(")\n");
}
Groups.player.each(p -> !p.admin() && p.con() != null && p != player, p -> {
builder.append("[lightgray] ").append(p.name()).append("[accent] (#").append(p.id()).append(")\n");
});
player.sendMessage(builder.toString());
}else{
Playerc found;
if(args[0].length() > 1 && args[0].startsWith("#") && Strings.canParseInt(args[0].substring(1))){
int id = Strings.parseInt(args[0].substring(1));
found = Groups.player.find(p -> p.id == id);
found = Groups.player.find(p -> p.id() == id);
}else{
found = Groups.player.find(p -> p.name.equalsIgnoreCase(args[0]));
found = Groups.player.find(p -> p.name().equalsIgnoreCase(args[0]));
}
if(found != null){
if(found.isAdmin){
if(found.admin()){
player.sendMessage("[scarlet]Did you really expect to be able to kick an admin?");
}else if(found.isLocal){
}else if(found.isLocal()){
player.sendMessage("[scarlet]Local players cannot be kicked.");
}else if(found.team() != player.team()){
player.sendMessage("[scarlet]Only players on your team can be kicked.");
@ -401,7 +393,7 @@ public class NetServer implements ApplicationListener{
}
//hosts can vote all they want
if(player.uuid != null && (currentlyKicking[0].voted.contains(player.uuid) || currentlyKicking[0].voted.contains(admins.getInfo(player.uuid).lastIP))){
if((currentlyKicking[0].voted.contains(player.uuid()) || currentlyKicking[0].voted.contains(admins.getInfo(player.uuid()).lastIP))){
player.sendMessage("[scarlet]You've already voted. Sit down.");
return;
}
@ -432,7 +424,7 @@ public class NetServer implements ApplicationListener{
}
player.getInfo().lastSyncTime = Time.millis();
Call.onWorldDataBegin(player.con);
Call.onWorldDataBegin(player.con());
netServer.sendWorldData(player);
}
});
@ -442,6 +434,10 @@ public class NetServer implements ApplicationListener{
return 2 + (Groups.player.size() > 4 ? 1 : 0);
}
public Team assignTeam(Playerc current){
return assigner.assign(current, Groups.player);
}
public Team assignTeam(Playerc current, Iterable<Playerc> players){
return assigner.assign(current, players);
}
@ -452,30 +448,30 @@ public class NetServer implements ApplicationListener{
NetworkIO.writeWorld(player, def);
WorldStream data = new WorldStream();
data.stream = new ByteArrayInputStream(stream.toByteArray());
player.con.sendStream(data);
player.con().sendStream(data);
Log.debug("Packed {0} compressed bytes of world data.", stream.size());
}
public static void onDisconnect(Playerc player, String reason){
//singleplayer multiplayer wierdness
if(player.con == null){
if(player.con() == null){
player.remove();
return;
}
if(!player.con.hasDisconnected){
if(player.con.hasConnected){
if(!player.con().hasDisconnected){
if(player.con().hasConnected){
Events.fire(new PlayerLeave(player));
if(Config.showConnectMessages.bool()) Call.sendMessage("[accent]" + player.name + "[accent] has disconnected.");
Call.onPlayerDisconnect(player.id);
if(Config.showConnectMessages.bool()) Call.sendMessage("[accent]" + player.name() + "[accent] has disconnected.");
Call.onPlayerDisconnect(player.id());
}
if(Config.showConnectMessages.bool()) Log.info("&lm[{1}] &lc{0} has disconnected. &lg&fi({2})", player.name(), player.uuid, reason);
if(Config.showConnectMessages.bool()) Log.info("&lm[{1}] &lc{0} has disconnected. &lg&fi({2})", player.name(), player.uuid(), reason);
}
player.remove();
player.con.hasDisconnected = true;
player.con().hasDisconnected = true;
}
@Remote(targets = Loc.client, unreliable = true)
@ -491,7 +487,9 @@ public class NetServer implements ApplicationListener{
BuildRequest[] requests,
float viewX, float viewY, float viewWidth, float viewHeight
){
NetConnection connection = player.con;
//TODO this entire thing needs to be rewritten.
/*
NetConnection connection = player.con();
if(connection == null || snapshotID < connection.lastRecievedClientSnapshot) return;
boolean verifyPosition = !player.dead() && netServer.admins.getStrict() && headless;
@ -534,7 +532,7 @@ public class NetServer implements ApplicationListener{
action.config = req.config;
})){
//force the player to remove this request if that's not the case
Call.removeQueueBlock(player.con, req.x, req.y, req.breaking);
Call.removeQueueBlock(player.con(), req.x, req.y, req.breaking);
connection.rejectedRequests.add(req);
continue;
}
@ -562,7 +560,7 @@ public class NetServer implements ApplicationListener{
newx = x;
newy = y;
}else if(Mathf.dst(x, y, newx, newy) > correctDist){
Call.onPositionSet(player.con, newx, newy); //teleport and correct position when necessary
Call.onPositionSet(player.con(), newx, newy); //teleport and correct position when necessary
}
//reset player to previous synced position so it gets interpolated
@ -574,7 +572,7 @@ public class NetServer implements ApplicationListener{
player.vel().set(xVelocity, yVelocity); //only for visual calculation purposes, doesn't actually update the player
connection.lastRecievedClientSnapshot = snapshotID;
connection.lastRecievedClientTime = Time.millis();
connection.lastRecievedClientTime = Time.millis();*/
}
@Remote(targets = Loc.client, called = Loc.server)
@ -603,9 +601,10 @@ public class NetServer implements ApplicationListener{
other.kick(KickReason.kick);
Log.info("&lc{0} has kicked {1}.", player.name(), other.name());
}else if(action == AdminAction.trace){
TraceInfo info = new TraceInfo(other.con().address, other.uuid(), other.con().modclient, other.con.mobile);
TraceInfo info = new TraceInfo(other.con().address, other.uuid(), other.con().modclient, other.con().mobile);
if(player.con() != null){
Call.onTraceInfo(player.con(), other, info);
//TODO uncomment
//Call.onTraceInfo(player.con(), other, info);
}else{
NetClient.onTraceInfo(other, info);
}
@ -635,7 +634,7 @@ public class NetServer implements ApplicationListener{
if(state.rules.pvp){
int used = 0;
for(TeamData t : state.teams.getActive()){
if(Groups.player.count(p -> p.getTeam() == t.team) > 0){
if(Groups.player.count(p -> p.team() == t.team) > 0){
used++;
}
}
@ -687,11 +686,11 @@ public class NetServer implements ApplicationListener{
syncStream.reset();
short sent = 0;
for(Tilec entity : tileGroup.all()){
if(!entity.block.sync) continue;
for(Tilec entity : Groups.tile){
if(!entity.block().sync) continue;
sent ++;
dataStream.writeInt(entity.tile.pos());
dataStream.writeInt(entity.tile().pos());
entity.write(dataStream);
if(syncStream.size() > maxSnapshotSize){
@ -725,35 +724,26 @@ public class NetServer implements ApplicationListener{
byte[] stateBytes = syncStream.toByteArray();
//write basic state data.
Call.onStateSnapshot(player.con, state.wavetime, state.wave, state.enemies, (short)stateBytes.length, net.compressSnapshot(stateBytes));
Call.onStateSnapshot(player.con(), state.wavetime, state.wave, state.enemies, (short)stateBytes.length, net.compressSnapshot(stateBytes));
viewport.setSize(player.con.viewWidth, player.con.viewHeight).setCenter(player.con.viewX, player.con.viewY);
//check for syncable groups
//make sure mapping is enabled for this group
if(!group.mappingEnabled()){
throw new RuntimeException("Entity group '" + group.getType() + "' contains SyncTrait entities, yet mapping is not enabled. In order for syncing to work, you must enable mapping for this group.");
}
viewport.setSize(player.con().viewWidth, player.con().viewHeight).setCenter(player.con().viewX, player.con().viewY);
syncStream.reset();
int sent = 0;
for(Entity entity : group.all()){
SyncTrait sync = (SyncTrait)entity;
for(Syncc entity : Groups.sync){
//write all entities now
dataStream.writeInt(entity.getID()); //write id
dataStream.writeByte(sync.getTypeID().id); //write type ID
sync.write(dataStream); //write entity
dataStream.writeInt(entity.id()); //write id
dataStream.writeByte(entity.classId()); //write type ID
entity.write(dataStream); //write entity
sent++;
if(syncStream.size() > maxSnapshotSize){
dataStream.close();
byte[] syncBytes = syncStream.toByteArray();
Call.onEntitySnapshot(player.con, (byte)group.getID(), (short)sent, (short)syncBytes.length, net.compressSnapshot(syncBytes));
Call.onEntitySnapshot(player.con(), (short)sent, (short)syncBytes.length, net.compressSnapshot(syncBytes));
sent = 0;
syncStream.reset();
}
@ -763,7 +753,7 @@ public class NetServer implements ApplicationListener{
dataStream.close();
byte[] syncBytes = syncStream.toByteArray();
Call.onEntitySnapshot(player.con, (byte)group.getID(), (short)sent, (short)syncBytes.length, net.compressSnapshot(syncBytes));
Call.onEntitySnapshot(player.con(), (short)sent, (short)syncBytes.length, net.compressSnapshot(syncBytes));
}
}
@ -821,22 +811,22 @@ public class NetServer implements ApplicationListener{
void sync(){
try{
//iterate through each player
for(int i = 0; i < Groups.player.size(); i++){
Playerc player = Groups.player.all().get(i);
if(player.isLocal()) continue;
if(player.con == null || !player.con.isConnected()){
Groups.player.each(p -> !p.isLocal(), player -> {
if(player.con() == null || !player.con().isConnected()){
onDisconnect(player, "disappeared");
continue;
return;
}
NetConnection connection = player.con;
NetConnection connection = player.con();
if(!player.timer.get(Playerc.timerSync, serverSyncTime) || !connection.hasConnected) continue;
if(!player.timer(0, serverSyncTime) || !connection.hasConnected) return;
writeEntitySnapshot(player);
}
try{
writeEntitySnapshot(player);
}catch(IOException e){
e.printStackTrace();
}
});
if(Groups.player.size() > 0 && Core.settings.getBool("blocksync") && timer.get(timerBlockSync, blockSyncTime)){
writeBlockSnapshots();

View File

@ -1,8 +1,6 @@
package mindustry.core;
import arc.*;
import arc.files.*;
import arc.func.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.graphics.gl.*;
@ -12,13 +10,8 @@ import arc.scene.ui.layout.*;
import arc.util.*;
import mindustry.content.*;
import mindustry.core.GameState.*;
import mindustry.gen.*;
import mindustry.game.EventType.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.input.*;
import mindustry.ui.*;
import mindustry.world.blocks.defense.ForceProjector.*;
import static arc.Core.*;
import static mindustry.Vars.*;
@ -80,6 +73,8 @@ public class Renderer implements ApplicationListener{
}else{
Vec2 position = Tmp.v3.set(player);
//TODO camera controls should be in input
/*
if(player.dead()){
Tilec core = player.closestCore();
if(core != null){
@ -91,7 +86,7 @@ public class Renderer implements ApplicationListener{
}
}else if(control.input instanceof DesktopInput && !state.isPaused()){
camera.position.lerpDelta(position, 0.08f);
}
}*/
updateShake(0.75f);
if(pixelator.enabled()){
@ -173,6 +168,10 @@ public class Renderer implements ApplicationListener{
}
}
public void draw(){
//TODO do it
}
/*
public void draw(){
camera.update();
@ -339,7 +338,7 @@ public class Renderer implements ApplicationListener{
Groups.unit.draw(u -> u.isFlying() == flying && !u.isDead(), Unitc::drawOver);
Groups.player.draw(p -> p.isFlying() == flying, Unitc::drawOver);
}
}*/
public void scaleCamera(float amount){
targetscale += amount;
@ -366,6 +365,8 @@ public class Renderer implements ApplicationListener{
}
public void takeMapScreenshot(){
//TODO uncomment
/*
drawGroundShadows();
int w = world.width() * tilesize, h = world.height() * tilesize;
@ -414,7 +415,7 @@ public class Renderer implements ApplicationListener{
buffer.dispose();
Core.settings.put("animatedwater", hadWater);
Core.settings.put("animatedshields", hadShields);
Core.settings.put("animatedshields", hadShields);*/
}
}

View File

@ -12,6 +12,7 @@ import mindustry.core.GameState.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.game.Teams.*;
import mindustry.gen.*;
import mindustry.io.*;
import mindustry.maps.*;
import mindustry.maps.filters.*;
@ -163,7 +164,7 @@ public class World{
addDarkness(tiles);
}
entities.all().each(group -> group.resize(-finalWorldBounds, -finalWorldBounds, tiles.width() * tilesize + finalWorldBounds * 2, tiles.height() * tilesize + finalWorldBounds * 2));
Groups.resize(-finalWorldBounds, -finalWorldBounds, tiles.width() * tilesize + finalWorldBounds * 2, tiles.height() * tilesize + finalWorldBounds * 2);
generating = false;
Events.fire(new WorldLoadEvent());
@ -377,7 +378,7 @@ public class World{
Tile tile = tiles.getn(x, y);
Block result = tile.block();
Team team = tile.getTeam();
Team team = tile.team();
int offsetx = -(result.size - 1) / 2;
int offsety = -(result.size - 1) / 2;

View File

@ -65,7 +65,7 @@ public class DrawOperation{
tile.setFloor((Floor)content.block(to));
}else if(type == OpType.block.ordinal()){
Block block = content.block(to);
tile.setBlock(block, tile.getTeam(), tile.rotation());
tile.setBlock(block, tile.team(), tile.rotation());
}else if(type == OpType.rotation.ordinal()){
tile.rotation(to);
}else if(type == OpType.team.ordinal()){

View File

@ -138,11 +138,12 @@ public class EditorTile extends Tile{
Block block = block();
if(block.hasEntity()){
entity = block.newEntity().init(this, false);
entity.cons = new ConsumeModule(entity);
if(block.hasItems) entity.items() = new ItemModule();
if(block.hasLiquids) entity.liquids() = new LiquidModule();
if(block.hasPower) entity.power() = new PowerModule();
//TODO uncomment once this mess is figure out
//entity = block.newEntity().init(this, false);
entity.cons(new ConsumeModule(entity));
if(block.hasItems) entity.items(new ItemModule());
if(block.hasLiquids) entity.liquids(new LiquidModule());
if(block.hasPower) entity.power(new PowerModule());
}
}

View File

@ -138,7 +138,7 @@ public enum EditorTool{
//only fill synthetic blocks, it's meaningless otherwise
if(tile.link().synthetic()){
Team dest = tile.getTeam();
Team dest = tile.team();
if(dest == editor.drawTeam) return;
fill(editor, x, y, false, t -> t.getTeamID() == (int)dest.id && t.link().synthetic(), t -> t.setTeam(editor.drawTeam));
}

View File

@ -83,7 +83,7 @@ public class MapEditor{
//re-add them
for(Tile tile : tiles){
if(tile.block().isMultiblock()){
tile.set(tile.block(), tile.getTeam());
tile.set(tile.block(), tile.team());
}
}

View File

@ -283,7 +283,8 @@ public class MapEditorDialog extends Dialog implements Disposable{
}
}
player.set(world.width() * tilesize/2f, world.height() * tilesize/2f);
player.dead(false);
//TODO figure out how to kill player
//player.dead(false);
logic.play();
});
}
@ -295,7 +296,8 @@ public class MapEditorDialog extends Dialog implements Disposable{
editor.getTags().put("rules", JsonIO.write(state.rules));
editor.getTags().remove("width");
editor.getTags().remove("height");
player.dead = true;
//TODO unkill player
//player.dead = true;
Map returned = null;

View File

@ -124,7 +124,7 @@ public class MapGenerateDialog extends FloatingDialog{
Tile tile = editor.tile(x, y);
input.apply(x, y, tile.floor(), tile.block(), tile.overlay());
filter.apply(input);
writeTiles[x][y].set(input.floor, input.block, input.ore, tile.getTeam(), tile.rotation());
writeTiles[x][y].set(input.floor, input.block, input.ore, tile.team(), tile.rotation());
}
}
@ -424,7 +424,7 @@ public class MapGenerateDialog extends FloatingDialog{
}
public GenTile set(Tile other){
set(other.floor(), other.block(), other.overlay(), other.getTeam(), other.rotation());
set(other.floor(), other.block(), other.overlay(), other.team(), other.rotation());
return this;
}

View File

@ -111,7 +111,7 @@ public class MapRenderer implements Disposable{
IndexedRenderer mesh = chunks[x][y];
Tile tile = editor.tiles().getn(wx, wy);
Team team = tile.getTeam();
Team team = tile.team();
Block floor = tile.floor();
Block wall = tile.block();

View File

@ -30,7 +30,7 @@ public class WaveInfoDialog extends FloatingDialog{
private Table table, preview;
private int start = 0;
private UnitType lastType = UnitTypes.dagger;
private UnitDef lastType = UnitTypes.dagger;
private float updateTimer, updatePeriod = 1f;
public WaveInfoDialog(MapEditor editor){
@ -221,7 +221,7 @@ public class WaveInfoDialog extends FloatingDialog{
dialog.setFillParent(true);
dialog.cont.pane(p -> {
int i = 0;
for(UnitType type : content.units()){
for(UnitDef type : content.units()){
p.addButton(t -> {
t.left();
t.addImage(type.icon(mindustry.ui.Cicon.medium)).size(40f).padRight(2f);
@ -256,7 +256,7 @@ public class WaveInfoDialog extends FloatingDialog{
for(int j = 0; j < spawned.length; j++){
if(spawned[j] > 0){
UnitType type = content.getByID(ContentType.unit, j);
UnitDef type = content.getByID(ContentType.unit, j);
table.addImage(type.icon(Cicon.medium)).size(8f * 4f).padRight(4);
table.add(spawned[j] + "x").color(Color.lightGray).padRight(6);
table.row();

View File

@ -1,19 +1,17 @@
package mindustry.entities;
import arc.*;
import mindustry.annotations.Annotations.*;
import arc.struct.*;
import arc.func.*;
import arc.graphics.*;
import arc.math.*;
import arc.math.geom.*;
import arc.struct.*;
import arc.util.*;
import mindustry.annotations.Annotations.*;
import mindustry.content.*;
import mindustry.entities.effect.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.world.*;
import static mindustry.Vars.*;
@ -31,8 +29,8 @@ public class Damage{
public static void dynamicExplosion(float x, float y, float flammability, float explosiveness, float power, float radius, Color color){
for(int i = 0; i < Mathf.clamp(power / 20, 0, 6); i++){
int branches = 5 + Mathf.clamp((int)(power / 30), 1, 20);
Time.run(i * 2f + Mathf.random(4f), () -> Lightning.create(Team.derelict, Pal.power, 3,
x, y, Mathf.random(360f), branches + Mathf.range(2)));
//TODO uncomment
//Time.run(i * 2f + Mathf.random(4f), () -> Lightning.create(Team.derelict, Pal.power, 3, x, y, Mathf.random(360f), branches + Mathf.range(2)));
}
for(int i = 0; i < Mathf.clamp(flammability / 4, 0, 30); i++){
@ -68,7 +66,8 @@ public class Damage{
float cy = y + Mathf.range(range);
Tile tile = world.tileWorld(cx, cy);
if(tile != null){
Fire.create(tile);
//TODO uncomment
//Fire.create(tile);
}
}
}
@ -234,7 +233,7 @@ public class Damage{
if(scaledDamage <= 0 || tile == null) continue;
//apply damage to entity if needed
if(tile.entity != null && tile.getTeam() != team){
if(tile.entity != null && tile.team() != team){
int health = (int)tile.entity.health();
if(tile.entity.health() > 0){
tile.entity.damage(scaledDamage);
@ -257,7 +256,7 @@ public class Damage{
for(int dx = -trad; dx <= trad; dx++){
for(int dy = -trad; dy <= trad; dy++){
Tile tile = world.tile(Math.round(x / tilesize) + dx, Math.round(y / tilesize) + dy);
if(tile != null && tile.entity != null && (team == null ||team.isEnemy(tile.getTeam())) && Mathf.dst(dx, dy) <= trad){
if(tile != null && tile.entity != null && (team == null ||team.isEnemy(tile.team())) && Mathf.dst(dx, dy) <= trad){
tile.entity.damage(damage);
}
}

View File

@ -97,6 +97,10 @@ public class Effect{
this.data = data;
}
public <T> T data(){
return (T)data;
}
public void scaled(float lifetime, Cons<EffectContainer> cons){
if(innerContainer == null) innerContainer = new EffectContainer();
if(time <= lifetime){

View File

@ -5,16 +5,19 @@ import arc.math.geom.*;
import arc.struct.*;
import mindustry.gen.*;
import java.util.*;
import static mindustry.Vars.*;
/** Represents a group of a certain type of entity.*/
@SuppressWarnings("unchecked")
public class EntityGroup<T extends Entityc>{
public class EntityGroup<T extends Entityc> implements Iterable<T>{
private final Array<T> array = new Array<>(false, 32);
private final Array<T> intersectArray = new Array<>();
private final Rect intersectRect = new Rect();
private IntMap<T> map;
private QuadTree tree;
private boolean clearing;
private int index;
@ -44,6 +47,13 @@ public class EntityGroup<T extends Entityc>{
}
}
public void each(Boolf<T> filter, Cons<T> cons){
T[] items = array.items;
for(index = 0; index < array.size; index++){
if(filter.get(items[index])) cons.get(items[index]);
}
}
public boolean useTree(){
return map != null;
}
@ -101,6 +111,10 @@ public class EntityGroup<T extends Entityc>{
return array.size;
}
public boolean contains(Boolf<T> pred){
return array.contains(pred);
}
public int count(Boolf<T> pred){
return array.count(pred);
}
@ -110,11 +124,12 @@ public class EntityGroup<T extends Entityc>{
array.add(type);
if(mappingEnabled()){
map.put(type.getId(), type);
map.put(type.id(), type);
}
}
public void remove(T type){
if(clearing) return;
if(type == null) throw new RuntimeException("Cannot remove a null entity!");
int idx = array.indexOf(type, true);
if(idx != -1){
@ -128,12 +143,22 @@ public class EntityGroup<T extends Entityc>{
}
public void clear(){
clearing = true;
array.each(Entityc::remove);
array.clear();
if(map != null)
map.clear();
clearing = false;
}
public T find(Boolf<T> pred){
return array.find(pred);
}
@Override
public Iterator<T> iterator(){
return array.iterator();
}
}

View File

@ -0,0 +1,86 @@
package mindustry.entities;
import arc.graphics.*;
import arc.math.*;
import arc.math.geom.*;
import arc.struct.*;
import mindustry.content.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.world.*;
import static mindustry.Vars.*;
//TODO move into a different class
public class Lightning{
private static final Rand random = new Rand();
private static final Rect rect = new Rect();
private static final Array<Unitc> entities = new Array<>();
private static final IntSet hit = new IntSet();
private static final int maxChain = 8;
private static final float hitRange = 30f;
private static boolean bhit = false;
private static int lastSeed = 0;
/** Create a lighting branch at a location. Use Team.none to damage everyone. */
public static void create(Team team, Color color, float damage, float x, float y, float targetAngle, int length){
createLightingInternal(lastSeed++, team, color, damage, x, y, targetAngle, length);
}
//TODO remote method
//@Remote(called = Loc.server, unreliable = true)
private static void createLightingInternal(int seed, Team team, Color color, float damage, float x, float y, float rotation, int length){
random.setSeed(seed);
hit.clear();
Array<Vec2> lines = new Array<>();
bhit = false;
for(int i = 0; i < length / 2; i++){
Bullets.damageLightning.create(null, team, x, y, 0f, damage, 1f, 1f, null);
lines.add(new Vec2(x + Mathf.range(3f), y + Mathf.range(3f)));
if(lines.size > 1){
bhit = false;
Vec2 from = lines.get(lines.size - 2);
Vec2 to = lines.get(lines.size - 1);
world.raycastEach(world.toTile(from.getX()), world.toTile(from.getY()), world.toTile(to.getX()), world.toTile(to.getY()), (wx, wy) -> {
Tile tile = world.ltile(wx, wy);
if(tile != null && tile.block().insulated){
bhit = true;
//snap it instead of removing
lines.get(lines.size -1).set(wx * tilesize, wy * tilesize);
return true;
}
return false;
});
if(bhit) break;
}
rect.setSize(hitRange).setCenter(x, y);
entities.clear();
if(hit.size < maxChain){
Units.nearbyEnemies(team, rect, u -> {
if(!hit.contains(u.id())){
entities.add(u);
}
});
}
Unitc furthest = Geometry.findFurthest(x, y, entities);
if(furthest != null){
hit.add(furthest.id());
x = furthest.x();
y = furthest.y();
}else{
rotation += random.range(20f);
x += Angles.trnsx(rotation, hitRange / 2f);
y += Angles.trnsy(rotation, hitRange / 2f);
}
}
Fx.lightning.at(x, y, rotation, color, lines);
}
}

View File

@ -3,6 +3,8 @@ package mindustry.entities;
import arc.math.*;
import arc.math.geom.*;
import arc.util.*;
import mindustry.gen.*;
/**
* Class for predicting shoot angles based on velocities of targets.
*/
@ -52,8 +54,8 @@ public class Predict{
/**
* See {@link #intercept(float, float, float, float, float, float, float)}.
*/
public static Vec2 intercept(Teamc src, Teamc dst, float v){
return intercept(src.getX(), src.getY(), dst.getX(), dst.getY(), dst.getTargetVelocityX() - src.getTargetVelocityX()/(2f*Time.delta()), dst.getTargetVelocityY() - src.getTargetVelocityY()/(2f*Time.delta()), v);
public static Vec2 intercept(Hitboxc src, Hitboxc dst, float v){
return intercept(src.getX(), src.getY(), dst.getX(), dst.getY(), dst.deltaX() - src.deltaX()/(2f*Time.delta()), dst.deltaY() - src.deltaX()/(2f*Time.delta()), v);
}
private static Vec2 quad(float a, float b, float c){

View File

@ -1,9 +1,7 @@
package mindustry.entities;
import arc.func.*;
import arc.math.*;
import arc.math.geom.*;
import mindustry.gen.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.world.*;
@ -41,8 +39,8 @@ public class Units{
}
/** See {@link #invalidateTarget(Teamc, Team, float, float, float)} */
public static boolean invalidateTarget(Teamc target, Unitc targeter){
return invalidateTarget(target, targeter.team(), targeter.x, targeter.y, targeter.getWeapon().bullet.range());
public static boolean invalidateTarget(Teamc target, Unitc targeter, float range){
return invalidateTarget(target, targeter.team(), targeter.x(), targeter.y(), range);
}
/** Returns whether there are any entities on this tile. */
@ -56,7 +54,7 @@ public class Units{
nearby(x, y, width, height, unit -> {
if(boolResult) return;
if(!unit.isFlying()){
if(unit.isGrounded()){
unit.hitbox(hitrect);
if(hitrect.overlaps(x, y, width, height)){
@ -118,7 +116,7 @@ public class Units{
nearbyEnemies(team, x - range, y - range, range*2f, range*2f, e -> {
if(e.dead() || !predicate.get(e)) return;
float dst2 = Mathf.dst2(e.x, e.y, x, y);
float dst2 = e.dst2(x, y);
if(dst2 < range*range && (result == null || dst2 < cdist)){
result = e;
cdist = dst2;
@ -136,7 +134,7 @@ public class Units{
nearby(team, x, y, range, e -> {
if(!predicate.get(e)) return;
float dist = Mathf.dst2(e.x, e.y, x, y);
float dist = e.dst2(x, y);
if(result == null || dist < cdist){
result = e;
cdist = dist;
@ -149,7 +147,7 @@ public class Units{
/** Iterates over all units in a rectangle. */
public static void nearby(Team team, float x, float y, float width, float height, Cons<Unitc> cons){
Groups.unit.intersect(x, y, width, height, u -> {
if(u.getTeam() == team){
if(u.team() == team){
cons.get(u);
}
});
@ -158,7 +156,7 @@ public class Units{
/** Iterates over all units in a circle around this position. */
public static void nearby(Team team, float x, float y, float radius, Cons<Unitc> cons){
Groups.unit.intersect(x - radius, y - radius, radius*2f, radius*2f, unit -> {
if(unit.getTeam() == team && unit.withinDst(x, y, radius)){
if(unit.team() == team && unit.withinDst(x, y, radius)){
cons.get(unit);
}
});
@ -177,7 +175,7 @@ public class Units{
/** Iterates over all units that are enemies of this team. */
public static void nearbyEnemies(Team team, float x, float y, float width, float height, Cons<Unitc> cons){
Groups.unit.intersect(x, y, width, height, u -> {
if(team.isEnemy(u.getTeam())){
if(team.isEnemy(u.team())){
cons.get(u);
}
});
@ -188,13 +186,4 @@ public class Units{
nearbyEnemies(team, rect.x, rect.y, rect.width, rect.height, cons);
}
/** Iterates over all units. */
public static void all(Cons<Unitc> cons){
Groups.unit.all().each(cons);
}
public static void each(Team team, Cons<Unitc> cons){
Groups.unit.all().each(t -> t.getTeam() == team, cons);
}
}

View File

@ -26,7 +26,7 @@ public class ArtilleryBulletType extends BasicBulletType{
public void update(Bulletc b){
super.update(b);
if(b.timer.get(0, 3 + b.fslope() * 2f)){
if(b.timer(0, 3 + b.fslope() * 2f)){
trailEffect.at(b.x(), b.y(), b.fslope() * 4f, backColor);
}
}

View File

@ -2,11 +2,11 @@ package mindustry.entities.bullet;
import arc.audio.*;
import arc.math.*;
import arc.util.ArcAnnotate.*;
import mindustry.annotations.Annotations.*;
import mindustry.content.*;
import mindustry.ctype.*;
import mindustry.entities.*;
import mindustry.entities.effect.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.graphics.*;
@ -109,7 +109,7 @@ public abstract class BulletType extends Content{
}
public void hit(Bulletc b, float x, float y){
hitEffect.at(x, y, b.getRotation());
hitEffect.at(x, y, b.rotation());
hitSound.at(b);
Effects.shake(hitShake, hitShake, b);
@ -132,7 +132,7 @@ public abstract class BulletType extends Content{
}
public void despawned(Bulletc b){
despawnEffect.at(b.getX(), b.getY(), b.getRotation());
despawnEffect.at(b.getX(), b.getY(), b.rotation());
hitSound.at(b);
if(fragBullet != null || splashDamageRadius > 0){
@ -140,7 +140,7 @@ public abstract class BulletType extends Content{
}
for(int i = 0; i < lightining; i++){
Lightning.createLighting(Lightning.nextSeed(), b.team(), Pal.surge, damage, b.getX(), b.getY(), Mathf.random(360f), lightningLength);
Lightning.create(b.team(), Pal.surge, damage, b.getX(), b.getY(), Mathf.random(360f), lightningLength);
}
}
@ -148,20 +148,20 @@ public abstract class BulletType extends Content{
}
public void init(Bulletc b){
if(killShooter && b.getOwner() instanceof Healthc){
((Healthc)b.getOwner()).kill();
if(killShooter && b.owner() instanceof Healthc){
((Healthc)b.owner()).kill();
}
if(instantDisappear){
b.setTime(lifetime);
b.time(lifetime);
}
}
public void update(Bulletc b){
if(homingPower > 0.0001f){
Teamc target = Units.closestTarget(b.team(), b.getX(), b.getY(), homingRange, e -> !e.isFlying() || collidesAir);
Teamc target = Units.closestTarget(b.team(), b.getX(), b.getY(), homingRange, e -> e.isGrounded() || collidesAir);
if(target != null){
b.vel().setAngle(Mathf.slerpDelta(b.getRotation(), b.angleTo(target), 0.08f));
b.vel().setAngle(Mathf.slerpDelta(b.rotation(), b.angleTo(target), 0.08f));
}
}
}
@ -182,23 +182,24 @@ public abstract class BulletType extends Content{
}
public Bulletc create(Entityc owner, Team team, float x, float y, float angle, float velocityScl){
return create(owner, team, x, y, angle, velocityScl, 1f, null);
return create(owner, team, x, y, angle, -1, velocityScl, 1f, null);
}
public Bulletc create(Entityc owner, Team team, float x, float y, float angle, float velocityScl, float lifetimeScl){
return create(owner, team, x, y, angle, velocityScl, lifetimeScl, null);
return create(owner, team, x, y, angle, -1, velocityScl, lifetimeScl, null);
}
public Bulletc create(Bulletc parent, float x, float y, float angle){
return create(parent.getOwner(), parent.team(), x, y, angle);
return create(parent.owner(), parent.team(), x, y, angle);
}
public Bulletc create(Bulletc parent, float x, float y, float angle, float velocityScl){
return create(parent.getOwner(), parent.team(), x, y, angle, velocityScl);
return create(parent.owner(), parent.team(), x, y, angle, velocityScl);
}
public Bulletc create(Entityc owner, Team team, float x, float y, float angle, float velocityScl, float lifetimeScl, Object data){
public Bulletc create(@Nullable Entityc owner, Team team, float x, float y, float angle, float damage, float velocityScl, float lifetimeScl, Object data){
//TODO assign type damage is damage <0, else assign provided damage
//TODO implement
return null;
@ -223,12 +224,12 @@ public abstract class BulletType extends Content{
return bullet;*/
}
public void createNet(Team team, float x, float y, float angle, float velocityScl, float lifetimeScl){
Call.createBullet(this, team, x, y, angle, velocityScl, lifetimeScl);
public void createNet(Team team, float x, float y, float angle, float damage, float velocityScl, float lifetimeScl){
Call.createBullet(this, team, x, y, damage, angle, velocityScl, lifetimeScl);
}
@Remote(called = Loc.server, unreliable = true)
public static void createBullet(BulletType type, Team team, float x, float y, float angle, float velocityScl, float lifetimeScl){
type.create(null, team, x, y, angle, velocityScl, lifetimeScl, null);
public static void createBullet(BulletType type, Team team, float x, float y, float angle, float damage, float velocityScl, float lifetimeScl){
type.create(null, team, x, y, angle, damage, velocityScl, lifetimeScl, null);
}
}

View File

@ -26,16 +26,16 @@ public class FlakBulletType extends BasicBulletType{
@Override
public void update(Bulletc b){
super.update(b);
if(b.getData() instanceof Integer) return;
if(b.data() instanceof Integer) return;
if(b.timer.get(2, 6)){
if(b.timer(2, 6)){
Units.nearbyEnemies(b.team(), rect.setSize(explodeRange * 2f).setCenter(b.x(), b.y()), unit -> {
if(b.getData() instanceof Float) return;
if(b.data() instanceof Float) return;
if(unit.dst(b) < explodeRange){
b.setData(0);
b.data(0);
Time.run(5f, () -> {
if(b.getData() instanceof Integer){
if(b.data() instanceof Integer){
b.time(b.lifetime());
}
});

View File

@ -29,7 +29,7 @@ public class HealBulletType extends BulletType{
@Override
public boolean collides(Bulletc b, Tile tile){
return tile.getTeam() != b.team() || tile.entity.healthf() < 1f;
return tile.team() != b.team() || tile.entity.healthf() < 1f;
}
@Override
@ -47,9 +47,9 @@ public class HealBulletType extends BulletType{
super.hit(b);
tile = tile.link();
if(tile.entity != null && tile.getTeam() == b.team() && !(tile.block() instanceof BuildBlock)){
if(tile.entity != null && tile.team() == b.team() && !(tile.block() instanceof BuildBlock)){
Fx.healBlockFull.at(tile.drawx(), tile.drawy(), tile.block().size, Pal.heal);
tile.entity.healBy(healPercent / 100f * tile.entity.maxHealth());
tile.entity.heal(healPercent / 100f * tile.entity.maxHealth());
}
}
}

View File

@ -58,7 +58,7 @@ public class LaserBulletType extends BulletType{
Lines.stroke((cwidth *= lengthFalloff) * b.fout());
Lines.lineAngle(b.x(), b.y(), b.rotation(), baseLen, CapStyle.none);
Tmp.v1.trns(b.rotation(), baseLen);
Drawf.tri(b.x + Tmp.v1.x, b.y + Tmp.v1.y, Lines.getStroke() * 1.22f, cwidth * 2f + width / 2f, b.rotation());
Drawf.tri(b.x() + Tmp.v1.x, b.y() + Tmp.v1.y, Lines.getStroke() * 1.22f, cwidth * 2f + width / 2f, b.rotation());
Fill.circle(b.x(), b.y(), 1f * cwidth * b.fout());
for(int i : Mathf.signs){

View File

@ -2,7 +2,7 @@ package mindustry.entities.bullet;
import arc.graphics.*;
import mindustry.content.*;
import mindustry.entities.effect.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.graphics.*;

View File

@ -5,7 +5,6 @@ import arc.graphics.g2d.*;
import arc.math.geom.*;
import arc.util.ArcAnnotate.*;
import mindustry.content.*;
import mindustry.entities.effect.*;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.*;
@ -66,7 +65,7 @@ public class LiquidBulletType extends BulletType{
@Override
public void hit(Bulletc b, float hitx, float hity){
hitEffect.at(liquid.color, hitx, hity);
hitEffect.at(hitx, hity, liquid.color);
Puddle.deposit(world.tileWorld(hitx, hity), liquid, puddleSize);
if(liquid.temperature <= 0.5f && liquid.flammability < 0.3f){

View File

@ -38,17 +38,17 @@ public class MassDriverBolt extends BulletType{
@Override
public void update(Bulletc b){
//data MUST be an instance of DriverBulletData
if(!(b.getData() instanceof DriverBulletData)){
if(!(b.data() instanceof DriverBulletData)){
hit(b);
return;
}
float hitDst = 7f;
DriverBulletData data = (DriverBulletData)b.getData();
DriverBulletData data = (DriverBulletData)b.data();
//if the target is dead, just keep flying until the bullet explodes
if(data.to.isDead()){
if(data.to.dead()){
return;
}
@ -67,7 +67,7 @@ public class MassDriverBolt extends BulletType{
if(Angles.near(angleTo, baseAngle, 2f)){
intersect = true;
//snap bullet position back; this is used for low-FPS situations
b.set(data.to.x + Angles.trnsx(baseAngle, hitDst), data.to.y + Angles.trnsy(baseAngle, hitDst));
b.set(data.to.x() + Angles.trnsx(baseAngle, hitDst), data.to.y() + Angles.trnsy(baseAngle, hitDst));
}
}
@ -85,9 +85,9 @@ public class MassDriverBolt extends BulletType{
public void despawned(Bulletc b){
super.despawned(b);
if(!(b.getData() instanceof DriverBulletData)) return;
if(!(b.data() instanceof DriverBulletData)) return;
DriverBulletData data = (DriverBulletData)b.getData();
DriverBulletData data = (DriverBulletData)b.data();
for(int i = 0; i < data.items.length; i++){
int amountDropped = Mathf.random(0, data.items[i]);

View File

@ -34,7 +34,7 @@ public class MissileBulletType extends BasicBulletType{
}
if(weaveMag > 0){
b.vel().rotate(Mathf.sin(Time.time() + b.id * 4422, weaveScale, weaveMag) * Time.delta());
b.vel().rotate(Mathf.sin(Time.time() + b.id() * 442, weaveScale, weaveMag) * Time.delta());
}
}
}

View File

@ -20,12 +20,12 @@ import mindustry.core.*;
import mindustry.ctype.*;
import mindustry.entities.*;
import mindustry.entities.bullet.*;
import mindustry.entities.effect.*;
import mindustry.entities.units.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.input.*;
import mindustry.net.Administration.*;
import mindustry.net.*;
import mindustry.net.Packets.*;
@ -177,21 +177,12 @@ public class EntityComps{
}
@Component
abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Drawc, Shielderc, Ownerc, Velc, Bulletc{
abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Drawc, Shielderc, Ownerc, Velc, Bulletc, Timerc{
private float lifeScl;
Object data;
BulletType type;
Interval timer = new Interval(6);
public boolean timer(int index, float time){
return timer.get(index, time);
}
@Override
public float getDamage(){
return type.damage;
}
float damage;
@Override
public void add(){
@ -258,8 +249,8 @@ public class EntityComps{
Tile tile = world.ltile(x, y);
if(tile == null) return false;
if(tile.entity != null && tile.entity.collide(this) && type.collides(this, tile) && !tile.entity.dead() && (type.collidesTeam || tile.getTeam() != team())){
if(tile.getTeam() != team()){
if(tile.entity != null && tile.entity.collide(this) && type.collides(this, tile) && !tile.entity.dead() && (type.collidesTeam || tile.team() != team())){
if(tile.team() != team()){
tile.entity.collision(this);
}
@ -295,6 +286,15 @@ public class EntityComps{
}
}
@Component
abstract class TimerComp{
@ReadOnly Interval timer = new Interval(6);
public boolean timer(int index, float time){
return timer.get(index, time);
}
}
@Component
abstract class DamageComp{
abstract float damage();
@ -590,7 +590,7 @@ public class EntityComps{
Tile other = world.ltile(tile.x + point.x, tile.y + point.y);
if(other == null) continue;
if(other.entity == null || !(other.interactable(tile.getTeam()))) continue;
if(other.entity == null || !(other.interactable(tile.team()))) continue;
//add this tile to proximity of nearby tiles
if(!other.entity.proximity().contains(tile, true)){
@ -671,7 +671,7 @@ public class EntityComps{
}
@Component
abstract class PlayerComp implements UnitController, Entityc, Syncc{
abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc{
@Nullable Unitc unit;
@ReadOnly Team team = Team.sharded;
@ -684,6 +684,19 @@ public class EntityComps{
@Nullable String lastText;
float textFadeTime;
public @Nullable Tilec closestCore(){
return state.teams.closestCore(x(), y(), team);
}
public void reset(){
team = state.rules.defaultTeam;
admin = typing = false;
lastText = null;
textFadeTime = 0f;
unit.controller(unit.type().createController());
unit = null;
}
public void update(){
if(unit != null){
x(unit.x());
@ -704,12 +717,16 @@ public class EntityComps{
unit.team(team);
}
boolean dead(){
return unit == null;
}
String uuid(){
return con == null ? "AAAAAAAA" : con.uuid;
return con == null ? "[LOCAL]" : con.uuid;
}
String usid(){
return con == null ? "AAAAAAAA" : con.usid;
return con == null ? "[LOCAL]" : con.usid;
}
void kick(KickReason reason){
@ -801,7 +818,7 @@ public class EntityComps{
}
@Component
abstract class TeamComp implements Posc, Healthc{
abstract class TeamComp implements Posc{
transient float x, y;
Team team = Team.sharded;
@ -944,8 +961,7 @@ public class EntityComps{
private void bullet(Weapon weapon, float x, float y, float angle){
Tmp.v1.trns(angle, 3f);
//TODO create the bullet
//Bullet.create(weapon.bullet, this, getTeam(), x + Tmp.v1.x, y + Tmp.v1.y, angle, (1f - weapon.velocityRnd) + Mathf.random(weapon.velocityRnd));
weapon.bullet.create(this, team(), x + Tmp.v1.x, y + Tmp.v1.y, angle, (1f - weapon.velocityRnd) + Mathf.random(weapon.velocityRnd));
}
}
@ -1202,7 +1218,7 @@ public class EntityComps{
mineTile.worldy() + Mathf.range(tilesize / 2f), core.tile());
}else if(acceptsItem(item)){
//this is clientside, since items are synced anyway
ItemTransfer.transferItemToUnit(item,
InputHandler.transferItemToUnit(item,
mineTile.worldx() + Mathf.range(tilesize / 2f),
mineTile.worldy() + Mathf.range(tilesize / 2f),
this);
@ -1480,6 +1496,16 @@ public class EntityComps{
boolean hasItem(){
return stack.amount > 0;
}
void addItem(Item item){
addItem(item, 1);
}
void addItem(Item item, int amount){
stack.amount = stack.item == item ? stack.amount + amount : amount;
stack.item = item;
stack.amount = Mathf.clamp(stack.amount, 0, itemCapacity());
}
}
@Component
@ -1591,8 +1617,7 @@ public class EntityComps{
return;
}else if(entry.effect.reactsWith(effect)){ //find opposite
StatusEntry.tmp.effect = entry.effect;
//TODO unit cannot be null here
entry.effect.getTransition((mindustry.gen.Unitc)this, effect, entry.time, duration, StatusEntry.tmp);
entry.effect.getTransition((Unitc)this, effect, entry.time, duration, StatusEntry.tmp);
entry.time = StatusEntry.tmp.time;
if(StatusEntry.tmp.effect != entry.effect){
@ -1611,6 +1636,10 @@ public class EntityComps{
statuses.add(entry);
}
boolean isBoss(){
return hasEffect(StatusEffects.boss);
}
boolean isImmune(StatusEffect effect){
return false;
}
@ -1714,7 +1743,7 @@ public class EntityComps{
}
boolean isLocal(){
return this instanceof Unitc && ((Unitc)this).controller() == player || this == player;
return ((Object)this) == player || ((Object)this) instanceof Unitc && ((Unitc)((Object)this)).controller() == player;
}
<T> T as(Class<T> type){

View File

@ -5,12 +5,17 @@ import mindustry.entities.def.EntityComps.*;
public class EntityGroupDefs{
@GroupDef(EntityComp.class)
void all(){
}
@GroupDef(PlayerComp.class)
void player(){
}
@GroupDef(UnitComp.class)
@GroupDef(value = UnitComp.class, spatial = true)
void unit(){
}

View File

@ -1,228 +0,0 @@
package mindustry.entities.effect;
import arc.*;
import mindustry.annotations.Annotations.*;
import arc.struct.*;
import arc.math.*;
import arc.math.geom.*;
import arc.util.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.*;
import java.io.*;
import static mindustry.Vars.*;
public class Fire extends TimedEntity implements SaveTrait, SyncTrait{
private static final IntMap<Fire> map = new IntMap<>();
private static final float baseLifetime = 1000f, spreadChance = 0.05f, fireballChance = 0.07f;
private int loadedPosition = -1;
private Tile tile;
private Block block;
private float baseFlammability = -1, puddleFlammability;
private float lifetime;
/** Deserialization use only! */
public Fire(){
}
@Remote
public static void onRemoveFire(int fid){
fireGroup.removeByID(fid);
}
/** Start a fire on the tile. If there already is a file there, refreshes its lifetime. */
public static void create(Tile tile){
if(net.client() || tile == null) return; //not clientside.
Fire fire = map.get(tile.pos());
if(fire == null){
fire = new Fire();
fire.tile = tile;
fire.lifetime = baseLifetime;
fire.set(tile.worldx(), tile.worldy());
fire.add();
map.put(tile.pos(), fire);
}else{
fire.lifetime = baseLifetime;
fire.time = 0f;
}
}
public static boolean has(int x, int y){
if(!Structs.inBounds(x, y, world.width(), world.height()) || !map.containsKey(Pos.get(x, y))){
return false;
}
Fire fire = map.get(Pos.get(x, y));
return fire.isAdded() && fire.fin() < 1f && fire.tile != null && fire.tile.x == x && fire.tile.y == y;
}
/**
* Attempts to extinguish a fire by shortening its life. If there is no fire here, does nothing.
*/
public static void extinguish(Tile tile, float intensity){
if(tile != null && map.containsKey(tile.pos())){
Fire fire = map.get(tile.pos());
fire.time += intensity * Time.delta();
if(fire.time >= fire.lifetime()){
Events.fire(Trigger.fireExtinguish);
}
}
}
@Override
public TypeID getTypeID(){
return TypeIDs.fire;
}
@Override
public byte version(){
return 0;
}
@Override
public float lifetime(){
return lifetime;
}
@Override
public void update(){
if(Mathf.chance(0.1 * Time.delta())){
Fx.fire.at(x + Mathf.range(4f), y + Mathf.range(4f));
}
if(Mathf.chance(0.05 * Time.delta())){
Fx.fireSmoke.at(x + Mathf.range(4f), y + Mathf.range(4f));
}
if(Mathf.chance(0.001 * Time.delta())){
Sounds.fire.at(this);
}
time = Mathf.clamp(time + Time.delta(), 0, lifetime());
map.put(tile.pos(), this);
if(net.client()){
return;
}
if(time >= lifetime() || tile == null){
remove();
return;
}
Tilec entity = tile.link().entity;
boolean damage = entity != null;
float flammability = baseFlammability + puddleFlammability;
if(!damage && flammability <= 0){
time += Time.delta() * 8;
}
if(baseFlammability < 0 || block != tile.block()){
baseFlammability = tile.block().getFlammability(tile);
block = tile.block();
}
if(damage){
lifetime += Mathf.clamp(flammability / 8f, 0f, 0.6f) * Time.delta();
}
if(flammability > 1f && Mathf.chance(spreadChance * Time.delta() * Mathf.clamp(flammability / 5f, 0.3f, 2f))){
Point2 p = Geometry.d4[Mathf.random(3)];
Tile other = world.tile(tile.x + p.x, tile.y + p.y);
create(other);
if(Mathf.chance(fireballChance * Time.delta() * Mathf.clamp(flammability / 10f))){
Call.createBullet(Bullets.fireball, Team.derelict, x, y, Mathf.random(360f), 1, 1);
}
}
if(Mathf.chance(0.1 * Time.delta())){
Puddle p = Puddle.getPuddle(tile);
if(p != null){
puddleFlammability = p.getFlammability() / 3f;
}else{
puddleFlammability = 0;
}
if(damage){
entity.damage(0.4f);
}
Damage.damageUnits(null, tile.worldx(), tile.worldy(), tilesize, 3f,
unit -> !unit.isFlying() && !unit.isImmune(StatusEffects.burning),
unit -> unit.applyEffect(StatusEffects.burning, 60 * 5));
}
}
@Override
public void writeSave(DataOutput stream) throws IOException{
stream.writeInt(tile.pos());
stream.writeFloat(lifetime);
stream.writeFloat(time);
}
@Override
public void readSave(DataInput stream, byte version) throws IOException{
this.loadedPosition = stream.readInt();
this.lifetime = stream.readFloat();
this.time = stream.readFloat();
add();
}
@Override
public void write(DataOutput data) throws IOException{
data.writeInt(tile.pos());
data.writeFloat(lifetime);
}
@Override
public void read(DataInput data) throws IOException{
int pos = data.readInt();
this.lifetime = data.readFloat();
x = Pos.x(pos) * tilesize;
y = Pos.y(pos) * tilesize;
tile = world.tile(pos);
}
@Override
public void reset(){
loadedPosition = -1;
tile = null;
baseFlammability = -1;
puddleFlammability = 0f;
incrementID();
}
@Override
public void added(){
if(loadedPosition != -1){
map.put(loadedPosition, this);
tile = world.tile(loadedPosition);
set(tile.worldx(), tile.worldy());
}
}
@Override
public void removed(){
if(tile != null){
Call.onRemoveFire(id);
map.remove(tile.pos());
}
}
@Override
public EntityGroup targetGroup(){
return fireGroup;
}
}

View File

@ -1,114 +0,0 @@
package mindustry.entities.effect;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.math.geom.*;
import arc.util.*;
import arc.util.pooling.*;
import mindustry.annotations.Annotations.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.type.*;
import mindustry.world.*;
import static mindustry.Vars.effectGroup;
public class ItemTransfer extends TimedEntity implements DrawTrait{
private Vec2 from = new Vec2();
private Vec2 current = new Vec2();
private Vec2 tovec = new Vec2();
private Item item;
private float seed;
private Position to;
private Runnable done;
public ItemTransfer(){
}
@Remote(called = Loc.server, unreliable = true)
public static void transferItemEffect(Item item, float x, float y, Itemsc to){
if(to == null) return;
create(item, x, y, to, () -> {
});
}
@Remote(called = Loc.server, unreliable = true)
public static void transferItemToUnit(Item item, float x, float y, Itemsc to){
if(to == null) return;
create(item, x, y, to, () -> to.addItem(item));
}
@Remote(called = Loc.server, unreliable = true)
public static void transferItemTo(Item item, int amount, float x, float y, Tile tile){
if(tile == null || tile.entity == null || tile.entity.items() == null) return;
for(int i = 0; i < Mathf.clamp(amount / 3, 1, 8); i++){
Time.run(i * 3, () -> create(item, x, y, tile, () -> {}));
}
tile.entity.items().add(item, amount);
}
public static void create(Item item, float fromx, float fromy, Position to, Runnable done){
ItemTransfer tr = Pools.obtain(ItemTransfer.class, ItemTransfer::new);
tr.item = item;
tr.from.set(fromx, fromy);
tr.to = to;
tr.done = done;
tr.seed = Mathf.range(1f);
tr.add();
}
@Override
public float lifetime(){
return 60;
}
@Override
public void reset(){
super.reset();
item = null;
to = null;
done = null;
from.setZero();
current.setZero();
tovec.setZero();
}
@Override
public void removed(){
if(done != null){
done.run();
}
Pools.free(this);
}
@Override
public void update(){
if(to == null){
remove();
return;
}
super.update();
current.set(from).interpolate(tovec.set(to.getX(), to.getY()), fin(), Interpolation.pow3);
current.add(tovec.set(to.getX(), to.getY()).sub(from).nor().rotate90(1).scl(seed * fslope() * 10f));
set(current.x, current.y);
}
@Override
public void draw(){
Lines.stroke(fslope() * 2f, Pal.accent);
Lines.circle(x, y, fslope() * 2f);
Draw.color(item.color);
Fill.circle(x, y, fslope() * 1.5f);
Draw.reset();
}
@Override
public EntityGroup targetGroup(){
return effectGroup;
}
}

View File

@ -1,154 +0,0 @@
package mindustry.entities.effect;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.math.geom.*;
import arc.struct.*;
import arc.util.pooling.*;
import mindustry.annotations.Annotations.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.world.*;
import static mindustry.Vars.*;
//TODO lightning should be an effect with custom logic + bullet with custom init logic
public class Lightning extends TimedEntity implements DrawTrait, TimeTrait{
public static final float lifetime = 10f;
private static final Rand random = new Rand();
private static final Rect rect = new Rect();
private static final Array<Unitc> entities = new Array<>();
private static final IntSet hit = new IntSet();
private static final int maxChain = 8;
private static final float hitRange = 30f;
private static int lastSeed = 0;
private Array<Vec2> lines = new Array<>();
private Color color = Pal.lancerLaser;
/** For pooling use only. Do not call directly! */
public Lightning(){
}
/** Create a lighting branch at a location. Use Team.none to damage everyone. */
public static void create(Team team, Color color, float damage, float x, float y, float targetAngle, int length){
Call.createLighting(nextSeed(), team, color, damage, x, y, targetAngle, length);
}
public static int nextSeed(){
return lastSeed++;
}
/** Do not invoke! */
@Remote(called = Loc.server, unreliable = true)
public static void createLighting(int seed, Team team, Color color, float damage, float x, float y, float rotation, int length){
Lightning l = Pools.obtain(Lightning.class, Lightning::new);
Float dmg = damage;
l.x = x;
l.y = y;
l.color = color;
l.add();
random.setSeed(seed);
hit.clear();
boolean[] bhit = {false};
for(int i = 0; i < length / 2; i++){
Bullet.create(Bullets.damageLightning, l, team, x, y, 0f, 1f, 1f, dmg);
l.lines.add(new Vec2(x + Mathf.range(3f), y + Mathf.range(3f)));
if(l.lines.size > 1){
bhit[0] = false;
Position from = l.lines.get(l.lines.size - 2);
Position to = l.lines.get(l.lines.size - 1);
world.raycastEach(world.toTile(from.getX()), world.toTile(from.getY()), world.toTile(to.getX()), world.toTile(to.getY()), (wx, wy) -> {
Tile tile = world.ltile(wx, wy);
if(tile != null && tile.block().insulated){
bhit[0] = true;
//snap it instead of removing
l.lines.get(l.lines.size -1).set(wx * tilesize, wy * tilesize);
return true;
}
return false;
});
if(bhit[0]) break;
}
rect.setSize(hitRange).setCenter(x, y);
entities.clear();
if(hit.size < maxChain){
Units.nearbyEnemies(team, rect, u -> {
if(!hit.contains(u.getID())){
entities.add(u);
}
});
}
Unitc furthest = Geometry.findFurthest(x, y, entities);
if(furthest != null){
hit.add(furthest.getID());
x = furthest.x;
y = furthest.y;
}else{
rotation += random.range(20f);
x += Angles.trnsx(rotation, hitRange / 2f);
y += Angles.trnsy(rotation, hitRange / 2f);
}
}
}
@Override
public float lifetime(){
return lifetime;
}
@Override
public void reset(){
super.reset();
color = Pal.lancerLaser;
lines.clear();
}
@Override
public void removed(){
super.removed();
Pools.free(this);
}
@Override
public void draw(){
Lines.stroke(3f * fout());
Draw.color(color, Color.white, fin());
Lines.beginLine();
Lines.linePoint(x, y);
for(Position p : lines){
Lines.linePoint(p.getX(), p.getY());
}
Lines.endLine();
int i = 0;
for(Position p : lines){
Fill.square(p.getX(), p.getY(), (5f - (float)i++ / lines.size * 2f) * fout(), 45);
}
Draw.reset();
}
@Override
public EntityGroup targetGroup(){
return bulletGroup;
}
}

View File

@ -1,320 +0,0 @@
package mindustry.entities.effect;
import mindustry.annotations.Annotations.*;
import arc.struct.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.math.geom.*;
import arc.util.*;
import arc.util.pooling.Pool.*;
import arc.util.pooling.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.*;
import java.io.*;
import static mindustry.Vars.*;
public class Puddle extends SolidEntity implements SaveTrait, Poolable, DrawTrait, SyncTrait{
private static final IntMap<Puddle> map = new IntMap<>();
private static final float maxLiquid = 70f;
private static final int maxGeneration = 2;
private static final Color tmp = new Color();
private static final Rect rect = new Rect();
private static final Rect rect2 = new Rect();
private static int seeds;
private int loadedPosition = -1;
private float updateTime;
private float lastRipple;
private Tile tile;
private Liquid liquid;
private float amount, targetAmount;
private float accepting;
private byte generation;
/** Deserialization use only! */
public Puddle(){
}
/** Deposists a puddle between tile and source. */
public static void deposit(Tile tile, Tile source, Liquid liquid, float amount){
deposit(tile, source, liquid, amount, 0);
}
/** Deposists a puddle at a tile. */
public static void deposit(Tile tile, Liquid liquid, float amount){
deposit(tile, tile, liquid, amount, 0);
}
/** Returns the puddle on the specified tile. May return null. */
public static Puddle getPuddle(Tile tile){
return map.get(tile.pos());
}
private static void deposit(Tile tile, Tile source, Liquid liquid, float amount, int generation){
if(tile == null) return;
if(tile.floor().isLiquid && !canStayOn(liquid, tile.floor().liquidDrop)){
reactPuddle(tile.floor().liquidDrop, liquid, amount, tile,
(tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f);
Puddle p = map.get(tile.pos());
if(generation == 0 && p != null && p.lastRipple <= Time.time() - 40f){
Fx.ripple.at(tile.floor().liquidDrop.color,
(tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f);
p.lastRipple = Time.time();
}
return;
}
Puddle p = map.get(tile.pos());
if(p == null){
if(net.client()) return; //not clientside.
Puddle puddle = Pools.obtain(Puddle.class, Puddle::new);
puddle.tile = tile;
puddle.liquid = liquid;
puddle.amount = amount;
puddle.generation = (byte)generation;
puddle.set((tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f);
puddle.add();
map.put(tile.pos(), puddle);
}else if(p.liquid == liquid){
p.accepting = Math.max(amount, p.accepting);
if(generation == 0 && p.lastRipple <= Time.time() - 40f && p.amount >= maxLiquid / 2f){
Fx.ripple.at(p.liquid.color, (tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f);
p.lastRipple = Time.time();
}
}else{
p.amount += reactPuddle(p.liquid, liquid, amount, p.tile, p.x, p.y);
}
}
/**
* Returns whether the first liquid can 'stay' on the second one.
* Currently, the only place where this can happen is oil on water.
*/
private static boolean canStayOn(Liquid liquid, Liquid other){
return liquid == Liquids.oil && other == Liquids.water;
}
/** Reacts two liquids together at a location. */
private static float reactPuddle(Liquid dest, Liquid liquid, float amount, Tile tile, float x, float y){
if((dest.flammability > 0.3f && liquid.temperature > 0.7f) ||
(liquid.flammability > 0.3f && dest.temperature > 0.7f)){ //flammable liquid + hot liquid
Fire.create(tile);
if(Mathf.chance(0.006 * amount)){
Call.createBullet(Bullets.fireball, Team.derelict, x, y, Mathf.random(360f), 1f, 1f);
}
}else if(dest.temperature > 0.7f && liquid.temperature < 0.55f){ //cold liquid poured onto hot puddle
if(Mathf.chance(0.5f * amount)){
Fx.steam.at(x, y);
}
return -0.1f * amount;
}else if(liquid.temperature > 0.7f && dest.temperature < 0.55f){ //hot liquid poured onto cold puddle
if(Mathf.chance(0.8f * amount)){
Fx.steam.at(x, y);
}
return -0.4f * amount;
}
return 0f;
}
@Remote(called = Loc.server)
public static void onPuddleRemoved(int puddleid){
puddleGroup.removeByID(puddleid);
}
public float getFlammability(){
return liquid.flammability * amount;
}
@Override
public TypeID getTypeID(){
return TypeIDs.puddle;
}
@Override
public byte version(){
return 0;
}
@Override
public void hitbox(Rect rect){
rect.setCenter(x, y).setSize(tilesize);
}
@Override
public void hitboxTile(Rect rect){
rect.setCenter(x, y).setSize(0f);
}
@Override
public void update(){
//no updating happens clientside
if(net.client()){
amount = Mathf.lerpDelta(amount, targetAmount, 0.15f);
}else{
//update code
float addSpeed = accepting > 0 ? 3f : 0f;
amount -= Time.delta() * (1f - liquid.viscosity) / (5f + addSpeed);
amount += accepting;
accepting = 0f;
if(amount >= maxLiquid / 1.5f && generation < maxGeneration){
float deposited = Math.min((amount - maxLiquid / 1.5f) / 4f, 0.3f) * Time.delta();
for(Point2 point : Geometry.d4){
Tile other = world.tile(tile.x + point.x, tile.y + point.y);
if(other != null && other.block() == Blocks.air){
deposit(other, tile, liquid, deposited, generation + 1);
amount -= deposited / 2f; //tweak to speed up/slow down puddle propagation
}
}
}
amount = Mathf.clamp(amount, 0, maxLiquid);
if(amount <= 0f){
Call.onPuddleRemoved(getID());
}
}
//effects-only code
if(amount >= maxLiquid / 2f && updateTime <= 0f){
Units.nearby(rect.setSize(Mathf.clamp(amount / (maxLiquid / 1.5f)) * 10f).setCenter(x, y), unit -> {
if(unit.isFlying()) return;
unit.hitbox(rect2);
if(!rect.overlaps(rect2)) return;
unit.applyEffect(liquid.effect, 60 * 2);
if(unit.vel().len() > 0.1){
Fx.ripple.at(liquid.color, unit.x, unit.y);
}
});
if(liquid.temperature > 0.7f && (tile.link().entity != null) && Mathf.chance(0.3 * Time.delta())){
Fire.create(tile);
}
updateTime = 20f;
}
updateTime -= Time.delta();
}
@Override
public void draw(){
seeds = id;
boolean onLiquid = tile.floor().isLiquid;
float f = Mathf.clamp(amount / (maxLiquid / 1.5f));
float smag = onLiquid ? 0.8f : 0f;
float sscl = 20f;
Draw.color(tmp.set(liquid.color).shiftValue(-0.05f));
Fill.circle(x + Mathf.sin(Time.time() + seeds * 532, sscl, smag), y + Mathf.sin(Time.time() + seeds * 53, sscl, smag), f * 8f);
Angles.randLenVectors(id, 3, f * 6f, (ex, ey) -> {
Fill.circle(x + ex + Mathf.sin(Time.time() + seeds * 532, sscl, smag),
y + ey + Mathf.sin(Time.time() + seeds * 53, sscl, smag), f * 5f);
seeds++;
});
Draw.color();
if(liquid.lightColor.a > 0.001f && f > 0){
Color color = liquid.lightColor;
float opacity = color.a * f;
renderer.lights.add(tile.drawx(), tile.drawy(), 30f * f, color, opacity * 0.8f);
}
}
@Override
public float drawSize(){
return 20;
}
@Override
public void writeSave(DataOutput stream) throws IOException{
stream.writeInt(tile.pos());
stream.writeFloat(x);
stream.writeFloat(y);
stream.writeByte(liquid.id);
stream.writeFloat(amount);
stream.writeByte(generation);
}
@Override
public void readSave(DataInput stream, byte version) throws IOException{
this.loadedPosition = stream.readInt();
this.x = stream.readFloat();
this.y = stream.readFloat();
this.liquid = content.liquid(stream.readByte());
this.amount = stream.readFloat();
this.generation = stream.readByte();
add();
}
@Override
public void reset(){
loadedPosition = -1;
tile = null;
liquid = null;
amount = 0;
generation = 0;
accepting = 0;
}
@Override
public void added(){
if(loadedPosition != -1){
map.put(loadedPosition, this);
tile = world.tile(loadedPosition);
}
}
@Override
public void removed(){
if(tile != null){
map.remove(tile.pos());
}
reset();
}
@Override
public void write(DataOutput data) throws IOException{
data.writeFloat(x);
data.writeFloat(y);
data.writeByte(liquid.id);
data.writeShort((short)(amount * 4));
data.writeInt(tile.pos());
}
@Override
public void read(DataInput data) throws IOException{
x = data.readFloat();
y = data.readFloat();
liquid = content.liquid(data.readByte());
targetAmount = data.readShort() / 4f;
int pos = data.readInt();
tile = world.tile(pos);
map.put(pos, this);
}
@Override
public EntityGroup targetGroup(){
return puddleGroup;
}
}

View File

@ -1,4 +1,17 @@
package mindustry.entities.units;
public class AIController extends UnitController{
import mindustry.gen.*;
public class AIController implements UnitController{
protected Unitc unit;
@Override
public void unit(Unitc unit){
this.unit = unit;
}
@Override
public Unitc unit(){
return unit;
}
}

View File

@ -1,28 +0,0 @@
package mindustry.game;
import arc.Core;
/** Presets for time between waves. Currently unused.*/
public enum Difficulty{
easy(1.4f),
normal(1f),
hard(0.5f),
insane(0.25f);
/** Multiplier of the time between waves. */
public final float waveTime;
private String value;
Difficulty(float waveTime){
this.waveTime = waveTime;
}
@Override
public String toString(){
if(value == null){
value = Core.bundle.get("setting.difficulty." + name());
}
return value;
}
}

View File

@ -315,7 +315,7 @@ public class Schematics implements Loadable{
for(int cy = y; cy <= y2; cy++){
Tile linked = world.ltile(cx, cy);
if(linked != null && linked.entity != null && linked.entity.block.isVisible() && !(linked.block() instanceof BuildBlock)){
if(linked != null && linked.entity != null && linked.entity.block().isVisible() && !(linked.block() instanceof BuildBlock)){
int top = linked.block().size/2;
int bot = linked.block().size % 2 == 1 ? -linked.block().size/2 : -(linked.block().size - 1)/2;
minx = Math.min(linked.x + bot, minx);
@ -344,7 +344,7 @@ public class Schematics implements Loadable{
Tile tile = world.ltile(cx, cy);
if(tile != null && tile.entity != null && !counted.contains(tile.pos()) && !(tile.block() instanceof BuildBlock)
&& (tile.entity.block.isVisible() || (tile.entity.block instanceof CoreBlock && Core.settings.getBool("coreselect")))){
&& (tile.entity.block().isVisible() || (tile.entity.block() instanceof CoreBlock && Core.settings.getBool("coreselect")))){
int config = tile.entity.config();
if(tile.block().posConfig){
config = Pos.get(Pos.x(config) + offsetX, Pos.y(config) + offsetY);

View File

@ -5,6 +5,7 @@ import arc.math.geom.*;
import arc.struct.*;
import arc.util.ArcAnnotate.*;
import arc.util.*;
import mindustry.gen.*;
import mindustry.world.blocks.storage.CoreBlock.*;
import static mindustry.Vars.*;

View File

@ -162,7 +162,7 @@ public class Tutorial{
},
withdraw(() -> event("withdraw")){
void begin(){
state.teams.playerCores().first().items.add(Items.copper, 10);
state.teams.playerCores().first().items().add(Items.copper, 10);
}
},
deposit(() -> event("deposit")),
@ -242,8 +242,8 @@ public class Tutorial{
static void placeBlocks(){
Tilec core = state.teams.playerCores().first();
for(int i = 0; i < blocksToBreak; i++){
world.ltile(core.tile.x + blockOffset, core.tile.y + i).remove();
world.tile(core.tile.x + blockOffset, core.tile.y + i).setBlock(Blocks.scrapWall, state.rules.defaultTeam);
world.ltile(core.tile().x + blockOffset, core.tile().y + i).remove();
world.tile(core.tile().x + blockOffset, core.tile().y + i).setBlock(Blocks.scrapWall, state.rules.defaultTeam);
}
}
@ -251,7 +251,7 @@ public class Tutorial{
Tilec core = state.teams.playerCores().first();
for(int i = 0; i < blocksToBreak; i++){
if(world.tile(core.tile.x + blockOffset, core.tile.y + i).block() == Blocks.scrapWall){
if(world.tile(core.tile().x + blockOffset, core.tile().y + i).block() == Blocks.scrapWall){
return false;
}
}
@ -271,7 +271,7 @@ public class Tutorial{
}
static int item(Item item){
return state.rules.defaultTeam.data().noCores() ? 0 : state.rules.defaultTeam.core().items.get(item);
return state.rules.defaultTeam.data().noCores() ? 0 : state.rules.defaultTeam.core().items().get(item);
}
static boolean toggled(String name){

View File

@ -275,7 +275,7 @@ public class BlockRenderer implements Disposable{
if(request.tile.entity != null && request.tile.entity.damaged()){
block.drawCracks(request.tile);
}
if(block.synthetic() && request.tile.getTeam() != player.team()){
if(block.synthetic() && request.tile.team() != player.team()){
block.drawTeam(request.tile);
}

View File

@ -1,23 +1,20 @@
package mindustry.graphics;
import arc.Core;
import arc.struct.Array;
import arc.func.Floatc2;
import arc.graphics.Camera;
import arc.graphics.Color;
import arc.*;
import arc.func.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.graphics.gl.FrameBuffer;
import arc.graphics.gl.*;
import arc.math.*;
import arc.scene.ui.layout.Scl;
import arc.scene.ui.layout.*;
import arc.struct.*;
import arc.util.*;
import arc.util.noise.RidgedPerlin;
import arc.util.noise.Simplex;
import mindustry.content.Blocks;
import mindustry.content.UnitTypes;
import mindustry.ui.Cicon;
import arc.util.noise.*;
import mindustry.content.*;
import mindustry.type.*;
import mindustry.ui.*;
import mindustry.world.*;
import mindustry.world.blocks.Floor;
import mindustry.world.blocks.OreBlock;
import mindustry.world.blocks.*;
import static mindustry.Vars.*;
@ -33,7 +30,7 @@ public class MenuRenderer implements Disposable{
private float time = 0f;
private float flyerRot = 45f;
private int flyers = Mathf.chance(0.2) ? Mathf.random(35) : Mathf.random(15);
private UnitType flyerType = Structs.select(UnitTypes.wraith, UnitTypes.wraith, UnitTypes.ghoul, UnitTypes.phantom, UnitTypes.phantom, UnitTypes.revenant);
private UnitDef flyerType = Structs.select(UnitTypes.wraith, UnitTypes.wraith, UnitTypes.ghoul, UnitTypes.phantom, UnitTypes.phantom, UnitTypes.revenant);
public MenuRenderer(){
Time.mark();

View File

@ -76,7 +76,7 @@ public class MinimapRenderer implements Disposable{
updateUnitArray();
}else{
units.clear();
Units.all(units::add);
Groups.unit.each(units::add);
}
float sz = baseSize * zoom;
@ -88,20 +88,19 @@ public class MinimapRenderer implements Disposable{
rect.set((dx - sz) * tilesize, (dy - sz) * tilesize, sz * 2 * tilesize, sz * 2 * tilesize);
for(Unitc unit : units){
if(unit.isDead()) continue;
float rx = !withLabels ? (unit.x - rect.x) / rect.width * w : unit.x / (world.width() * tilesize) * w;
float ry = !withLabels ? (unit.y - rect.y) / rect.width * h : unit.y / (world.height() * tilesize) * h;
float rx = !withLabels ? (unit.x() - rect.x) / rect.width * w : unit.x() / (world.width() * tilesize) * w;
float ry = !withLabels ? (unit.y() - rect.y) / rect.width * h : unit.y() / (world.height() * tilesize) * h;
Draw.mixcol(unit.getTeam().color, 1f);
Draw.mixcol(unit.team().color, 1f);
float scale = Scl.scl(1f) / 2f * scaling * 32f;
Draw.rect(unit.getIconRegion(), x + rx, y + ry, scale, scale, unit.rotation - 90);
Draw.rect(unit.type().region, x + rx, y + ry, scale, scale, unit.rotation() - 90);
Draw.reset();
if(withLabels && unit instanceof Playerc){
Playerc pl = (Playerc) unit;
if(!pl.isLocal){
if(!pl.isLocal()){
// Only display names for other players.
drawLabel(x + rx, y + ry, pl.name, unit.getTeam().color);
drawLabel(x + rx, y + ry, pl.name(), unit.team().color);
}
}
}
@ -162,7 +161,7 @@ public class MinimapRenderer implements Disposable{
if(bc != 0){
return bc;
}
return Tmp.c1.set(MapIO.colorFor(tile.floor(), tile.block(), tile.overlay(), tile.getTeam())).mul(tile.block().cacheLayer == CacheLayer.walls ? 1f - tile.rotation() / 4f : 1f).rgba();
return Tmp.c1.set(MapIO.colorFor(tile.floor(), tile.block(), tile.overlay(), tile.team())).mul(tile.block().cacheLayer == CacheLayer.walls ? 1f - tile.rotation() / 4f : 1f).rgba();
}
@Override

View File

@ -8,7 +8,6 @@ import arc.math.geom.*;
import arc.util.*;
import mindustry.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.input.*;
import mindustry.type.*;
@ -36,12 +35,12 @@ public class OverlayRenderer{
public void drawTop(){
if(Core.settings.getBool("indicators")){
for(Playerc player : Groups.player.all()){
for(Playerc player : Groups.player){
if(Vars.player != player && Vars.player.team() == player.team()){
if(!rect.setSize(Core.camera.width * 0.9f, Core.camera.height * 0.9f)
.setCenter(Core.camera.position.x, Core.camera.position.y).contains(player.x, player.y)){
.setCenter(Core.camera.position.x, Core.camera.position.y).contains(player.x(), player.y())){
Tmp.v1.set(player.x, player.y).sub(Core.camera.position.x, Core.camera.position.y).setLength(indicatorLength);
Tmp.v1.set(player.x(), player.y()).sub(Core.camera.position.x, Core.camera.position.y).setLength(indicatorLength);
Lines.stroke(2f, player.team().color);
Lines.lineAngle(Core.camera.position.x + Tmp.v1.x, Core.camera.position.y + Tmp.v1.y, Tmp.v1.angle(), 4f);
@ -50,15 +49,15 @@ public class OverlayRenderer{
}
}
Units.all(unit -> {
if(unit != player && unit.team() != player.team() && !rect.setSize(Core.camera.width * 0.9f, Core.camera.height * 0.9f).setCenter(Core.camera.position.x, Core.camera.position.y).contains(unit.x, unit.y)){
Tmp.v1.set(unit.x, unit.y).sub(Core.camera.position.x, Core.camera.position.y).setLength(indicatorLength);
Groups.unit.each(unit -> {
if(unit != player && unit.team() != player.team() && !rect.setSize(Core.camera.width * 0.9f, Core.camera.height * 0.9f).setCenter(Core.camera.position.x, Core.camera.position.y).contains(unit.x(), unit.y())){
Tmp.v1.set(unit.x(), unit.y()).sub(Core.camera.position.x, Core.camera.position.y).setLength(indicatorLength);
Lines.stroke(1f, unit.team().color);
Lines.lineAngle(Core.camera.position.x + Tmp.v1.x, Core.camera.position.y + Tmp.v1.y, Tmp.v1.angle(), 3f);
Draw.reset();
}
});
Lines.stroke(1f, unit.team().color);
Lines.lineAngle(Core.camera.position.x + Tmp.v1.x, Core.camera.position.y + Tmp.v1.y, Tmp.v1.angle(), 3f);
Draw.reset();
}
});
if(ui.hudfrag.blockfrag.currentCategory == Category.upgrade){
for(Tile mechpad : indexer.getAllied(player.team(), BlockFlag.mechPad)){
@ -98,9 +97,9 @@ public class OverlayRenderer{
float dst = core.dst(player);
if(dst < state.rules.enemyCoreBuildRadius * 2.2f){
Draw.color(Color.darkGray);
Lines.circle(core.x, core.y - 2, state.rules.enemyCoreBuildRadius);
Draw.color(Pal.accent, core.getTeam().color, 0.5f + Mathf.absin(Time.time(), 10f, 0.5f));
Lines.circle(core.x, core.y, state.rules.enemyCoreBuildRadius);
Lines.circle(core.x(), core.y() - 2, state.rules.enemyCoreBuildRadius);
Draw.color(Pal.accent, core.team().color, 0.5f + Mathf.absin(Time.time(), 10f, 0.5f));
Lines.circle(core.x(), core.y(), state.rules.enemyCoreBuildRadius);
}
});
}
@ -109,7 +108,7 @@ public class OverlayRenderer{
Draw.color(Color.gray, Color.lightGray, Mathf.absin(Time.time(), 8f, 1f));
for(Tile tile : spawner.getGroundSpawns()){
if(tile.withinDst(player.x, player.y, state.rules.dropZoneRadius + spawnerMargin)){
if(tile.withinDst(player.x(), player.y(), state.rules.dropZoneRadius + spawnerMargin)){
Draw.alpha(Mathf.clamp(1f - (player.dst(tile) - state.rules.dropZoneRadius) / spawnerMargin));
Lines.dashCircle(tile.worldx(), tile.worldy(), state.rules.dropZoneRadius);
}
@ -122,7 +121,7 @@ public class OverlayRenderer{
Vec2 vec = Core.input.mouseWorld(input.getMouseX(), input.getMouseY());
Tile tile = world.ltileWorld(vec.x, vec.y);
if(tile != null && tile.block() != Blocks.air && tile.getTeam() == player.team()){
if(tile != null && tile.block() != Blocks.air && tile.team() == player.team()){
tile.block().drawSelect(tile);
if(Core.input.keyDown(Binding.rotateplaced) && tile.block().rotate && tile.interactable(player.team())){
@ -138,13 +137,13 @@ public class OverlayRenderer{
if(input.isDroppingItem()){
Vec2 v = Core.input.mouseWorld(input.getMouseX(), input.getMouseY());
float size = 8;
Draw.rect(player.item().item.icon(Cicon.medium), v.x, v.y, size, size);
Draw.rect(player.unit().item().icon(Cicon.medium), v.x, v.y, size, size);
Draw.color(Pal.accent);
Lines.circle(v.x, v.y, 6 + Mathf.absin(Time.time(), 5f, 1f));
Draw.reset();
Tile tile = world.ltileWorld(v.x, v.y);
if(tile != null && tile.interactable(player.team()) && tile.block().acceptStack(player.item().item, player.item().amount, tile, player) > 0){
if(tile != null && tile.interactable(player.team()) && tile.block().acceptStack(player.unit().item(), player.unit().stack().amount, tile, player.unit()) > 0){
Lines.stroke(3f, Pal.gray);
Lines.square(tile.drawx(), tile.drawy(), tile.block().size * tilesize / 2f + 3 + Mathf.absin(Time.time(), 5f, 1f));
Lines.stroke(1f, Pal.place);

View File

@ -1,16 +1,13 @@
package mindustry.graphics;
import arc.Core;
import arc.graphics.Blending;
import arc.graphics.Texture.TextureFilter;
import arc.graphics.g2d.Draw;
import arc.graphics.gl.FrameBuffer;
import arc.util.Disposable;
import mindustry.gen.*;
import arc.*;
import arc.graphics.*;
import arc.graphics.Texture.*;
import arc.graphics.g2d.*;
import arc.graphics.gl.*;
import arc.util.*;
import static arc.Core.camera;
import static arc.Core.graphics;
import static mindustry.Groups.player;
import static arc.Core.*;
import static mindustry.Vars.renderer;
public class Pixelator implements Disposable{
@ -55,7 +52,8 @@ public class Pixelator implements Disposable{
Draw.rect(Draw.wrap(buffer.getTexture()), Core.camera.position.x, Core.camera.position.y, Core.camera.width, -Core.camera.height);
Draw.blend();
Groups.player.draw(p -> !p.isDead(), Playerc::drawName);
//TODO implement drawing functions, maybe
//Groups.player.draw(p -> !p.isDead(), Playerc::drawName);
Core.camera.position.set(px, py);
Core.settings.put("animatedwater", hadWater);

View File

@ -17,7 +17,6 @@ import arc.util.*;
import mindustry.annotations.Annotations.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.entities.effect.*;
import mindustry.gen.*;
import mindustry.entities.units.*;
import mindustry.game.EventType.*;
@ -67,6 +66,34 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
//methods to override
@Remote(called = Loc.server, unreliable = true)
public static <T extends Posc & Itemsc> void transferItemEffect(Item item, float x, float y, T to){
if(to == null) return;
createItemTransfer(item, x, y, to, null);
}
@Remote(called = Loc.server, unreliable = true)
public static <T extends Posc & Itemsc> void transferItemToUnit(Item item, float x, float y, T to){
if(to == null) return;
createItemTransfer(item, x, y, to, () -> to.addItem(item));
}
@Remote(called = Loc.server, unreliable = true)
public static void transferItemTo(Item item, int amount, float x, float y, Tile tile){
if(tile == null || tile.entity == null || tile.entity.items() == null) return;
for(int i = 0; i < Mathf.clamp(amount / 3, 1, 8); i++){
Time.run(i * 3, () -> createItemTransfer(item, x, y, tile, () -> {}));
}
tile.entity.items().add(item, amount);
}
public static void createItemTransfer(Item item, float x, float y, Position to, Runnable done){
Fx.itemTransfer.at(x, y, 0, item.color, to);
if(done != null){
Time.run(Fx.itemTransfer.lifetime, done);
}
}
@Remote(variants = Variant.one)
public static void removeQueueBlock(int x, int y, boolean breaking){
player.removeRequest(x, y, breaking);
@ -1052,7 +1079,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
if(target == null){
isShooting = false;
if(Core.settings.getBool("autotarget")){
target = Units.closestTarget(team, x, y, mech.range, u -> u.team() != Team.derelict, u -> u.getTeam() != Team.derelict);
target = Units.closestTarget(team, x, y, mech.range, u -> u.team() != Team.derelict, u -> u.team() != Team.derelict);
if(mech.canHeal && target == null){
target = Geometry.findClosest(x, y, indexer.getDamaged(Team.sharded));

View File

@ -75,11 +75,11 @@ public class MobileInput extends InputHandler implements GestureListener{
}else{
Tile tile = world.ltileWorld(x, y);
if(tile != null && tile.synthetic() && player.team().isEnemy(tile.getTeam())){
if(tile != null && tile.synthetic() && player.team().isEnemy(tile.team())){
Tilec entity = tile.entity;
player.setMineTile(null);
player.target = entity;
}else if(tile != null && player.mech.canHeal && tile.entity != null && tile.getTeam() == player.team() && tile.entity.damaged()){
}else if(tile != null && player.mech.canHeal && tile.entity != null && tile.team() == player.team() && tile.entity.damaged()){
player.setMineTile(null);
player.target = tile.entity;
}

View File

@ -81,7 +81,7 @@ public class MapIO{
@Override
public void setBlock(Block type){
super.setBlock(type);
int c = colorFor(Blocks.air, block(), Blocks.air, getTeam());
int c = colorFor(Blocks.air, block(), Blocks.air, team());
if(c != black){
walls.draw(x, floors.getHeight() - 1 - y, c);
floors.draw(x, floors.getHeight() - 1 - y + 1, shade);
@ -138,7 +138,7 @@ public class MapIO{
for(int x = 0; x < pixmap.getWidth(); x++){
for(int y = 0; y < pixmap.getHeight(); y++){
Tile tile = tiles.getn(x, y);
pixmap.draw(x, pixmap.getHeight() - 1 - y, colorFor(tile.floor(), tile.block(), tile.overlay(), tile.getTeam()));
pixmap.draw(x, pixmap.getHeight() - 1 - y, colorFor(tile.floor(), tile.block(), tile.overlay(), tile.team()));
}
}
return pixmap;

View File

@ -6,6 +6,7 @@ import mindustry.ctype.*;
import mindustry.entities.bullet.*;
import mindustry.entities.units.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.net.Administration.*;
import mindustry.net.Packets.*;
import mindustry.type.*;
@ -20,6 +21,16 @@ import static mindustry.Vars.*;
@SuppressWarnings("unused")
public class TypeIO{
@WriteClass(Entityc.class)
public static void writeEntity(ByteBuffer buffer, Entityc entity){
buffer.putInt(entity == null ? -1 : entity.id());
}
@ReadClass(Entityc.class)
public static <T extends Entityc> T readEntity(ByteBuffer buffer){
return (T)Groups.all.getByID(buffer.getInt());
}
@WriteClass(Tile.class)
public static void writeTile(ByteBuffer buffer, Tile tile){
buffer.putInt(tile == null ? Pos.get(-1, -1) : tile.pos());

View File

@ -1,7 +1,6 @@
package mindustry.io.versions;
import arc.func.Prov;
import mindustry.entities.effect.*;
import mindustry.gen.*;
import mindustry.entities.type.base.*;

View File

@ -3,7 +3,6 @@ package mindustry.io.versions;
import mindustry.ctype.ContentType;
import mindustry.entities.*;
import mindustry.io.*;
import mindustry.type.TypeID;
import java.io.*;

View File

@ -23,7 +23,7 @@ public class CoreSpawnFilter extends GenerateFilter{
public void apply(Tiles tiles, GenerateInput in){
IntArray spawns = new IntArray();
for(Tile tile : tiles){
if(tile.getTeam() == state.rules.defaultTeam && tile.block() instanceof CoreBlock){
if(tile.team() == state.rules.defaultTeam && tile.block() instanceof CoreBlock){
spawns.add(tile.pos());
}
}

View File

@ -68,7 +68,7 @@ public class MapGenerator extends Generator{
});
}
if(tile.block() instanceof CoreBlock && tile.getTeam() == state.rules.defaultTeam){
if(tile.block() instanceof CoreBlock && tile.team() == state.rules.defaultTeam){
schematics.placeLoadout(loadout, tile.x, tile.y);
anyCores = true;
}

View File

@ -1,18 +0,0 @@
package mindustry.type;
import arc.func.*;
import mindustry.ctype.*;
import mindustry.ctype.ContentType;
public class TypeID extends MappableContent{
public final Prov<? extends TypeTrait> constructor;
public TypeID(String name, Prov<? extends TypeTrait> constructor){
super(name);
this.constructor = constructor;
}
@Override
public ContentType getContentType(){
return ContentType.typeid;
}
}

View File

@ -5,15 +5,12 @@ import arc.audio.*;
import arc.func.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.scene.ui.layout.*;
import arc.struct.*;
import arc.util.ArcAnnotate.*;
import arc.util.*;
import mindustry.annotations.Annotations.*;
import mindustry.ctype.*;
import mindustry.entities.type.base.*;
import mindustry.game.*;
import mindustry.entities.units.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.ui.*;
@ -21,9 +18,7 @@ import mindustry.ui.*;
//TODO change to UnitType or Shell or something
public class UnitDef extends UnlockableContent{
//TODO implement
public @NonNull Prov<? extends Unitc> constructor = () -> this.flying ? new FlyingUnit() : new GroundUnit();
public TypeID typeID;
public @NonNull Prov<? extends UnitController> defaultController = AIController::new;
public boolean flying;
public float speed = 1.1f, boostSpeed = 0.75f, rotateSpeed = 0.2f, baseRotateSpeed = 0.1f;
public float drag = 0.3f, mass = 1f, accel = 0.1f;
@ -52,15 +47,10 @@ public class UnitDef extends UnlockableContent{
public UnitDef(String name){
super(name);
//TODO replace with the sane constructor
typeID = new TypeID(name, constructor);
}
public Unitc create(Team team){
Unitc unit = constructor.get();
unit.init(this, team);
return unit;
public UnitController createController(){
return defaultController.get();
}
@Override
@ -93,50 +83,4 @@ public class UnitDef extends UnlockableContent{
public ContentType getContentType(){
return ContentType.unit;
}
//TODO remove methods below!
public void update(Unitc player){
}
public void draw(Unitc player){
}
public void drawStats(Unitc player){
if(drawCell){
float health = player.healthf();
Draw.color(Color.black, player.team().color, health + Mathf.absin(Time.time(), health * 5f, 1f - health));
Draw.rect(player.getPowerCellRegion(),
player.x + Angles.trnsx(player.rotation, cellOffsetY, cellOffsetX),
player.y + Angles.trnsy(player.rotation, cellOffsetY, cellOffsetX),
player.rotation - 90);
Draw.reset();
}
if(drawItems){
//player.drawBackItems(0f, true);
}
}
public float getExtraArmor(Unitc player){
return 0f;
}
//TODO remove
public float spreadX(Unitc player){
return 0f;
}
//TODO remove
public float getRotationAlpha(Unitc player){
return 1f;
}
public boolean canShoot(Unitc player){
return true;
}
public void onLand(Unitc player){
}
}

View File

@ -1,80 +1,22 @@
package mindustry.type;
import arc.util.ArcAnnotate.*;
import mindustry.annotations.Annotations.*;
import mindustry.ctype.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.type.Weather.*;
import java.io.*;
import static mindustry.Vars.*;
public abstract class Weather<T extends WeatherEntity> extends MappableContent{
public abstract class Weather extends MappableContent{
protected float duration = 100f;
public Weather(String name){
super(name);
}
public abstract void update(T entity);
public abstract void update();
public abstract void draw(T entity);
public abstract void draw();
@Override
public ContentType getContentType(){
return ContentType.weather;
}
/** Represents the in-game state of a weather event. */
@SuppressWarnings("unchecked")
public static class WeatherEntity extends BaseEntity implements SaveTrait, DrawTrait{
/** How long this event has been occuring in ticks. */
protected float life;
/** Type of weather that is being simulated. */
protected @NonNull
Weather weather;
public WeatherEntity(Weather weather){
this.weather = weather;
}
@Override
public void update(){
weather.update(this);
}
@Override
public void draw(){
weather.draw(this);
}
@CallSuper
@Override
public void writeSave(DataOutput stream) throws IOException{
stream.writeShort(weather.id);
}
@CallSuper
@Override
public void readSave(DataInput stream, byte version) throws IOException{
weather = content.getByID(ContentType.weather, stream.readShort());
}
@Override
public byte version(){
return 0;
}
@Override
public TypeID getTypeID(){
return null;
}
@Override
public EntityGroup targetGroup(){
return weatherGroup;
}
}
//TODO implement
}

View File

@ -1,34 +1,27 @@
package mindustry.ui.fragments;
import arc.*;
import mindustry.annotations.Annotations.*;
import arc.struct.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.input.*;
import arc.math.*;
import arc.math.geom.*;
import arc.scene.*;
import arc.scene.actions.*;
import arc.scene.event.*;
import arc.scene.style.*;
import arc.scene.ui.*;
import arc.scene.ui.ImageButton.*;
import arc.scene.ui.layout.*;
import arc.struct.*;
import arc.util.*;
import mindustry.annotations.Annotations.*;
import mindustry.core.GameState.*;
import mindustry.ctype.ContentType;
import mindustry.ctype.UnlockableContent;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.game.*;
import mindustry.ctype.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.input.*;
import mindustry.net.Packets.*;
import mindustry.ui.*;
import mindustry.ui.Cicon;
import mindustry.ui.dialogs.*;
import static mindustry.Vars.*;
@ -179,59 +172,6 @@ public class HudFragment extends Fragment{
}
}
}).left();
if(enableUnitEditing){
t.row();
t.addImageTextButton("$editor.spawn", Icon.add, () -> {
FloatingDialog dialog = new FloatingDialog("$editor.spawn");
int i = 0;
for(UnitType type : content.<UnitType>getBy(ContentType.unit)){
dialog.cont.addImageButton(Tex.whiteui, 8 * 6f, () -> {
Call.spawnUnitEditor(player, type);
dialog.hide();
}).get().getStyle().imageUp = new TextureRegionDrawable(type.icon(Cicon.xlarge));
if(++i % 4 == 0) dialog.cont.row();
}
dialog.addCloseButton();
dialog.setFillParent(false);
dialog.show();
}).fillX();
float[] size = {0};
float[] position = {0, 0};
t.row();
t.addImageTextButton("$editor.removeunit", Icon.cancel, Styles.togglet, () -> {}).fillX().update(b -> {
boolean[] found = {false};
if(b.isChecked()){
Element e = Core.scene.hit(Core.input.mouseX(), Core.input.mouseY(), true);
if(e == null){
Vec2 world = Core.input.mouseWorld();
Units.nearby(world.x, world.y, 1f, 1f, unit -> {
if(!found[0] && unit instanceof Unitc){
if(Core.input.keyTap(KeyCode.MOUSE_LEFT)){
Call.removeUnitEditor(player, (Unitc)unit);
}
found[0] = true;
unit.hitbox(Tmp.r1);
size[0] = Mathf.lerpDelta(size[0], Tmp.r1.width * 2f + Mathf.absin(Time.time(), 10f, 5f), 0.1f);
position[0] = unit.x;
position[1] = unit.y;
}
});
}
}
Draw.color(Pal.accent, Color.white, Mathf.absin(Time.time(), 8f, 1f));
Lines.poly(position[0], position[1], 4, size[0] / 2f);
Draw.reset();
if(!found[0]){
size[0] = Mathf.lerpDelta(size[0], 0f, 0.2f);
}
});
}
}).width(dsize * 5 + 4f);
editorMain.visible(() -> shown && state.isEditor());
}
@ -255,7 +195,7 @@ public class HudFragment extends Fragment{
t.add(new Minimap());
t.row();
//position
t.label(() -> world.toTile(player.x) + "," + world.toTile(player.y))
t.label(() -> player.tileX() + "," + player.tileY())
.visible(() -> Core.settings.getBool("position") && !state.rules.tutorial);
t.top().right();
});
@ -350,23 +290,6 @@ public class HudFragment extends Fragment{
}
}
@Remote(targets = Loc.both, called = Loc.server)
public static void spawnUnitEditor(Playerc player, UnitType type){
if(state.isEditor()){
Unitc unit = type.create(player.team());
unit.set(player.x, player.y);
unit.rotation = player.rotation;
unit.add();
}
}
@Remote(targets = Loc.both, called = Loc.server, forward = true)
public static void removeUnitEditor(Playerc player, Unitc unit){
if(state.isEditor() && unit != null){
unit.remove();
}
}
private void scheduleToast(Runnable run){
long duration = (int)(3.5 * 1000);
long since = Time.timeSinceMillis(lastToast);
@ -645,12 +568,12 @@ public class HudFragment extends Fragment{
}
private boolean canSkipWave(){
return state.rules.waves && ((net.server() || player.isAdmin) || !net.active()) && state.enemies == 0 && !spawner.isSpawning() && !state.rules.tutorial;
return state.rules.waves && ((net.server() || player.admin()) || !net.active()) && state.enemies == 0 && !spawner.isSpawning() && !state.rules.tutorial;
}
private void addPlayButton(Table table){
table.right().addImageButton(Icon.play, Styles.righti, 30f, () -> {
if(net.client() && player.isAdmin){
if(net.client() && player.admin()){
Call.onAdminRequest(player, AdminAction.wave);
}else if(inLaunchWave()){
ui.showConfirm("$confirm", "$launch.skip.confirm", () -> !canSkipWave(), () -> state.wavetime = 0f);

View File

@ -337,7 +337,7 @@ public class PlacementFragment extends Fragment{
t.add(new Image(lastDisplay.getDisplayIcon(hoverTile))).size(8 * 4);
t.labelWrap(lastDisplay.getDisplayName(hoverTile)).left().width(190f).padLeft(5);
}).growX().left();
if(hoverTile.getTeam() == player.team()){
if(hoverTile.team() == player.team()){
topTable.row();
topTable.table(t -> {
t.left().defaults().left();

View File

@ -129,7 +129,7 @@ public class PlayerListFragment extends Fragment{
t.addImageButton(Icon.zoom, Styles.clearPartiali, () -> Call.onAdminRequest(user, AdminAction.trace));
}).padRight(12).size(bs + 10f, bs);
}else if(!user.isLocal && !user.isAdmin && net.client() && Groups.player.size() >= 3 && player.team() == user.getTeam()){ //votekick
}else if(!user.isLocal && !user.isAdmin && net.client() && Groups.player.size() >= 3 && player.team() == user.team()){ //votekick
button.add().growY();
button.addImageButton(Icon.hammer, Styles.clearPartiali,
@ -138,7 +138,7 @@ public class PlayerListFragment extends Fragment{
content.add(button).padBottom(-6).width(350f).maxHeight(h + 14);
content.row();
content.addImage().height(4f).color(state.rules.pvp ? user.getTeam().color : Pal.gray).growX();
content.addImage().height(4f).color(state.rules.pvp ? user.team().color : Pal.gray).growX();
content.row();
});

View File

@ -19,7 +19,6 @@ import arc.util.pooling.*;
import mindustry.annotations.Annotations.*;
import mindustry.ctype.*;
import mindustry.entities.*;
import mindustry.entities.effect.*;
import mindustry.gen.*;
import mindustry.entities.units.*;
import mindustry.gen.*;
@ -317,7 +316,7 @@ public class Block extends BlockStorage{
}
public void drawTeam(Tile tile){
Draw.color(tile.getTeam().color);
Draw.color(tile.team().color);
Draw.rect("block-border", tile.drawx() - size * tilesize / 2f + 4, tile.drawy() - size * tilesize / 2f + 4);
Draw.color();
}
@ -372,7 +371,7 @@ public class Block extends BlockStorage{
/** Call when some content is produced. This unlocks the content if it is applicable. */
public void useContent(Tile tile, UnlockableContent content){
//only unlocks content in zones
if(!headless && tile.getTeam() == player.team() && world.isZone()){
if(!headless && tile.team() == player.team() && world.isZone()){
logic.handleContent(content);
}
}

View File

@ -7,7 +7,6 @@ import arc.util.*;
import mindustry.*;
import mindustry.content.*;
import mindustry.ctype.*;
import mindustry.entities.effect.*;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.consumers.*;
@ -48,7 +47,7 @@ public abstract class BlockStorage extends UnlockableContent{
/** Returns the amount of items this block can accept. */
public int acceptStack(Item item, int amount, Tile tile, Teamc source){
if(acceptItem(item, tile, tile) && hasItems && (source == null || source.team() == tile.getTeam())){
if(acceptItem(item, tile, tile) && hasItems && (source == null || source.team() == tile.team())){
return Math.min(getMaximumAccepted(tile, item) - tile.entity.items().get(item), amount);
}else{
return 0;
@ -114,7 +113,7 @@ public abstract class BlockStorage extends UnlockableContent{
other = other.block().getLiquidDestination(other, in, liquid);
if(other != null && other.getTeam() == tile.getTeam() && other.block().hasLiquids && canDumpLiquid(tile, other, liquid) && other.entity.liquids() != null){
if(other != null && other.team() == tile.team() && other.block().hasLiquids && canDumpLiquid(tile, other, liquid) && other.entity.liquids() != null){
float ofract = other.entity.liquids().get(liquid) / other.block().liquidCapacity;
float fract = tile.entity.liquids().get(liquid) / liquidCapacity;
@ -147,7 +146,7 @@ public abstract class BlockStorage extends UnlockableContent{
next = next.link();
next = next.block().getLiquidDestination(next, tile, liquid);
if(next.getTeam() == tile.getTeam() && next.block().hasLiquids && tile.entity.liquids().get(liquid) > 0f){
if(next.team() == tile.team() && next.block().hasLiquids && tile.entity.liquids().get(liquid) > 0f){
if(next.block().acceptLiquid(next, tile, liquid, 0f)){
float ofract = next.entity.liquids().get(liquid) / next.block().liquidCapacity;
@ -199,7 +198,7 @@ public abstract class BlockStorage extends UnlockableContent{
incrementDump(tile, proximity.size);
Tile other = proximity.get((i + dump) % proximity.size);
Tile in = Edges.getFacingEdge(tile, other);
if(other.getTeam() == tile.getTeam() && other.block().acceptItem(item, other, in) && canDump(tile, other, item)){
if(other.team() == tile.team() && other.block().acceptItem(item, other, in) && canDump(tile, other, item)){
other.block().handleItem(item, other, in);
return;
}
@ -236,7 +235,7 @@ public abstract class BlockStorage extends UnlockableContent{
for(int ii = 0; ii < Vars.content.items().size; ii++){
Item item = Vars.content.item(ii);
if(other.getTeam() == tile.getTeam() && entity.items().has(item) && other.block().acceptItem(item, other, in) && canDump(tile, other, item)){
if(other.team() == tile.team() && entity.items().has(item) && other.block().acceptItem(item, other, in) && canDump(tile, other, item)){
other.block().handleItem(item, other, in);
tile.entity.items().remove(item, 1);
incrementDump(tile, proximity.size);
@ -245,7 +244,7 @@ public abstract class BlockStorage extends UnlockableContent{
}
}else{
if(other.getTeam() == tile.getTeam() && other.block().acceptItem(todump, other, in) && canDump(tile, other, todump)){
if(other.team() == tile.team() && other.block().acceptItem(todump, other, in) && canDump(tile, other, todump)){
other.block().handleItem(todump, other, in);
tile.entity.items().remove(todump, 1);
incrementDump(tile, proximity.size);
@ -271,7 +270,7 @@ public abstract class BlockStorage extends UnlockableContent{
/** Try offloading an item to a nearby container in its facing direction. Returns true if success. */
public boolean offloadDir(Tile tile, Item item){
Tile other = tile.front();
if(other != null && other.getTeam() == tile.getTeam() && other.block().acceptItem(item, other, tile)){
if(other != null && other.team() == tile.team() && other.block().acceptItem(item, other, tile)){
other.block().handleItem(item, other, tile);
return true;
}

View File

@ -15,7 +15,7 @@ public class CachedTile extends Tile{
}
@Override
public Team getTeam(){
public Team team(){
return Team.get(getTeamID());
}

View File

@ -143,7 +143,7 @@ public class Tile implements Position{
return (T)block;
}
public Team getTeam(){
public Team team(){
return Team.get(link().team);
}
@ -281,7 +281,7 @@ public class Tile implements Position{
}
public boolean isEnemyCheat(){
return getTeam() == state.rules.waveTeam && state.rules.enemyCheat;
return team() == state.rules.waveTeam && state.rules.enemyCheat;
}
public boolean isLinked(){
@ -385,7 +385,7 @@ public class Tile implements Position{
}
public boolean interactable(Team team){
return state.teams.canInteract(team, getTeam());
return state.teams.canInteract(team, team());
}
public @Nullable Item drop(){
@ -497,7 +497,7 @@ public class Tile implements Position{
@Override
public String toString(){
return floor.name + ":" + block.name + ":" + overlay + "[" + x + "," + y + "] " + "entity=" + (entity == null ? "null" : (entity.getClass())) + ":" + getTeam();
return floor.name + ":" + block.name + ":" + overlay + "[" + x + "," + y + "] " + "entity=" + (entity == null ? "null" : (entity.getClass())) + ":" + team();
}
//remote utility methods

View File

@ -53,7 +53,7 @@ public class BuildBlock extends Block{
@Remote(called = Loc.server)
public static void onDeconstructFinish(Tile tile, Block block, int builderID){
Team team = tile.getTeam();
Team team = tile.team();
Fx.breakBlock.at(tile.drawx(), tile.drawy(), block.size);
Events.fire(new BlockBuildEndEvent(tile, Groups.player.getByID(builderID), team, true));
tile.remove();

View File

@ -4,6 +4,7 @@ import arc.graphics.g2d.*;
import arc.math.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.type.*;
import mindustry.ui.*;
import mindustry.world.*;
@ -11,7 +12,7 @@ import static mindustry.Vars.net;
public class RespawnBlock{
public static void drawRespawn(Tile tile, float heat, float progress, float time, Playerc player, Mech to){
public static void drawRespawn(Tile tile, float heat, float progress, float time, Playerc player, UnitDef to){
progress = Mathf.clamp(progress);
Draw.color(Pal.darkMetal);

View File

@ -64,7 +64,7 @@ public class DeflectorWall extends Wall{
}
//bullet.updateVelocity();
bullet.resetOwner(entity, entity.getTeam());
bullet.resetOwner(entity, entity.team());
bullet.scaleTime(1f);
bullet.deflect();

View File

@ -36,7 +36,7 @@ public class ForceProjector extends Block{
private static ForceProjector paramBlock;
private static ForceEntity paramEntity;
private static Cons<Shielderc> shieldConsumer = trait -> {
if(trait.team() != paramTile.getTeam() && Intersector.isInsideHexagon(trait.x(), trait.y(), paramBlock.realRadius(paramEntity) * 2f, paramTile.drawx(), paramTile.drawy())){
if(trait.team() != paramTile.team() && Intersector.isInsideHexagon(trait.x(), trait.y(), paramBlock.realRadius(paramEntity) * 2f, paramTile.drawx(), paramTile.drawy())){
trait.absorb();
Fx.absorb.at(trait);
paramEntity.hit = 1f;

View File

@ -31,7 +31,7 @@ public class ShockMine extends Block{
@Override
public void drawLayer(Tile tile){
super.draw(tile);
Draw.color(tile.getTeam().color);
Draw.color(tile.team().color);
Draw.alpha(0.22f);
Fill.rect(tile.drawx(), tile.drawy(), 2f, 2f);
Draw.color();
@ -49,9 +49,9 @@ public class ShockMine extends Block{
@Override
public void unitOn(Tile tile, Unitc unit){
if(unit.getTeam() != tile.getTeam() && tile.entity.timer(timerDamage, cooldown)){
if(unit.team() != tile.team() && tile.entity.timer(timerDamage, cooldown)){
for(int i = 0; i < tendrils; i++){
Lightning.create(tile.getTeam(), Pal.lancerLaser, damage, tile.drawx(), tile.drawy(), Mathf.random(360f), length);
Lightning.create(tile.team(), Pal.lancerLaser, damage, tile.drawx(), tile.drawy(), Mathf.random(360f), length);
}
tile.entity.damage(tileDamage);
}

View File

@ -1,9 +1,9 @@
package mindustry.world.blocks.defense;
import arc.math.Mathf;
import mindustry.entities.effect.Lightning;
import arc.math.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.graphics.Pal;
import mindustry.graphics.*;
public class SurgeWall extends Wall{
public float lightningChance = 0.05f;
@ -15,10 +15,10 @@ public class SurgeWall extends Wall{
}
@Override
public void handleBulletHit(Tilec entity, Bullet bullet){
public void handleBulletHit(Tilec entity, Bulletc bullet){
super.handleBulletHit(entity, bullet);
if(Mathf.chance(lightningChance)){
Lightning.create(entity.team(), Pal.surge, lightningDamage, bullet.x, bullet.y, bullet.rotation() + 180f, lightningLength);
Lightning.create(entity.team(), Pal.surge, lightningDamage, bullet.x(), bullet.y(), bullet.rotation() + 180f, lightningLength);
}
}
}

View File

@ -36,7 +36,7 @@ public class ArtilleryTurret extends ItemTurret{
float maxTraveled = type.lifetime * type.speed;
for(int i = 0; i < shots; i++){
Bullet.create(ammo, tile.entity, tile.getTeam(), tile.drawx() + tr.x, tile.drawy() + tr.y,
Bullet.create(ammo, tile.entity, tile.team(), tile.drawx() + tr.x, tile.drawy() + tr.y,
entity.rotation + Mathf.range(inaccuracy + type.inaccuracy), 1f + Mathf.range(velocityInaccuracy), (dst / maxTraveled));
}

View File

@ -3,6 +3,7 @@ package mindustry.world.blocks.defense.turrets;
import arc.math.*;
import arc.util.*;
import mindustry.entities.bullet.*;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.consumers.*;
@ -94,7 +95,7 @@ public class LaserTurret extends PowerTurret{
protected void bullet(Tile tile, BulletType type, float angle){
LaserTurretEntity entity = tile.ent();
entity.bullet = Bullet.create(type, tile.entity, tile.getTeam(), tile.drawx() + tr.x, tile.drawy() + tr.y, angle);
entity.bullet = Bullet.create(type, tile.entity, tile.team(), tile.drawx() + tr.x, tile.drawy() + tr.y, angle);
entity.bulletLife = shootDuration;
}
@ -106,7 +107,7 @@ public class LaserTurret extends PowerTurret{
}
class LaserTurretEntity extends TurretEntity{
Bullet bullet;
Bulletc bullet;
float bulletLife;
}
}

View File

@ -5,7 +5,6 @@ import arc.graphics.g2d.*;
import arc.struct.*;
import mindustry.entities.*;
import mindustry.entities.bullet.*;
import mindustry.entities.effect.*;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.*;

View File

@ -131,7 +131,7 @@ public abstract class Turret extends Block{
@Override
public void drawSelect(Tile tile){
Drawf.dashCircle(tile.drawx(), tile.drawy(), range, tile.getTeam().color);
Drawf.dashCircle(tile.drawx(), tile.drawy(), range, tile.team().color);
}
@Override
@ -184,16 +184,16 @@ public abstract class Turret extends Block{
protected boolean validateTarget(Tile tile){
TurretEntity entity = tile.ent();
return !Units.invalidateTarget(entity.target, tile.getTeam(), tile.drawx(), tile.drawy());
return !Units.invalidateTarget(entity.target, tile.team(), tile.drawx(), tile.drawy());
}
protected void findTarget(Tile tile){
TurretEntity entity = tile.ent();
if(targetAir && !targetGround){
entity.target = Units.closestEnemy(tile.getTeam(), tile.drawx(), tile.drawy(), range, e -> !e.dead() && e.isFlying());
entity.target = Units.closestEnemy(tile.team(), tile.drawx(), tile.drawy(), range, e -> !e.dead() && e.isFlying());
}else{
entity.target = Units.closestTarget(tile.getTeam(), tile.drawx(), tile.drawy(), range, e -> !e.dead() && (!e.isFlying() || targetAir) && (e.isFlying() || targetGround));
entity.target = Units.closestTarget(tile.team(), tile.drawx(), tile.drawy(), range, e -> !e.dead() && (!e.isFlying() || targetAir) && (e.isFlying() || targetGround));
}
}
@ -267,7 +267,7 @@ public abstract class Turret extends Block{
}
protected void bullet(Tile tile, BulletType type, float angle){
Bullet.create(type, tile.entity, tile.getTeam(), tile.drawx() + tr.x, tile.drawy() + tr.y, angle);
Bullet.create(type, tile.entity, tile.team(), tile.drawx() + tr.x, tile.drawy() + tr.y, angle);
}
protected void effects(Tile tile){

View File

@ -95,7 +95,7 @@ public class Conveyor extends Block implements Autotiler{
if(tile.front() != null && tile.front().entity != null){
entity.next = tile.front().entity;
entity.nextc = entity.next instanceof ConveyorEntity && entity.next.team() == tile.getTeam() ? (ConveyorEntity)entity.next : null;
entity.nextc = entity.next instanceof ConveyorEntity && entity.next.team() == tile.team() ? (ConveyorEntity)entity.next : null;
entity.aligned = entity.nextc != null && tile.rotation() == entity.next.tile.rotation();
}
}

View File

@ -255,7 +255,7 @@ public class ItemBridge extends Block{
@Override
public boolean acceptItem(Item item, Tile tile, Tile source){
if(tile.getTeam() != source.getTeam()) return false;
if(tile.team() != source.team()) return false;
ItemBridgeEntity entity = tile.ent();
Tile other = world.tile(entity.link);
@ -301,7 +301,7 @@ public class ItemBridge extends Block{
@Override
public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){
if(tile.getTeam() != source.getTeam() || !hasLiquids) return false;
if(tile.team() != source.team() || !hasLiquids) return false;
ItemBridgeEntity entity = tile.ent();
Tile other = world.tile(entity.link);

View File

@ -57,7 +57,7 @@ public class Junction extends Block{
if(dest != null) dest = dest.link();
//skip blocks that don't want the item, keep waiting until they do
if(dest == null || !dest.block().acceptItem(item, dest, tile) || dest.getTeam() != tile.getTeam()){
if(dest == null || !dest.block().acceptItem(item, dest, tile) || dest.team() != tile.team()){
continue;
}
@ -83,7 +83,7 @@ public class Junction extends Block{
if(entity == null || relative == -1 || !entity.buffer.accepts(relative)) return false;
Tile to = tile.getNearby(relative);
return to != null && to.link().entity != null && to.getTeam() == tile.getTeam();
return to != null && to.link().entity != null && to.team() == tile.team();
}
class JunctionEntity extends Tilec{

View File

@ -214,7 +214,7 @@ public class MassDriver extends Block{
if(entity.link == other.pos()){
tile.configure(-1);
return false;
}else if(other.block() instanceof MassDriver && other.dst(tile) <= range && other.getTeam() == tile.getTeam()){
}else if(other.block() instanceof MassDriver && other.dst(tile) <= range && other.team() == tile.team()){
tile.configure(other.pos());
return false;
}
@ -248,9 +248,9 @@ public class MassDriver extends Block{
float angle = tile.angleTo(target);
Bullet.create(Bullets.driverBolt, entity, entity.getTeam(),
Bullets.driverBolt.create(entity, entity.team(),
tile.drawx() + Angles.trnsx(angle, translation), tile.drawy() + Angles.trnsy(angle, translation),
angle, 1f, 1f, data);
angle, -1f, 1f, 1f, data);
shootEffect.at(tile.drawx() + Angles.trnsx(angle, translation),
tile.drawy() + Angles.trnsy(angle, translation), angle);
@ -261,7 +261,7 @@ public class MassDriver extends Block{
Effects.shake(shake, shake, entity);
}
protected void handlePayload(MassDriverEntity entity, Bullet bullet, DriverBulletData data){
protected void handlePayload(MassDriverEntity entity, Bulletc bullet, DriverBulletData data){
int totalItems = entity.items().total();
//add all the items possible
@ -297,7 +297,7 @@ public class MassDriver extends Block{
if(entity == null || entity.link == -1) return false;
Tile link = world.tile(entity.link);
return link != null && link.block() instanceof MassDriver && link.getTeam() == tile.getTeam() && tile.dst(link) <= range;
return link != null && link.block() instanceof MassDriver && link.team() == tile.team() && tile.dst(link) <= range;
}
public static class DriverBulletData implements Poolable{
@ -322,8 +322,8 @@ public class MassDriver extends Block{
return waitingShooters.isEmpty() ? null : waitingShooters.first();
}
public void handlePayload(Bullet bullet, DriverBulletData data){
((MassDriver)block).handlePayload(this, bullet, data);
public void handlePayload(Bulletc bullet, DriverBulletData data){
((MassDriver)block()).handlePayload(this, bullet, data);
}
@Override

View File

@ -63,7 +63,7 @@ public class OverflowGate extends Block{
public boolean acceptItem(Item item, Tile tile, Tile source){
OverflowGateEntity entity = tile.ent();
return tile.getTeam() == source.getTeam() && entity.lastItem == null && entity.items().total() == 0;
return tile.team() == source.team() && entity.lastItem == null && entity.items().total() == 0;
}
@Override
@ -83,13 +83,13 @@ public class OverflowGate extends Block{
Tile to = tile.getNearby((from + 2) % 4);
if(to == null) return null;
Tile edge = Edges.getFacingEdge(tile, to);
boolean canForward = to.block().acceptItem(item, to, edge) && to.getTeam() == tile.getTeam() && !(to.block() instanceof OverflowGate);
boolean canForward = to.block().acceptItem(item, to, edge) && to.team() == tile.team() && !(to.block() instanceof OverflowGate);
if(!canForward || invert){
Tile a = tile.getNearby(Mathf.mod(from - 1, 4));
Tile b = tile.getNearby(Mathf.mod(from + 1, 4));
boolean ac = a != null && a.block().acceptItem(item, a, edge) && !(a.block() instanceof OverflowGate) && a.getTeam() == tile.getTeam();
boolean bc = b != null && b.block().acceptItem(item, b, edge) && !(b.block() instanceof OverflowGate) && b.getTeam() == tile.getTeam();
boolean ac = a != null && a.block().acceptItem(item, a, edge) && !(a.block() instanceof OverflowGate) && a.team() == tile.team();
boolean bc = b != null && b.block().acceptItem(item, b, edge) && !(b.block() instanceof OverflowGate) && b.team() == tile.team();
if(!ac && !bc){
return invert && canForward ? to : null;

View File

@ -47,7 +47,7 @@ public class Router extends Block{
public boolean acceptItem(Item item, Tile tile, Tile source){
RouterEntity entity = tile.ent();
return tile.getTeam() == source.getTeam() && entity.lastItem == null && entity.items().total() == 0;
return tile.team() == source.team() && entity.lastItem == null && entity.items().total() == 0;
}
@Override

View File

@ -74,7 +74,7 @@ public class Sorter extends Block{
public boolean acceptItem(Item item, Tile tile, Tile source){
Tile to = getTileTarget(item, tile, source, false);
return to != null && to.block().acceptItem(item, to, tile) && to.getTeam() == tile.getTeam();
return to != null && to.block().acceptItem(item, to, tile) && to.team() == tile.team();
}
@Override

View File

@ -28,7 +28,7 @@ public class ArmoredConduit extends Conduit{
// draw the cap when a conduit would normally leak
Tile next = tile.front();
if(next != null && next.getTeam() == tile.getTeam() && next.block().hasLiquids) return;
if(next != null && next.team() == tile.team() && next.block().hasLiquids) return;
Draw.rect(capRegion, tile.drawx(), tile.drawy(), tile.rotation() * 90);
}

View File

@ -27,7 +27,7 @@ public class PowerDiode extends Block{
public void update(Tile tile){
super.update(tile);
if(tile.front() == null || tile.back() == null || !tile.back().block().hasPower || !tile.front().block().hasPower || tile.back().getTeam() != tile.front().getTeam()) return;
if(tile.front() == null || tile.back() == null || !tile.back().block().hasPower || !tile.front().block().hasPower || tile.back().team() != tile.front().team()) return;
PowerGraph backGraph = tile.back().entity.power().graph;
PowerGraph frontGraph = tile.front().entity.power().graph;

View File

@ -134,7 +134,7 @@ public class PowerNode extends PowerBlock{
private void getPotentialLinks(Tile tile, Cons<Tile> others){
Boolf<Tile> valid = other -> other != null && other != tile && other.entity != null && other.entity.power() != null &&
((!other.block().outputsPower && other.block().consumesPower) || (other.block().outputsPower && !other.block().consumesPower) || other.block() instanceof PowerNode) &&
overlaps(tile.x * tilesize + offset(), tile.y * tilesize + offset(), other, laserRange * tilesize) && other.getTeam() == player.team()
overlaps(tile.x * tilesize + offset(), tile.y * tilesize + offset(), other, laserRange * tilesize) && other.team() == player.team()
&& !other.entity.proximity().contains(tile) && !graphs.contains(other.entity.power().graph);
tempTiles.clear();
@ -289,7 +289,7 @@ public class PowerNode extends PowerBlock{
}
public boolean linkValid(Tile tile, Tile link, boolean checkMaxNodes){
if(tile == link || link == null || link.entity == null || tile.entity == null || !link.block().hasPower || tile.getTeam() != link.getTeam()) return false;
if(tile == link || link == null || link.entity == null || tile.entity == null || !link.block().hasPower || tile.team() != link.team()) return false;
if(overlaps(tile, link, laserRange * tilesize) || (link.block() instanceof PowerNode && overlaps(link, tile, link.<PowerNode>cblock().laserRange * tilesize))){
if(checkMaxNodes && link.block() instanceof PowerNode){

View File

@ -83,7 +83,7 @@ public class CoreBlock extends StorageBlock{
public void onProximityUpdate(Tile tile){
CoreEntity entity = tile.ent();
for(Tilec other : state.teams.cores(tile.getTeam())){
for(Tilec other : state.teams.cores(tile.team())){
if(other.tile() != tile){
entity.items(other.items());
}
@ -96,7 +96,7 @@ public class CoreBlock extends StorageBlock{
t.<StorageBlockEntity>ent().linkedCore = tile;
});
for(Tilec other : state.teams.cores(tile.getTeam())){
for(Tilec other : state.teams.cores(tile.team())){
if(other.tile() == tile) continue;
entity.storageCapacity += other.block().itemCapacity + other.proximity().sum(e -> isContainer(e) ? e.block().itemCapacity : 0);
}
@ -107,7 +107,7 @@ public class CoreBlock extends StorageBlock{
}
}
for(CoreEntity other : state.teams.cores(tile.getTeam())){
for(CoreEntity other : state.teams.cores(tile.team())){
other.storageCapacity = entity.storageCapacity;
}
}
@ -137,7 +137,7 @@ public class CoreBlock extends StorageBlock{
@Override
public float handleDamage(Tile tile, float amount){
//TODO implement
//if(player != null && tile.getTeam() == player.team()){
//if(player != null && tile.team() == player.team()){
// Events.fire(Trigger.teamCoreDamage);
//}
return amount;
@ -152,7 +152,7 @@ public class CoreBlock extends StorageBlock{
public void removed(Tile tile){
CoreEntity entity = tile.ent();
int total = tile.entity.proximity().count(e -> e.entity != null && e.entity.items() != null && e.entity.items() == tile.entity.items());
float fract = 1f / total / state.teams.cores(tile.getTeam()).size;
float fract = 1f / total / state.teams.cores(tile.team()).size;
tile.entity.proximity().each(e -> isContainer(e) && e.entity.items() == tile.entity.items(), t -> {
StorageBlockEntity ent = (StorageBlockEntity)t.entity;
@ -165,12 +165,12 @@ public class CoreBlock extends StorageBlock{
state.teams.unregisterCore(entity);
int max = itemCapacity * state.teams.cores(tile.getTeam()).size;
int max = itemCapacity * state.teams.cores(tile.team()).size;
for(Item item : content.items()){
tile.entity.items().set(item, Math.min(tile.entity.items().get(item), max));
}
for(CoreEntity other : state.teams.cores(tile.getTeam())){
for(CoreEntity other : state.teams.cores(tile.team())){
other.block().onProximityUpdate(other.tile());
}
}

Some files were not shown because too many files have changed in this diff Show More