Entity IO fixes

This commit is contained in:
Anuken
2020-05-14 17:40:49 -04:00
parent 12f4d5a9a4
commit 6d23963e98
29 changed files with 226 additions and 109 deletions

View File

@@ -2,6 +2,7 @@ package mindustry.annotations.entity;
import arc.files.*; import arc.files.*;
import arc.struct.*; import arc.struct.*;
import arc.util.*;
import arc.util.serialization.*; import arc.util.serialization.*;
import com.squareup.javapoet.*; import com.squareup.javapoet.*;
import mindustry.annotations.Annotations.*; import mindustry.annotations.Annotations.*;
@@ -45,8 +46,8 @@ public class EntityIO{
Array<FieldSpec> fields = Array.with(type.fieldSpecs).select(spec -> Array<FieldSpec> fields = Array.with(type.fieldSpecs).select(spec ->
!spec.hasModifier(Modifier.TRANSIENT) && !spec.hasModifier(Modifier.TRANSIENT) &&
!spec.hasModifier(Modifier.STATIC) && !spec.hasModifier(Modifier.STATIC) &&
!spec.hasModifier(Modifier.FINAL) && !spec.hasModifier(Modifier.FINAL)/* &&
(spec.type.isPrimitive() || serializer.has(spec.type.toString()))); (spec.type.isPrimitive() || serializer.has(spec.type.toString()))*/);
//sort to keep order //sort to keep order
fields.sortComparing(f -> f.name); fields.sortComparing(f -> f.name);
@@ -116,6 +117,55 @@ public class EntityIO{
st("$L(write, $L)", serializer.writers.get(type), field); st("$L(write, $L)", serializer.writers.get(type), field);
}else if(serializer.readers.containsKey(type) && !write){ }else if(serializer.readers.containsKey(type) && !write){
st("$L$L(read)", field, serializer.readers.get(type)); st("$L$L(read)", field, serializer.readers.get(type));
}else if(type.endsWith("[]")){ //it's a 1D array
String rawType = type.substring(0, type.length() - 2);
if(write){
s("i", field + ".length");
cont("for(int INDEX = 0; INDEX < $L.length; INDEX ++)", field);
io(rawType, field + "[INDEX]");
}else{
String fieldName = field.replace(" = ", "").replace("this.", "");
String lenf = fieldName + "_LENGTH";
s("i", "int " + lenf + " = ");
if(!field.isEmpty()){
st("$Lnew $L[$L]", field, type.replace("[]", ""), lenf);
}
cont("for(int INDEX = 0; INDEX < $L; INDEX ++)", lenf);
io(rawType, field.replace(" = ", "[INDEX] = "));
}
econt();
}else if(type.startsWith("arc.struct") && type.contains("<")){ //it's some type of data structure
String struct = type.substring(0, type.indexOf("<"));
String generic = type.substring(type.indexOf("<") + 1, type.indexOf(">"));
if(struct.equals("arc.struct.Queue") || struct.equals("arc.struct.Array")){
if(write){
s("i", field + ".size");
cont("for(int INDEX = 0; INDEX < $L.size; INDEX ++)", field);
io(generic, field + ".get(INDEX)");
}else{
String fieldName = field.replace(" = ", "").replace("this.", "");
String lenf = fieldName + "_LENGTH";
s("i", "int " + lenf + " = ");
if(!field.isEmpty()){
st("$L.clear()", field.replace(" = ", ""));
}
cont("for(int INDEX = 0; INDEX < $L; INDEX ++)", lenf);
io(generic, field.replace(" = ", "_ITEM = ").replace("this.", generic + " "));
if(!field.isEmpty()){
String temp = field.replace(" = ", "_ITEM").replace("this.", "");
st("if($L != null) $L.add($L)", temp, field.replace(" = ", ""), temp);
}
}
econt();
}else{
Log.warn("Missing serialization code for collection '@' in '@'", type, name);
}
}else{
Log.warn("Missing serialization code for type '@' in '@'", type, name);
} }
} }

View File

