This commit is contained in:
Anuken
2020-09-12 12:47:18 -04:00
parent 197b67f8c1
commit fa9611e28c
14 changed files with 64 additions and 45 deletions

View File

@@ -43,6 +43,7 @@ public class PhysicsProcess implements AsyncProcess{
//find entities without bodies and assign them //find entities without bodies and assign them
for(Physicsc entity : group){ for(Physicsc entity : group){
boolean grounded = entity.isGrounded(); boolean grounded = entity.isGrounded();
int bits = grounded ? flying.maskBits : ground.maskBits;
if(entity.physref() == null){ if(entity.physref() == null){
//add bodies to entities that have none //add bodies to entities that have none
@@ -66,12 +67,9 @@ public class PhysicsProcess implements AsyncProcess{
//save last position //save last position
PhysicRef ref = entity.physref(); PhysicRef ref = entity.physref();
if(ref.wasGround != grounded){ if(ref.body.getFixtureList().any() && ref.body.getFixtureList().first().getFilterData().categoryBits != bits){
if(ref.body.getFixtureList().isEmpty()) continue;
//set correct filter //set correct filter
ref.body.getFixtureList().first().setFilterData(grounded ? ground : flying); ref.body.getFixtureList().first().setFilterData(grounded ? ground : flying);
ref.wasGround = grounded;
} }
ref.velocity.set(entity.deltaX(), entity.deltaY()); ref.velocity.set(entity.deltaX(), entity.deltaY());
@@ -143,10 +141,9 @@ public class PhysicsProcess implements AsyncProcess{
} }
public static class PhysicRef{ public static class PhysicRef{
Physicsc entity; public Physicsc entity;
Body body; public Body body;
boolean wasGround = true; public Vec2 lastPosition = new Vec2(), delta = new Vec2(), velocity = new Vec2(), lastVelocity = new Vec2(), position = new Vec2();
Vec2 lastPosition = new Vec2(), delta = new Vec2(), velocity = new Vec2(), lastVelocity = new Vec2(), position = new Vec2();
public PhysicRef(Physicsc entity, Body body){ public PhysicRef(Physicsc entity, Body body){
this.entity = entity; this.entity = entity;

View File

@@ -485,7 +485,7 @@ public class NetServer implements ApplicationListener{
data.stream = new ByteArrayInputStream(stream.toByteArray()); data.stream = new ByteArrayInputStream(stream.toByteArray());
player.con.sendStream(data); player.con.sendStream(data);
Log.debug("Packed @ invalid world data.", stream.size()); Log.debug("Packed @ bytes of world data.", stream.size());
} }
public void addPacketHandler(String type, Cons2<Player, String> handler){ public void addPacketHandler(String type, Cons2<Player, String> handler){

View File

@@ -99,7 +99,7 @@ public class Units{
nearby(x, y, width, height, unit -> { nearby(x, y, width, height, unit -> {
if(boolResult) return; if(boolResult) return;
if(unit.isGrounded() == ground){ if((unit.isGrounded() && !unit.type().hovering) == ground){
unit.hitbox(hitrect); unit.hitbox(hitrect);
if(hitrect.overlaps(x, y, width, height)){ if(hitrect.overlaps(x, y, width, height)){

View File

@@ -30,6 +30,30 @@ abstract class LegsComp implements Posc, Rotc, Hitboxc, Flyingc, Unitc{
collisions.moveCheck(this, cx, cy, !type.allowLegStep ? EntityCollisions::solid : EntityCollisions::legsSolid); collisions.moveCheck(this, cx, cy, !type.allowLegStep ? EntityCollisions::solid : EntityCollisions::legsSolid);
} }
@Override
public void add(){
resetLegs();
}
public void resetLegs(){
float rot = baseRotation;
int count = type.legCount;
float legLength = type.legLength;
this.legs = new Leg[count];
float spacing = 360f / count;
for(int i = 0; i < legs.length; i++){
Leg l = new Leg();
l.joint.trns(i * spacing + rot, legLength/2f + type.legBaseOffset).add(x, y);
l.base.trns(i * spacing + rot, legLength + type.legBaseOffset).add(x, y);
legs[i] = l;
}
}
@Override @Override
public void update(){ public void update(){
if(Mathf.dst(deltaX(), deltaY()) > 0.001f){ if(Mathf.dst(deltaX(), deltaY()) > 0.001f){
@@ -37,23 +61,11 @@ abstract class LegsComp implements Posc, Rotc, Hitboxc, Flyingc, Unitc{
} }
float rot = baseRotation; float rot = baseRotation;
int count = type.legCount;
float legLength = type.legLength; float legLength = type.legLength;
//set up initial leg positions //set up initial leg positions
if(legs.length != type.legCount){ if(legs.length != type.legCount){
this.legs = new Leg[count]; resetLegs();
float spacing = 360f / count;
for(int i = 0; i < legs.length; i++){
Leg l = new Leg();
l.joint.trns(i * spacing + rot, legLength/2f + type.legBaseOffset).add(x, y);
l.base.trns(i * spacing + rot, legLength + type.legBaseOffset).add(x, y);
legs[i] = l;
}
} }
float moveSpeed = type.legSpeed; float moveSpeed = type.legSpeed;

View File

@@ -22,7 +22,7 @@ public class Scripts implements Disposable{
private final Seq<String> blacklist = Seq.with(".net.", "java.net", "files", "reflect", "javax", "rhino", "file", "channels", "jdk", private final Seq<String> blacklist = Seq.with(".net.", "java.net", "files", "reflect", "javax", "rhino", "file", "channels", "jdk",
"runtime", "util.os", "rmi", "security", "org.", "sun.", "beans", "sql", "http", "exec", "compiler", "process", "system", "runtime", "util.os", "rmi", "security", "org.", "sun.", "beans", "sql", "http", "exec", "compiler", "process", "system",
".awt", "socket", "classloader", "oracle", "invoke", "java.util.function", "java.util.stream", "org."); ".awt", "socket", "classloader", "oracle", "invoke", "java.util.function", "java.util.stream", "org.");
private final Seq<String> whitelist = Seq.with("mindustry.net", "netserver", "netclient", "com.sun.proxy.$proxy", "mindustry.gen.", "mindustry.logic."); private final Seq<String> whitelist = Seq.with("mindustry.net", "netserver", "netclient", "com.sun.proxy.$proxy", "mindustry.gen.", "mindustry.logic.", "mindustry.async.");
private final Context context; private final Context context;
private final Scriptable scope; private final Scriptable scope;
private boolean errored; private boolean errored;

View File

@@ -112,6 +112,17 @@ public class UnitType extends UnlockableContent{
return unit; return unit;
} }
public Unit spawn(Team team, float x, float y){
Unit out = create(team);
out.set(x, y);
out.add();
return out;
}
public Unit spawn(float x, float y){
return spawn(state.rules.defaultTeam, x, y);
}
public boolean hasWeapons(){ public boolean hasWeapons(){
return weapons.size > 0; return weapons.size > 0;
} }

View File

@@ -196,7 +196,7 @@ public class Block extends UnlockableContent{
/** Whether this block has instant transfer.*/ /** Whether this block has instant transfer.*/
public boolean instantTransfer = false; public boolean instantTransfer = false;
protected Prov<Building> entityType = null; //initialized later public Prov<Building> buildType = null; //initialized later
public ObjectMap<Class<?>, Cons2> configurations = new ObjectMap<>(); public ObjectMap<Class<?>, Cons2> configurations = new ObjectMap<>();
protected TextureRegion[] generatedIcons; protected TextureRegion[] generatedIcons;
@@ -217,7 +217,7 @@ public class Block extends UnlockableContent{
public Block(String name){ public Block(String name){
super(name); super(name);
initEntity(); initBuilding();
} }
public void drawBase(Tile tile){ public void drawBase(Tile tile){
@@ -499,8 +499,8 @@ public class Block extends UnlockableContent{
return destructible || update; return destructible || update;
} }
public final Building newEntity(){ public final Building newBuilding(){
return entityType.get(); return buildType.get();
} }
public Rect bounds(int x, int y, Rect rect){ public Rect bounds(int x, int y, Rect rect){
@@ -576,7 +576,7 @@ public class Block extends UnlockableContent{
Arrays.sort(requirements, Structs.comparingInt(i -> i.item.id)); Arrays.sort(requirements, Structs.comparingInt(i -> i.item.id));
} }
protected void initEntity(){ protected void initBuilding(){
//attempt to find the first declared class and use it as the entity type //attempt to find the first declared class and use it as the entity type
try{ try{
Class<?> current = getClass(); Class<?> current = getClass();
@@ -585,13 +585,13 @@ public class Block extends UnlockableContent{
current = current.getSuperclass(); current = current.getSuperclass();
} }
while(entityType == null && Block.class.isAssignableFrom(current)){ while(buildType == null && Block.class.isAssignableFrom(current)){
//first class that is subclass of Building //first class that is subclass of Building
Class<?> type = Structs.find(current.getDeclaredClasses(), t -> Building.class.isAssignableFrom(t) && !t.isInterface()); Class<?> type = Structs.find(current.getDeclaredClasses(), t -> Building.class.isAssignableFrom(t) && !t.isInterface());
if(type != null){ if(type != null){
//these are inner classes, so they have an implicit parameter generated //these are inner classes, so they have an implicit parameter generated
Constructor<? extends Building> cons = (Constructor<? extends Building>)type.getDeclaredConstructor(type.getDeclaringClass()); Constructor<? extends Building> cons = (Constructor<? extends Building>)type.getDeclaredConstructor(type.getDeclaringClass());
entityType = () -> { buildType = () -> {
try{ try{
return cons.newInstance(this); return cons.newInstance(this);
}catch(Exception e){ }catch(Exception e){
@@ -607,9 +607,9 @@ public class Block extends UnlockableContent{
}catch(Throwable ignored){ }catch(Throwable ignored){
} }
if(entityType == null){ if(buildType == null){
//assign default value //assign default value
entityType = Building::create; buildType = Building::create;
} }
} }

View File

@@ -45,7 +45,7 @@ public class Tile implements Position, QuadTreeObject, Displayable{
this.block = wall; this.block = wall;
//update entity and create it if needed //update entity and create it if needed
changeEntity(Team.derelict, wall::newEntity, 0); changeEntity(Team.derelict, wall::newBuilding, 0);
changed(); changed();
} }
@@ -174,7 +174,7 @@ public class Tile implements Position, QuadTreeObject, Displayable{
} }
public void setBlock(@NonNull Block type, Team team, int rotation){ public void setBlock(@NonNull Block type, Team team, int rotation){
setBlock(type, team, rotation, type::newEntity); setBlock(type, team, rotation, type::newBuilding);
} }
public void setBlock(@NonNull Block type, Team team, int rotation, Prov<Building> entityprov){ public void setBlock(@NonNull Block type, Team team, int rotation, Prov<Building> entityprov){

View File

@@ -103,9 +103,8 @@ public class Floor extends Block{
super.init(); super.init();
if(wall == Blocks.air){ if(wall == Blocks.air){
wall = content.block(name + "Rocks"); wall = content.block(name + "-wall");
if(wall == null) wall = content.block(name + "rocks"); if(wall == null) wall = content.block(name.replace("darksand", "dune") + "-wall");
if(wall == null) wall = content.block(name.replace("darksand", "dune") + "rocks");
} }
//keep default value if not found... //keep default value if not found...

View File

@@ -14,7 +14,7 @@ public class BlockPayload implements Payload{
public Building entity; public Building entity;
public BlockPayload(Block block, Team team){ public BlockPayload(Block block, Team team){
this.entity = block.newEntity().create(block, team); this.entity = block.newBuilding().create(block, team);
} }
public BlockPayload(Building entity){ public BlockPayload(Building entity){

View File

@@ -377,7 +377,7 @@ public class ApplicationTests{
world.tile(length + 1, 0).setBlock(new Block("___"){{ world.tile(length + 1, 0).setBlock(new Block("___"){{
hasItems = true; hasItems = true;
destructible = true; destructible = true;
entityType = () -> new Building(){ buildType = () -> new Building(){
@Override @Override
public void handleItem(Building source, Item item){ public void handleItem(Building source, Item item){
itemsa[0] ++; itemsa[0] ++;

View File

@@ -39,7 +39,7 @@ public class ItemLiquidGeneratorTests extends PowerTestFixture{
powerProduction = 0.1f; powerProduction = 0.1f;
itemDuration = fakeItemDuration; itemDuration = fakeItemDuration;
maxLiquidGenerate = maximumLiquidUsage; maxLiquidGenerate = maximumLiquidUsage;
entityType = ItemLiquidGeneratorBuild::new; buildType = ItemLiquidGeneratorBuild::new;
} }
@Override @Override

View File

@@ -43,21 +43,21 @@ public class PowerTestFixture{
protected static PowerGenerator createFakeProducerBlock(float producedPower){ protected static PowerGenerator createFakeProducerBlock(float producedPower){
return new PowerGenerator("fakegen"){{ return new PowerGenerator("fakegen"){{
entityType = () -> new GeneratorBuild(); buildType = () -> new GeneratorBuild();
powerProduction = producedPower; powerProduction = producedPower;
}}; }};
} }
protected static Battery createFakeBattery(float capacity){ protected static Battery createFakeBattery(float capacity){
return new Battery("fakebattery"){{ return new Battery("fakebattery"){{
entityType = () -> new BatteryBuild(); buildType = () -> new BatteryBuild();
consumes.powerBuffered(capacity); consumes.powerBuffered(capacity);
}}; }};
} }
protected static Block createFakeDirectConsumer(float powerPerTick){ protected static Block createFakeDirectConsumer(float powerPerTick){
return new PowerBlock("fakedirectconsumer"){{ return new PowerBlock("fakedirectconsumer"){{
entityType = Building::create; buildType = Building::create;
consumes.power(powerPerTick); consumes.power(powerPerTick);
}}; }};
} }
@@ -86,7 +86,7 @@ public class PowerTestFixture{
Reflect.set(Tile.class, tile, "floor", Blocks.sand); Reflect.set(Tile.class, tile, "floor", Blocks.sand);
// Simulate the "changed" method. Calling it through reflections would require half the game to be initialized. // Simulate the "changed" method. Calling it through reflections would require half the game to be initialized.
tile.build = block.newEntity().init(tile, Team.sharded, false, 0); tile.build = block.newBuilding().init(tile, Team.sharded, false, 0);
if(block.hasPower){ if(block.hasPower){
tile.build.power.graph = new PowerGraph(){ tile.build.power.graph = new PowerGraph(){
//assume there's always something consuming power //assume there's always something consuming power