@@ -4,6 +4,7 @@ import arc.*;
import arc.files.*; import arc.files.*;
import arc.func.*; import arc.func.*;
import arc.struct.*; import arc.struct.*;
import arc.util.ArcAnnotate.*;
import arc.util.*; import arc.util.*;
import arc.util.io.*; import arc.util.io.*;
import arc.util.pooling.Pool.*; import arc.util.pooling.Pool.*;
@@ -262,7 +263,7 @@ public class EntityProcess extends BaseProcessor{
.addModifiers(Modifier.PUBLIC) .addModifiers(Modifier.PUBLIC)
.addStatement("return $S + $L", name + "#", "id").build()); .addStatement("return $S + $L", name + "#", "id").build());
EntityIO io = new EntityIO(type.name(), builder, serializer, rootDirectory.child("annotations/src/main/resources/revisions").child(name)); EntityIO io = ann.serialize() ? new EntityIO(type.name(), builder, serializer, rootDirectory.child("annotations/src/main/resources/revisions").child(name)) : null;
//add all methods from components //add all methods from components
for(ObjectMap.Entry<String, Array<Smethod>> entry : methods){ for(ObjectMap.Entry<String, Array<Smethod>> entry : methods){
@@ -323,7 +324,7 @@ public class EntityProcess extends BaseProcessor{
//SPECIAL CASE: I/O code //SPECIAL CASE: I/O code
//note that serialization is generated even for non-serializing entities for manual usage //note that serialization is generated even for non-serializing entities for manual usage
if((first.name().equals("read") || first.name().equals("write")) && ann.genio()){ if((first.name().equals("read") || first.name().equals("write")) && ann.genio() && ann.serialize()){
io.write(mbuilder, first.name().equals("write")); io.write(mbuilder, first.name().equals("write"));
} }
@@ -620,7 +621,17 @@ public class EntityProcess extends BaseProcessor{
Array<Stype> allComponents(Selement<?> type){ Array<Stype> allComponents(Selement<?> type){
if(!defComponents.containsKey(type)){ if(!defComponents.containsKey(type)){
//get base defs //get base defs
Array<Stype> components = types(type.annotation(EntityDef.class), EntityDef::value).map(this::interfaceToComp); Array<Stype> interfaces = types(type.annotation(EntityDef.class), EntityDef::value);
Array<Stype> components = new Array<>();
for(Stype i : interfaces){
Stype comp = interfaceToComp(i);
if(comp != null){
components.add(comp);
}else{
throw new IllegalArgumentException("Type '" + i + "' is not a component interface!");
}
}
ObjectSet<Stype> out = new ObjectSet<>(); ObjectSet<Stype> out = new ObjectSet<>();
for(Stype comp : components){ for(Stype comp : components){
//get dependencies for each def, add them //get dependencies for each def, add them
@@ -665,7 +676,7 @@ public class EntityProcess extends BaseProcessor{
return interfaceToComp(type) != null; return interfaceToComp(type) != null;
} }
Stype interfaceToComp(Stype type){ @Nullable Stype interfaceToComp(Stype type){
String name = type.name().substring(0, type.name().length() - 1) + "Comp"; String name = type.name().substring(0, type.name().length() - 1) + "Comp";
return componentNames.get(name); return componentNames.get(name);
} }

View File

@@ -1,17 +1,16 @@
#Maps entity names to IDs. Autogenerated. #Maps entity names to IDs. Autogenerated.
dagger=0 draug=0
draug=1 mindustry.entities.def.BulletComp=1
mindustry.entities.def.BulletComp=2 mindustry.entities.def.DecalComp=2
mindustry.entities.def.DecalComp=3 mindustry.entities.def.EffectComp=3
mindustry.entities.def.EffectComp=4 mindustry.entities.def.FireComp=4
mindustry.entities.def.FireComp=5 mindustry.entities.def.PlayerComp=5
mindustry.entities.def.PlayerComp=6 mindustry.entities.def.PuddleComp=6
mindustry.entities.def.PuddleComp=7 mindustry.entities.def.TileComp=7
mindustry.entities.def.TileComp=8 mindustry.type.Weather.WeatherComp=8
mindustry.type.Weather.WeatherComp=9 mindustry.world.blocks.storage.LaunchPad.LaunchPayloadComp=9
phantom=10 phantom=10
reaper=14 titan=11
titan=13 vanguard=12
vanguard=11 wraith=13
wraith=12

View File

@@ -1 +1 @@
{fields:[{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]} {fields:[{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:requests,type:arc.struct.Queue<mindustry.entities.units.BuildRequest>,size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Array<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:vel,type:arc.math.geom.Vec2,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@@ -1 +0,0 @@
{fields:[{name:damage,type:float,size:4},{name:data,type:java.lang.Object,size:-1},{name:lifetime,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:time,type:float,size:4},{name:type,type:mindustry.entities.bullet.BulletType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@@ -1 +1 @@
{fields:[{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]} {fields:[{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Array<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:vel,type:arc.math.geom.Vec2,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@@ -1 +0,0 @@
{fields:[{name:color,type:arc.graphics.Color,size:-1},{name:lifetime,type:float,size:4},{name:rotation,type:float,size:4},{name:time,type:float,size:4},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@@ -1 +0,0 @@
{fields:[{name:color,type:arc.graphics.Color,size:-1},{name:data,type:java.lang.Object,size:-1},{name:lifetime,type:float,size:4},{name:offsetX,type:float,size:4},{name:offsetY,type:float,size:4},{name:rotation,type:float,size:4},{name:time,type:float,size:4},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@@ -0,0 +1 @@
{fields:[{name:height,type:float,size:4},{name:stacks,type:arc.struct.Array<mindustry.type.ItemStack>,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@@ -1 +1 @@
{fields:[{name:baseRotation,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]} {fields:[{name:baseRotation,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Array<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:vel,type:arc.math.geom.Vec2,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@@ -1 +1 @@
{fields:[{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:mineTile,type:mindustry.world.Tile,size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]} {fields:[{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:mineTile,type:mindustry.world.Tile,size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Array<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:vel,type:arc.math.geom.Vec2,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@@ -1 +0,0 @@
{fields:[{name:admin,type:boolean,size:1},{name:color,type:arc.graphics.Color,size:-1},{name:deathTimer,type:float,size:4},{name:lastText,type:java.lang.String,size:-1},{name:mouseX,type:float,size:4},{name:mouseY,type:float,size:4},{name:name,type:java.lang.String,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:textFadeTime,type:float,size:4},{name:typing,type:boolean,size:1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@@ -1 +0,0 @@
{fields:[{name:health,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@@ -1 +1 @@
{fields:[{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]} {fields:[{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Array<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:vel,type:arc.math.geom.Vec2,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@@ -58,7 +58,7 @@ abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Draw
remove(); remove();
} }
@Override @Replace
public float clipSize(){ public float clipSize(){
return type.drawSize; return type.drawSize;
} }

View File

@@ -25,7 +25,7 @@ abstract class DecalComp implements Drawc, Timedc, Rotc, Posc{
Draw.color(); Draw.color();
} }
@Override @Replace
public float clipSize(){ public float clipSize(){
return region.getWidth()*2; return region.getWidth()*2;
} }

View File

@@ -6,7 +6,9 @@ import mindustry.gen.*;
@Component @Component
abstract class DrawComp implements Posc{ abstract class DrawComp implements Posc{
abstract float clipSize(); float clipSize(){
return Float.MAX_VALUE;
}
void draw(){ void draw(){

View File

@@ -17,7 +17,7 @@ abstract class EffectComp implements Posc, Drawc, Timedc, Rotc, Childc{
effect.render(id(), color, time(), rotation(), x(), y(), data); effect.render(id(), color, time(), rotation(), x(), y(), data);
} }
@Override @Replace
public float clipSize(){ public float clipSize(){
return effect.size; return effect.size;
} }

View File

@@ -62,7 +62,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
} }
} }
@Override @Replace
public float clipSize(){ public float clipSize(){
return 20; return 20;
} }

View File

@@ -114,7 +114,7 @@ abstract class PuddleComp implements Posc, Puddlec, Drawc{
} }
} }
@Override @Replace
public float clipSize(){ public float clipSize(){
return 20; return 20;
} }

View File

@@ -20,7 +20,7 @@ import static mindustry.Vars.content;
@Component @Component
abstract class StatusComp implements Posc, Flyingc{ abstract class StatusComp implements Posc, Flyingc{
private Array<StatusEntry> statuses = new Array<>(); private Array<StatusEntry> statuses = new Array<>();
private Bits applied = new Bits(content.getBy(ContentType.status).size); private transient Bits applied = new Bits(content.getBy(ContentType.status).size);
@ReadOnly transient float speedMultiplier, damageMultiplier, armorMultiplier; @ReadOnly transient float speedMultiplier, damageMultiplier, armorMultiplier;
@@ -145,31 +145,4 @@ abstract class StatusComp implements Posc, Flyingc{
boolean hasEffect(StatusEffect effect){ boolean hasEffect(StatusEffect effect){
return applied.get(effect.id); return applied.get(effect.id);
} }
//TODO autogen io code
void writeSave(DataOutput stream) throws IOException{
stream.writeByte(statuses.size);
for(StatusEntry entry : statuses){
stream.writeByte(entry.effect.id);
stream.writeFloat(entry.time);
}
}
void readSave(DataInput stream, byte version) throws IOException{
for(StatusEntry effect : statuses){
Pools.free(effect);
}
statuses.clear();
byte amount = stream.readByte();
for(int i = 0; i < amount; i++){
byte id = stream.readByte();
float time = stream.readFloat();
StatusEntry entry = Pools.obtain(StatusEntry.class, StatusEntry::new);
entry.set(content.getByID(ContentType.status, id), time);
statuses.add(entry);
}
}
} }

View File

@@ -9,7 +9,7 @@ import mindustry.net.*;
abstract class SyncComp implements Posc{ abstract class SyncComp implements Posc{
@Import float x, y; @Import float x, y;
Interpolator interpolator = new Interpolator(); transient Interpolator interpolator = new Interpolator();
void setNet(float x, float y){ void setNet(float x, float y){
set(x, y); set(x, y);

View File

@@ -22,7 +22,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
@Import float x, y, rotation, elevation, maxHealth; @Import float x, y, rotation, elevation, maxHealth;
private UnitController controller; private transient UnitController controller;
private UnitType type; private UnitType type;
public void moveAt(Vec2 vector){ public void moveAt(Vec2 vector){
@@ -43,7 +43,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
return type.hasWeapons(); return type.hasWeapons();
} }
@Override @Replace
public float clipSize(){ public float clipSize(){
return type.region.getWidth() * 2f; return type.region.getWidth() * 2f;
} }

View File

@@ -20,7 +20,7 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc{
static int sequenceNum = 0; static int sequenceNum = 0;
/** weapon mount array, never null */ /** weapon mount array, never null */
@ReadOnly WeaponMount[] mounts = {}; @ReadOnly transient WeaponMount[] mounts = {};
@ReadOnly transient float range, aimX, aimY; @ReadOnly transient float range, aimX, aimY;
@ReadOnly transient boolean isRotate, isShooting; @ReadOnly transient boolean isRotate, isShooting;

View File

@@ -5,6 +5,8 @@ import arc.struct.*;
import mindustry.annotations.Annotations.*; import mindustry.annotations.Annotations.*;
import mindustry.type.*; import mindustry.type.*;
import static mindustry.Vars.content;
@Serialize @Serialize
public class Stats{ public class Stats{
/** Items delivered to global resoure counter. Zones only. */ /** Items delivered to global resoure counter. Zones only. */
@@ -22,6 +24,9 @@ public class Stats{
/** Friendly buildings destroyed. */ /** Friendly buildings destroyed. */
public int buildingsDestroyed; public int buildingsDestroyed;
/** Item production means. */
private transient WindowedMean[] itemProduction = new WindowedMean[content.items().size];
public RankResult calculateRank(Sector zone, boolean launched){ public RankResult calculateRank(Sector zone, boolean launched){
float score = 0; float score = 0;

View File

@@ -4,6 +4,7 @@ import arc.graphics.*;
import arc.math.geom.*; import arc.math.geom.*;
import arc.struct.*; import arc.struct.*;
import arc.util.io.*; import arc.util.io.*;
import arc.util.pooling.*;
import mindustry.annotations.Annotations.*; import mindustry.annotations.Annotations.*;
import mindustry.ctype.*; import mindustry.ctype.*;
import mindustry.entities.bullet.*; import mindustry.entities.bullet.*;
@@ -118,22 +119,51 @@ public class TypeIO{
return content.block(read.s()); return content.block(read.s());
} }
public static void writeRequest(Writes write, BuildRequest request){
write.b(request.breaking ? (byte)1 : 0);
write.i(Point2.pack(request.x, request.y));
if(!request.breaking){
write.s(request.block.id);
write.b((byte)request.rotation);
write.b(request.hasConfig ? (byte)1 : 0);
writeObject(write, request.config);
}
}
public static BuildRequest readRequest(Reads read){
BuildRequest currentRequest;
byte type = read.b();
int position = read.i();
if(world.tile(position) == null){
return null;
}
if(type == 1){ //remove
currentRequest = new BuildRequest(Point2.x(position), Point2.y(position));
}else{ //place
short block = read.s();
byte rotation = read.b();
boolean hasConfig = read.b() == 1;
Object config = readObject(read);
currentRequest = new BuildRequest(Point2.x(position), Point2.y(position), rotation, content.block(block));
if(hasConfig){
currentRequest.configure(config);
}
}
return currentRequest;
}
public static void writeRequests(Writes write, BuildRequest[] requests){ public static void writeRequests(Writes write, BuildRequest[] requests){
if(requests == null){ if(requests == null){
write.s(-1); write.s(-1);
return; return;
} }
write.s((short)requests.length); write.s((short)requests.length);
for(BuildRequest request : requests){ for(BuildRequest request : requests){
write.b(request.breaking ? (byte)1 : 0); writeRequest(write, request);
write.i(Point2.pack(request.x, request.y));
if(!request.breaking){
write.s(request.block.id);
write.b((byte)request.rotation);
write.b(request.hasConfig ? (byte)1 : 0);
writeObject(write, request.config);
}
} }
} }
@@ -145,28 +175,10 @@ public class TypeIO{
BuildRequest[] reqs = new BuildRequest[reqamount]; BuildRequest[] reqs = new BuildRequest[reqamount];
for(int i = 0; i < reqamount; i++){ for(int i = 0; i < reqamount; i++){
byte type = read.b(); BuildRequest request = readRequest(read);
int position = read.i(); if(request != null){
BuildRequest currentRequest; reqs[i] = request;
if(world.tile(position) == null){
continue;
} }
if(type == 1){ //remove
currentRequest = new BuildRequest(Point2.x(position), Point2.y(position));
}else{ //place
short block = read.s();
byte rotation = read.b();
boolean hasConfig = read.b() == 1;
Object config = readObject(read);
currentRequest = new BuildRequest(Point2.x(position), Point2.y(position), rotation, content.block(block));
if(hasConfig){
currentRequest.configure(config);
}
}
reqs[i] = (currentRequest);
} }
return reqs; return reqs;
@@ -193,6 +205,38 @@ public class TypeIO{
return JsonIO.read(Rules.class, string); return JsonIO.read(Rules.class, string);
} }
public static void writeVec2(Writes write, Vec2 v){
if(v == null){
write.f(0);
write.f(0);
}else{
write.f(v.x);
write.f(v.y);
}
}
public static Vec2 readVec2(Reads read){
return new Vec2(read.f(), read.f());
}
public static void writeStatuse(Writes write, StatusEntry entry){
write.s(entry.effect.id);
write.f(entry.time);
}
public static StatusEntry readStatuse(Reads read){
return Pools.obtain(StatusEntry.class, StatusEntry::new).set(content.getByID(ContentType.status, read.s()), read.f());
}
public static void writeItems(Writes write, ItemStack stack){
writeItem(write, stack.item);
write.i(stack.amount);
}
public static ItemStack readItems(Reads read){
return new ItemStack(readItem(read), read.i());
}
public static void writeTeam(Writes write, Team reason){ public static void writeTeam(Writes write, Team reason){
write.b(reason.id); write.b(reason.id);
} }

View File

@@ -23,7 +23,7 @@ import mindustry.world.blocks.environment.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
public class UnitType extends UnlockableContent{ public class UnitType extends UnlockableContent{
static final float shadowTX = -12, shadowTY = -13, shadowColor = Color.toFloatBits(0, 0, 0, 0.22f); public static final float shadowTX = -12, shadowTY = -13, shadowColor = Color.toFloatBits(0, 0, 0, 0.22f);
public boolean flying; public boolean flying;
public @NonNull Prov<? extends Unitc> constructor; public @NonNull Prov<? extends Unitc> constructor;

View File

@@ -150,10 +150,5 @@ public abstract class Weather extends MappableContent{
}); });
} }
} }
@Override
public float clipSize(){
return Float.MAX_VALUE;
}
} }
} }

View File

@@ -1,19 +1,25 @@
package mindustry.world.blocks.storage; package mindustry.world.blocks.storage;
import arc.graphics.g2d.*;
import arc.struct.*;
import arc.util.*;
import mindustry.annotations.Annotations.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.type.*; import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.meta.*; import mindustry.world.meta.*;
public class LaunchPad extends StorageBlock{ public class LaunchPad extends Block{
public final int timerLaunch = timers++; public final int timerLaunch = timers++;
/** Time inbetween launches. */ /** Time inbetween launches. */
public float launchTime; public float launchTime;
public LaunchPad(String name){ public LaunchPad(String name){
super(name); super(name);
update = true;
hasItems = true; hasItems = true;
solid = true; solid = true;
update = true;
} }
@Override @Override
@@ -23,7 +29,7 @@ public class LaunchPad extends StorageBlock{
stats.add(BlockStat.launchTime, launchTime / 60f, StatUnit.seconds); stats.add(BlockStat.launchTime, launchTime / 60f, StatUnit.seconds);
} }
public class LaunchPadEntity extends StorageBlockEntity{ public class LaunchPadEntity extends TileEntity{
@Override @Override
public void draw(){ public void draw(){
super.draw(); super.draw();
@@ -54,12 +60,16 @@ public class LaunchPad extends StorageBlock{
@Override @Override
public boolean acceptItem(Tilec source, Item item){ public boolean acceptItem(Tilec source, Item item){
return item.type == ItemType.material && super.acceptItem(source, item); return items.total() < itemCapacity;
} }
@Override @Override
public void updateTile(){ public void updateTile(){
//TODO
//launch when full
if(items.total() >= itemCapacity){
}
/* /*
if(state.isCampaign() && consValid() && items.total() >= itemCapacity && timer(timerLaunch, launchTime / timeScale())){ if(state.isCampaign() && consValid() && items.total() >= itemCapacity && timer(timerLaunch, launchTime / timeScale())){
@@ -74,4 +84,36 @@ public class LaunchPad extends StorageBlock{
}*/ }*/
} }
} }
@EntityDef(LaunchPayloadc.class)
@Component
static abstract class LaunchPayloadComp implements Drawc{
static final float speed = 1f;
@Import float x,y;
float height;
transient TextureRegion region;
Array<ItemStack> stacks = new Array<>();
@Override
public void draw(){
Draw.z(Layer.weather - 1);
Draw.rect(region, x, y);
Tmp.v1.trns(225f, height);
Draw.z(Layer.flyingUnit + 1);
Draw.color(UnitType.shadowColor);
Draw.rect(region, x + Tmp.v1.x, y + Tmp.v1.y);
Draw.reset();
}
@Override
public void update(){
height += Time.delta() * speed;
}
}
} }