Building / Fixed some tests

This commit is contained in:
Anuken
2020-02-15 14:51:31 -05:00
parent 03d0f54083
commit 8b4fcf99a6
21 changed files with 221 additions and 188 deletions

View File

@@ -3,10 +3,13 @@
mindustry.entities.def.PuddleComp=6 mindustry.entities.def.PuddleComp=6
mindustry.entities.def.BulletComp=1 mindustry.entities.def.BulletComp=1
dagger=0 dagger=0
phantom=11
mindustry.entities.def.StandardEffectComp=7 mindustry.entities.def.StandardEffectComp=7
vanguard=9 vanguard=9
mindustry.entities.def.PlayerComp=5 mindustry.entities.def.PlayerComp=5
draug=10
mindustry.entities.def.DecalComp=2 mindustry.entities.def.DecalComp=2
mindustry.entities.def.TileComp=8 mindustry.entities.def.TileComp=8
spirit=12
mindustry.entities.def.FireComp=3 mindustry.entities.def.FireComp=3
mindustry.entities.def.GroundEffectComp=4 mindustry.entities.def.GroundEffectComp=4

View File

@@ -0,0 +1 @@
{fields:[{name:drownTime,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,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}]}

View File

@@ -0,0 +1 @@
{fields:[{name:drownTime,type:float,size:4},{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: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}]}

View File

@@ -0,0 +1 @@
{fields:[{name:drownTime,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,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}]}

View File

@@ -7,12 +7,14 @@ import mindustry.type.*;
public class UnitTypes implements ContentList{ public class UnitTypes implements ContentList{
public static UnitType public static UnitType
draug, spirit, phantom,
wraith, ghoul, revenant, lich, reaper, wraith, ghoul, revenant, lich, reaper,
crawler, titan, fortress, eruptor, chaosArray, eradicator; crawler, titan, fortress, eruptor, chaosArray, eradicator;
public static @EntityDef({Unitc.class, Legsc.class}) UnitType dagger; public static @EntityDef({Unitc.class, Legsc.class}) UnitType dagger;
public static @EntityDef({Unitc.class, WaterMovec.class}) UnitType vanguard; public static @EntityDef({Unitc.class, WaterMovec.class}) UnitType vanguard;
public static @EntityDef({Unitc.class, Minerc.class}) UnitType draug;
public static @EntityDef({Unitc.class}) UnitType spirit;
public static @EntityDef({Unitc.class, Builderc.class}) UnitType phantom;
public static UnitType alpha, delta, tau, omega, dart, javelin, trident, glaive; public static UnitType alpha, delta, tau, omega, dart, javelin, trident, glaive;
public static UnitType starter; public static UnitType starter;
@@ -52,63 +54,51 @@ public class UnitTypes implements ContentList{
}}); }});
}}; }};
/* draug = new UnitType("draug"){{
draug = new UnitDef("draug", MinerDrone::new){{
flying = true; flying = true;
drag = 0.01f; drag = 0.05f;
speed = 0.3f; speed = 1.5f;
maxVelocity = 1.2f;
range = 50f; range = 50f;
health = 80; health = 80;
minePower = 0.9f; mineSpeed = 0.9f;
engineSize = 1.8f; engineSize = 1.8f;
engineOffset = 5.7f; engineOffset = 5.7f;
drillTier = 1;
}}; }};
spirit = new UnitDef("spirit", RepairDrone::new){{ spirit = new UnitType("spirit"){{
flying = true; flying = true;
drag = 0.01f; drag = 0.05f;
speed = 0.42f; speed = 1.5f;
maxVelocity = 1.6f;
range = 50f; range = 50f;
health = 100; health = 100;
engineSize = 1.8f; engineSize = 1.8f;
engineOffset = 5.7f; engineOffset = 5.7f;
weapon = new Weapon(){{ weapons.add(new Weapon(){{
length = 1.5f; y = 1.5f;
reload = 40f; reload = 40f;
width = 0.5f; x = 0.5f;
alternate = true; alternate = true;
ejectEffect = Fx.none; ejectEffect = Fx.none;
recoil = 2f; recoil = 2f;
bullet = Bullets.healBulletBig; bullet = Bullets.healBulletBig;
shootSound = Sounds.pew; shootSound = Sounds.pew;
}}; }});
}}; }};
phantom = new UnitDef("phantom", BuilderDrone::new){{ phantom = new UnitType("phantom"){{
flying = true; flying = true;
drag = 0.01f; drag = 0.05f;
mass = 2f; mass = 2f;
speed = 0.45f; speed = 1.5f;
maxVelocity = 1.9f;
range = 70f; range = 70f;
itemCapacity = 70; itemCapacity = 70;
health = 400; health = 400;
buildPower = 0.4f; buildSpeed = 0.4f;
engineOffset = 6.5f; engineOffset = 6.5f;
toMine = ObjectSet.with(Items.lead, Items.copper, Items.titanium);
weapon = new Weapon(){{
length = 1.5f;
reload = 20f;
width = 0.5f;
alternate = true;
ejectEffect = Fx.none;
recoil = 2f;
bullet = Bullets.healBullet;
}};
}}; }};
/*
dagger = new UnitDef("dagger", GroundUnit::new){{ dagger = new UnitDef("dagger", GroundUnit::new){{
maxVelocity = 1.1f; maxVelocity = 1.1f;
speed = 0.2f; speed = 0.2f;
@@ -421,7 +411,7 @@ public class UnitTypes implements ContentList{
{ {
flying = true; flying = true;
drillTier = 1; drillTier = 1;
minePower = 4f; mineSpeed = 4f;
speed = 0.49f; speed = 0.49f;
drag = 0.09f; drag = 0.09f;
health = 200f; health = 200f;
@@ -430,7 +420,7 @@ public class UnitTypes implements ContentList{
weaponOffsetY = -1; weaponOffsetY = -1;
engineColor = Pal.lightTrail; engineColor = Pal.lightTrail;
cellTrnsY = 1f; cellTrnsY = 1f;
buildPower = 1.2f; buildSpeed = 1.2f;
weapon = new Weapon("vanguard-blaster"){{ weapon = new Weapon("vanguard-blaster"){{
length = 1.5f; length = 1.5f;
reload = 30f; reload = 30f;
@@ -479,7 +469,7 @@ public class UnitTypes implements ContentList{
itemCapacity = 15; itemCapacity = 15;
mass = 0.9f; mass = 0.9f;
health = 150f; health = 150f;
buildPower = 0.9f; buildSpeed = 0.9f;
weaponOffsetX = 1; weaponOffsetX = 1;
weaponOffsetY = -1; weaponOffsetY = -1;
engineColor = Pal.heal; engineColor = Pal.heal;
@@ -519,7 +509,7 @@ public class UnitTypes implements ContentList{
speed = 0.5f; speed = 0.5f;
itemCapacity = 40; itemCapacity = 40;
boostSpeed = 0.95f; boostSpeed = 0.95f;
buildPower = 1.2f; buildSpeed = 1.2f;
engineColor = Color.valueOf("ffd37f"); engineColor = Color.valueOf("ffd37f");
health = 250f; health = 250f;
weaponOffsetX = 4f; weaponOffsetX = 4f;
@@ -559,7 +549,7 @@ public class UnitTypes implements ContentList{
boostSpeed = 0.8f; boostSpeed = 0.8f;
canHeal = true; canHeal = true;
health = 200f; health = 200f;
buildPower = 1.6f; buildSpeed = 1.6f;
engineColor = Pal.heal; engineColor = Pal.heal;
weapon = new Weapon("heal-blaster"){{ weapon = new Weapon("heal-blaster"){{
@@ -609,7 +599,7 @@ public class UnitTypes implements ContentList{
weaponOffsetY = 0; weaponOffsetY = 0;
engineColor = Color.valueOf("feb380"); engineColor = Color.valueOf("feb380");
health = 350f; health = 350f;
buildPower = 1.5f; buildSpeed = 1.5f;
weapon = new Weapon("swarmer"){{ weapon = new Weapon("swarmer"){{
length = 1.5f; length = 1.5f;
recoil = 4f; recoil = 4f;
@@ -682,7 +672,7 @@ public class UnitTypes implements ContentList{
weaponOffsetY = -1; weaponOffsetY = -1;
engineColor = Pal.lightTrail; engineColor = Pal.lightTrail;
cellTrnsY = 1f; cellTrnsY = 1f;
buildPower = 1.1f; buildSpeed = 1.1f;
weapon = new Weapon("blaster"){{ weapon = new Weapon("blaster"){{
length = 1.5f; length = 1.5f;
reload = 15f; reload = 15f;
@@ -789,7 +779,7 @@ public class UnitTypes implements ContentList{
itemCapacity = 30; itemCapacity = 30;
engineColor = Color.valueOf("84f491"); engineColor = Color.valueOf("84f491");
cellTrnsY = 1f; cellTrnsY = 1f;
buildPower = 2.5f; buildSpeed = 2.5f;
weapon = new Weapon("bomber"){{ weapon = new Weapon("bomber"){{
length = 0f; length = 0f;
width = 2f; width = 2f;
@@ -831,7 +821,7 @@ public class UnitTypes implements ContentList{
itemCapacity = 60; itemCapacity = 60;
engineColor = Color.valueOf("feb380"); engineColor = Color.valueOf("feb380");
cellTrnsY = 1f; cellTrnsY = 1f;
buildPower = 1.2f; buildSpeed = 1.2f;
weapon = new Weapon("bomber"){{ weapon = new Weapon("bomber"){{
length = 1.5f; length = 1.5f;

View File

@@ -11,6 +11,7 @@ import arc.util.serialization.*;
import mindustry.*; import mindustry.*;
import mindustry.annotations.Annotations.*; import mindustry.annotations.Annotations.*;
import mindustry.core.GameState.*; import mindustry.core.GameState.*;
import mindustry.entities.units.*;
import mindustry.game.EventType.*; import mindustry.game.EventType.*;
import mindustry.game.*; import mindustry.game.*;
import mindustry.gen.*; import mindustry.gen.*;
@@ -528,23 +529,28 @@ public class NetClient implements ApplicationListener{
} }
void sync(){ void sync(){
//TODO implement
/*
if(timer.get(0, playerSyncTime)){ if(timer.get(0, playerSyncTime)){
BuildRequest[] requests; BuildRequest[] requests = null;
//limit to 10 to prevent buffer overflows if(player.isBuilder() && control.input.isBuilding){
int usedRequests = Math.min(player.builder().requests().size, 10); //limit to 10 to prevent buffer overflows
int usedRequests = Math.min(player.builder().requests().size, 10);
requests = new BuildRequest[usedRequests]; requests = new BuildRequest[usedRequests];
for(int i = 0; i < usedRequests; i++){ for(int i = 0; i < usedRequests; i++){
requests[i] = player.builder().requests().get(i); requests[i] = player.builder().requests().get(i);
}
} }
Call.onClientShapshot(lastSent++, player.x, player.y, Unitc unit = player.dead() ? Nulls.unit : player.unit();
player.pointerX, player.pointerY, player.rotation, player.baseRotation,
player.vel().x, player.vel().y, Call.onClientShapshot(lastSent++,
unit.x(), unit.y(),
player.mouseX(), player.mouseY(),
unit.rotation(),
unit instanceof Legsc ? ((Legsc)unit).baseRotation() : 0,
unit.vel().x, unit.vel().y,
player.miner().mineTile(), player.miner().mineTile(),
player.isBoosting, player.isShooting, ui.chatfrag.shown(), player.isBuilding, /*player.isBoosting*/false, control.input.isShooting, ui.chatfrag.shown(),
requests, requests,
Core.camera.position.x, Core.camera.position.y, Core.camera.position.x, Core.camera.position.y,
Core.camera.width * viewScale, Core.camera.height * viewScale); Core.camera.width * viewScale, Core.camera.height * viewScale);
@@ -552,7 +558,7 @@ public class NetClient implements ApplicationListener{
if(timer.get(1, 60)){ if(timer.get(1, 60)){
Call.onPing(Time.millis()); Call.onPing(Time.millis());
}*/ }
} }
String getUsid(String ip){ String getUsid(String ip){

View File

@@ -10,6 +10,7 @@ import arc.util.CommandHandler.*;
import arc.util.io.*; import arc.util.io.*;
import arc.util.serialization.*; import arc.util.serialization.*;
import mindustry.annotations.Annotations.*; import mindustry.annotations.Annotations.*;
import mindustry.content.*;
import mindustry.core.GameState.*; import mindustry.core.GameState.*;
import mindustry.entities.units.*; import mindustry.entities.units.*;
import mindustry.game.EventType.*; import mindustry.game.EventType.*;
@@ -501,8 +502,6 @@ public class NetServer implements ApplicationListener{
BuildRequest[] requests, BuildRequest[] requests,
float viewX, float viewY, float viewWidth, float viewHeight float viewX, float viewY, float viewWidth, float viewHeight
){ ){
//TODO this entire thing needs to be rewritten.
/*
NetConnection connection = player.con(); NetConnection connection = player.con();
if(connection == null || snapshotID < connection.lastRecievedClientSnapshot) return; if(connection == null || snapshotID < connection.lastRecievedClientSnapshot) return;
@@ -515,78 +514,90 @@ public class NetServer implements ApplicationListener{
connection.viewWidth = viewWidth; connection.viewWidth = viewWidth;
connection.viewHeight = viewHeight; connection.viewHeight = viewHeight;
long elapsed = Time.timeSinceMillis(connection.lastRecievedClientTime);
float maxSpeed = boosting && !player.mech.flying ? player.mech.compoundSpeedBoost : player.mech.compoundSpeed;
float maxMove = elapsed / 1000f * 60f * Math.min(maxSpeed, player.mech.maxSpeed) * 1.2f;
player.mouseX(pointerX); player.mouseX(pointerX);
player.mouseY(pointerY); player.mouseY(pointerY);
player.miner().mineTile(mining); player.typing(chatting);
player.isTyping = chatting;
player.isBoosting = boosting;
player.isShooting = shooting;
player.isBuilding = building;
player.builder().requests().clear();
for(BuildRequest req : requests){ player.unit().controlWeapons(shooting, shooting);
if(req == null) continue; player.unit().aim(pointerX, pointerY);
Tile tile = world.tile(req.x, req.y);
if(tile == null || (!req.breaking && req.block == null)) continue; if(player.isBuilder()){
//auto-skip done requests player.builder().clearBuilding();
if(req.breaking && tile.block() == Blocks.air){ }
continue;
}else if(!req.breaking && tile.block() == req.block && (!req.block.rotate || tile.rotation() == req.rotation)){ if(player.isMiner()){
continue; player.miner().mineTile(mining);
}else if(connection.rejectedRequests.contains(r -> r.breaking == req.breaking && r.x == req.x && r.y == req.y)){ //check if request was recently rejected, and skip it if so }
continue;
}else if(!netServer.admins.allowAction(player, req.breaking ? ActionType.breakBlock : ActionType.placeBlock, tile, action -> { //make sure request is allowed by the server if(requests != null){
action.block = req.block; for(BuildRequest req : requests){
action.rotation = req.rotation; if(req == null) continue;
action.config = req.config; Tile tile = world.tile(req.x, req.y);
})){ if(tile == null || (!req.breaking && req.block == null)) continue;
//force the player to remove this request if that's not the case //auto-skip done requests
Call.removeQueueBlock(player.con(), req.x, req.y, req.breaking); if(req.breaking && tile.block() == Blocks.air){
connection.rejectedRequests.add(req); continue;
continue; }else if(!req.breaking && tile.block() == req.block && (!req.block.rotate || tile.rotation() == req.rotation)){
continue;
}else if(connection.rejectedRequests.contains(r -> r.breaking == req.breaking && r.x == req.x && r.y == req.y)){ //check if request was recently rejected, and skip it if so
continue;
}else if(!netServer.admins.allowAction(player, req.breaking ? ActionType.breakBlock : ActionType.placeBlock, tile, action -> { //make sure request is allowed by the server
action.block = req.block;
action.rotation = req.rotation;
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);
connection.rejectedRequests.add(req);
continue;
}
player.builder().requests().addLast(req);
} }
player.builder().requests().addLast(req);
} }
connection.rejectedRequests.clear(); connection.rejectedRequests.clear();
vector.set(x - player.getInterpolator().target.x, y - player.getInterpolator().target.y); if(!player.dead()){
vector.limit(maxMove); Unitc unit = player.unit();
long elapsed = Time.timeSinceMillis(connection.lastRecievedClientTime);
float maxSpeed = player.dead() ? Float.MAX_VALUE : player.unit().type().speed;
float maxMove = elapsed / 1000f * 60f * maxSpeed * 1.1f;
float prevx = player.x, prevy = player.y; vector.set(x - unit.interpolator().target.x, y - unit.interpolator().target.y);
player.set(player.getInterpolator().target.x, player.getInterpolator().target.y); vector.limit(maxMove);
if(!player.mech.flying && player.boostHeat < 0.01f){
player.move(vector.x, vector.y); float prevx = unit.x(), prevy = unit.y();
unit.set(unit.interpolator().target.x, unit.interpolator().target.y);
if(!unit.isFlying()){
unit.move(vector.x, vector.y);
}else{
unit.trns(vector.x, vector.y);
}
float newx = unit.x(), newy = unit.y();
if(!verifyPosition){
unit.x(prevx);
unit.y(prevy);
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
}
//reset player to previous synced position so it gets interpolated
unit.x(prevx);
unit.y(prevy);
//set interpolator target to *new* position so it moves toward it
unit.interpolator().read(unit.x(), unit.y(), newx, newy, rotation, baseRotation);
unit.vel().set(xVelocity, yVelocity); //only for visual calculation purposes, doesn't actually update the player
}else{ }else{
player.x += vector.x; player.x(x);
player.y += vector.y; player.y(y);
} }
float newx = player.x, newy = player.y;
if(!verifyPosition){
player.x = prevx;
player.y = prevy;
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
}
//reset player to previous synced position so it gets interpolated
player.x = prevx;
player.y = prevy;
//set interpolator target to *new* position so it moves toward it
player.getInterpolator().read(player.x, player.y, newx, newy, rotation, baseRotation);
player.vel().set(xVelocity, yVelocity); //only for visual calculation purposes, doesn't actually update the player
connection.lastRecievedClientSnapshot = snapshotID; connection.lastRecievedClientSnapshot = snapshotID;
connection.lastRecievedClientTime = Time.millis();*/ connection.lastRecievedClientTime = Time.millis();
} }
@Remote(targets = Loc.client, called = Loc.server) @Remote(targets = Loc.client, called = Loc.server)

View File

@@ -10,7 +10,7 @@ class AllDefs{
} }
@GroupDef(Playerc.class) @GroupDef(value = Playerc.class, mapping = true)
class player{ class player{
} }
@@ -20,7 +20,7 @@ class AllDefs{
} }
@GroupDef(value = Unitc.class, spatial = true, collide = {unit.class}) @GroupDef(value = Unitc.class, spatial = true, collide = {unit.class}, mapping = true)
class unit{ class unit{
} }
@@ -30,7 +30,7 @@ class AllDefs{
} }
@GroupDef(Syncc.class) @GroupDef(value = Syncc.class, mapping = true)
class sync{ class sync{
} }

View File

@@ -23,7 +23,7 @@ import java.util.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
@Component @Component
abstract class BuilderComp implements Unitc{ abstract class BuilderComp implements Unitc, DrawLayerFlyingc{
static final Vec2[] tmptr = new Vec2[]{new Vec2(), new Vec2(), new Vec2(), new Vec2()}; static final Vec2[] tmptr = new Vec2[]{new Vec2(), new Vec2(), new Vec2(), new Vec2()};
@Import float x, y, rotation; @Import float x, y, rotation;
@@ -32,7 +32,8 @@ abstract class BuilderComp implements Unitc{
transient float buildSpeed = 1f; transient float buildSpeed = 1f;
//boolean building; //boolean building;
void updateBuilding(){ @Override
public void update(){
float finalPlaceDst = state.rules.infiniteResources ? Float.MAX_VALUE : buildingRange; float finalPlaceDst = state.rules.infiniteResources ? Float.MAX_VALUE : buildingRange;
Iterator<BuildRequest> it = requests.iterator(); Iterator<BuildRequest> it = requests.iterator();
@@ -189,7 +190,8 @@ abstract class BuilderComp implements Unitc{
return requests.size == 0 ? null : requests.first(); return requests.size == 0 ? null : requests.first();
} }
void drawOver(){ @Override
public void drawFlying(){
if(!isBuilding()) return; if(!isBuilding()) return;
BuildRequest request = buildRequest(); BuildRequest request = buildRequest();
Tile tile = world.tile(request.x, request.y); Tile tile = world.tile(request.x, request.y);
@@ -211,7 +213,7 @@ abstract class BuilderComp implements Unitc{
tmptr[2].set(tile.drawx() - sz, tile.drawy() + sz); tmptr[2].set(tile.drawx() - sz, tile.drawy() + sz);
tmptr[3].set(tile.drawx() + sz, tile.drawy() + sz); tmptr[3].set(tile.drawx() + sz, tile.drawy() + sz);
Arrays.sort(tmptr, Structs.comparingFloat(vec -> Angles.angleDist(angleTo(vec), ang))); Arrays.sort(tmptr, Structs.comparingFloat(vec -> -Angles.angleDist(angleTo(vec), ang)));
float x1 = tmptr[0].x, y1 = tmptr[0].y, float x1 = tmptr[0].x, y1 = tmptr[0].y,
x3 = tmptr[1].x, y3 = tmptr[1].y; x3 = tmptr[1].x, y3 = tmptr[1].y;

View File

@@ -33,7 +33,8 @@ abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc{
return mineTile != null; return mineTile != null;
} }
void updateMining(){ @Override
public void update(){
Tilec core = closestCore(); Tilec core = closestCore();
if(core != null && mineTile != null && mineTile.drop() != null && !acceptsItem(mineTile.drop()) && dst(core) < mineTransferRange){ if(core != null && mineTile != null && mineTile.drop() != null && !acceptsItem(mineTile.drop()) && dst(core) < mineTransferRange){
@@ -47,6 +48,7 @@ abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc{
} }
if(mineTile == null || core == null || mineTile.block() != Blocks.air || dst(mineTile.worldx(), mineTile.worldy()) > miningRange if(mineTile == null || core == null || mineTile.block() != Blocks.air || dst(mineTile.worldx(), mineTile.worldy()) > miningRange
|| (((Object)this) instanceof Builderc && ((Builderc)(Object)this).isBuilding())
|| mineTile.drop() == null || !acceptsItem(mineTile.drop()) || !canMine(mineTile.drop())){ || mineTile.drop() == null || !acceptsItem(mineTile.drop()) || !canMine(mineTile.drop())){
mineTile = null; mineTile = null;
mineTimer = 0f; mineTimer = 0f;

View File

@@ -20,7 +20,7 @@ import static mindustry.Vars.*;
@Component @Component
abstract class UnitComp implements Healthc, Velc, Statusc, Teamc, Itemsc, Hitboxc, Rotc, Massc, Unitc, Weaponsc, Drawc, Boundedc, abstract class UnitComp implements Healthc, Velc, Statusc, Teamc, Itemsc, Hitboxc, Rotc, Massc, Unitc, Weaponsc, Drawc, Boundedc,
DrawLayerGroundc, DrawLayerFlyingc, DrawLayerGroundShadowsc, DrawLayerFlyingShadowsc, Syncc{ DrawLayerGroundc, DrawLayerFlyingc, DrawLayerGroundShadowsc, DrawLayerFlyingShadowsc, Syncc{
@Import float x, y, rotation; @Import float x, y, rotation, elevation;
private UnitController controller; private UnitController controller;
private UnitType type; private UnitType type;
@@ -83,6 +83,8 @@ abstract class UnitComp implements Healthc, Velc, Statusc, Teamc, Itemsc, Hitbox
hitSize(type.hitsize); hitSize(type.hitsize);
controller(type.createController()); controller(type.createController());
setupWeapons(type); setupWeapons(type);
elevation = type.flying ? 1f : 0f;
} }
@Override @Override
@@ -186,4 +188,22 @@ abstract class UnitComp implements Healthc, Velc, Statusc, Teamc, Itemsc, Hitbox
Events.fire(Trigger.suicideBomb); Events.fire(Trigger.suicideBomb);
} }
} }
//TODO this is bad
public boolean isPlayer(){
return controller instanceof Playerc;
}
public boolean canMine(Item item){
return type.drillTier >= item.hardness;
}
public float miningSpeed(){
return type.mineSpeed;
}
public boolean offloadImmediately(){
return false;
}
} }

View File

@@ -1,7 +1,6 @@
package mindustry.entities.units; package mindustry.entities.units;
import arc.math.*; import arc.math.*;
import arc.util.*;
import mindustry.gen.*; import mindustry.gen.*;
public class AIController implements UnitController{ public class AIController implements UnitController{
@@ -21,11 +20,12 @@ public class AIController implements UnitController{
@Override @Override
public void update(){ public void update(){
rot += Mathf.range(3f) * Time.delta(); //TODO implement
//rot += Mathf.range(3f) * Time.delta();
unit.moveAt(Tmp.v1.trns(rot, unit.type().speed)); //unit.moveAt(Tmp.v1.trns(rot, unit.type().speed));
if(!unit.vel().isZero()){ //if(!unit.vel().isZero()){
unit.lookAt(unit.vel().angle()); // unit.lookAt(unit.vel().angle());
} //}
} }
} }

View File

@@ -3,8 +3,8 @@ package mindustry.game;
import arc.util.ArcAnnotate.*; import arc.util.ArcAnnotate.*;
import mindustry.core.GameState.*; import mindustry.core.GameState.*;
import mindustry.ctype.*; import mindustry.ctype.*;
import mindustry.gen.*;
import mindustry.entities.units.*; import mindustry.entities.units.*;
import mindustry.gen.*;
import mindustry.type.*; import mindustry.type.*;
import mindustry.world.*; import mindustry.world.*;
@@ -264,14 +264,13 @@ public class EventType{
public static class BlockBuildEndEvent{ public static class BlockBuildEndEvent{
public final Tile tile; public final Tile tile;
public final Team team; public final Team team;
public final @Nullable public final @Nullable Unitc unit;
Playerc player;
public final boolean breaking; public final boolean breaking;
public BlockBuildEndEvent(Tile tile, @Nullable Playerc player, Team team, boolean breaking){ public BlockBuildEndEvent(Tile tile, @Nullable Unitc unit, Team team, boolean breaking){
this.tile = tile; this.tile = tile;
this.team = team; this.team = team;
this.player = player; this.unit = unit;
this.breaking = breaking; this.breaking = breaking;
} }
} }

View File

@@ -35,7 +35,7 @@ public class UnitType extends UnlockableContent{
public int itemCapacity = 30; public int itemCapacity = 30;
public int drillTier = -1; public int drillTier = -1;
public float buildPower = 1f, minePower = 1f; public float buildSpeed = 1f, mineSpeed = 1f;
public Color engineColor = Pal.boostTo; public Color engineColor = Pal.boostTo;
public float engineOffset = 5f, engineSize = 2.5f; public float engineOffset = 5f, engineSize = 2.5f;
@@ -46,6 +46,8 @@ public class UnitType extends UnlockableContent{
public Color lightColor = Pal.powerLight; public Color lightColor = Pal.powerLight;
public boolean drawCell = true, drawItems = true; public boolean drawCell = true, drawItems = true;
//public ObjectSet<Item> mineables = new ObjectSet<>();
public ObjectSet<StatusEffect> immunities = new ObjectSet<>(); public ObjectSet<StatusEffect> immunities = new ObjectSet<>();
public Sound deathSound = Sounds.bang; public Sound deathSound = Sounds.bang;

View File

@@ -11,6 +11,7 @@ import arc.util.io.*;
import mindustry.annotations.Annotations.*; import mindustry.annotations.Annotations.*;
import mindustry.content.*; import mindustry.content.*;
import mindustry.entities.*; import mindustry.entities.*;
import mindustry.entities.units.*;
import mindustry.game.EventType.*; import mindustry.game.EventType.*;
import mindustry.game.*; import mindustry.game.*;
import mindustry.gen.*; import mindustry.gen.*;
@@ -20,8 +21,6 @@ import mindustry.ui.*;
import mindustry.world.*; import mindustry.world.*;
import mindustry.world.modules.*; import mindustry.world.modules.*;
import java.io.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
public class BuildBlock extends Block{ public class BuildBlock extends Block{
@@ -55,7 +54,7 @@ public class BuildBlock extends Block{
public static void onDeconstructFinish(Tile tile, Block block, int builderID){ public static void onDeconstructFinish(Tile tile, Block block, int builderID){
Team team = tile.team(); Team team = tile.team();
Fx.breakBlock.at(tile.drawx(), tile.drawy(), block.size); Fx.breakBlock.at(tile.drawx(), tile.drawy(), block.size);
Events.fire(new BlockBuildEndEvent(tile, Groups.player.getByID(builderID), team, true)); Events.fire(new BlockBuildEndEvent(tile, Groups.unit.getByID(builderID), team, true));
tile.remove(); tile.remove();
if(shouldPlay()) Sounds.breaks.at(tile, calcPitch(false)); if(shouldPlay()) Sounds.breaks.at(tile, calcPitch(false));
} }
@@ -105,7 +104,7 @@ public class BuildBlock extends Block{
Call.onConstructFinish(tile, block, builderID, rotation, team, skipConfig); Call.onConstructFinish(tile, block, builderID, rotation, team, skipConfig);
tile.block().placed(tile); tile.block().placed(tile);
Events.fire(new BlockBuildEndEvent(tile, Groups.player.getByID(builderID), team, false)); Events.fire(new BlockBuildEndEvent(tile, Groups.unit.getByID(builderID), team, false));
if(shouldPlay()) Sounds.place.at(tile, calcPitch(true)); if(shouldPlay()) Sounds.place.at(tile, calcPitch(true));
} }
@@ -141,16 +140,13 @@ public class BuildBlock extends Block{
public void tapped(Tile tile, Playerc player){ public void tapped(Tile tile, Playerc player){
BuildEntity entity = tile.ent(); BuildEntity entity = tile.ent();
//TODO building
/*
//if the target is constructible, begin constructing //if the target is constructible, begin constructing
if(entity.cblock != null){ if(!headless && entity.cblock != null){
if(player.buildWasAutoPaused && !player.isBuilding){ if(control.input.buildWasAutoPaused && !control.input.isBuilding && player.isBuilder()){
player.isBuilding = true; control.input.isBuilding = true;
} }
//player.clearBuilding();
player.builder().addBuild(new BuildRequest(tile.x, tile.y, tile.rotation(), entity.cblock), false); player.builder().addBuild(new BuildRequest(tile.x, tile.y, tile.rotation(), entity.cblock), false);
}*/ }
} }
@Override @Override
@@ -281,9 +277,7 @@ public class BuildBlock extends Block{
progress = Mathf.clamp(progress - amount); progress = Mathf.clamp(progress - amount);
if(builder instanceof Playerc){ builderID = builder.id();
builderID = builder.id();
}
if(progress <= 0 || state.rules.infiniteResources){ if(progress <= 0 || state.rules.infiniteResources){
Call.onDeconstructFinish(tile, this.cblock == null ? previous : this.cblock, builderID); Call.onDeconstructFinish(tile, this.cblock == null ? previous : this.cblock, builderID);

View File

@@ -105,7 +105,7 @@ public class SStats implements SteamUserStatsCallback{
}); });
Events.on(BlockBuildEndEvent.class, e -> { Events.on(BlockBuildEndEvent.class, e -> {
if(campaign() && e.player == player && !e.breaking){ if(campaign() && e.unit != null && e.unit.isLocal() && !e.breaking){
SStat.blocksBuilt.add(); SStat.blocksBuilt.add();
if(e.tile.block() == Blocks.router && e.tile.entity.proximity().contains(t -> t.block() == Blocks.router)){ if(e.tile.block() == Blocks.router && e.tile.entity.proximity().contains(t -> t.block() == Blocks.router)){

View File

@@ -8,9 +8,9 @@ import mindustry.content.*;
import mindustry.core.*; import mindustry.core.*;
import mindustry.core.GameState.*; import mindustry.core.GameState.*;
import mindustry.ctype.*; import mindustry.ctype.*;
import mindustry.entities.type.base.*;
import mindustry.entities.units.*; import mindustry.entities.units.*;
import mindustry.game.*; import mindustry.game.*;
import mindustry.gen.*;
import mindustry.io.*; import mindustry.io.*;
import mindustry.maps.*; import mindustry.maps.*;
import mindustry.net.Net; import mindustry.net.Net;
@@ -103,8 +103,8 @@ public class ApplicationTests{
Time.update(); Time.update();
Time.update(); Time.update();
Time.setDeltaProvider(() -> 1f); Time.setDeltaProvider(() -> 1f);
unitGroup.update(); Groups.unit.update();
assertFalse(unitGroup.isEmpty(), "No enemies spawned."); assertFalse(Groups.unit.isEmpty(), "No enemies spawned.");
} }
@Test @Test
@@ -335,18 +335,18 @@ public class ApplicationTests{
void buildingOverlap(){ void buildingOverlap(){
initBuilding(); initBuilding();
BuilderDrone d1 = (BuilderDrone)UnitTypes.phantom.create(Team.sharded); Builderc d1 = (Builderc)UnitTypes.phantom.create(Team.sharded);
BuilderDrone d2 = (BuilderDrone)UnitTypes.phantom.create(Team.sharded); Builderc d2 = (Builderc)UnitTypes.phantom.create(Team.sharded);
d1.set(10f, 20f); d1.set(10f, 20f);
d2.set(10f, 20f); d2.set(10f, 20f);
d1.addBuildRequest(new BuildRequest(0, 0, 0, Blocks.copperWallLarge)); d1.addBuild(new BuildRequest(0, 0, 0, Blocks.copperWallLarge));
d2.addBuildRequest(new BuildRequest(1, 1, 0, Blocks.copperWallLarge)); d2.addBuild(new BuildRequest(1, 1, 0, Blocks.copperWallLarge));
Time.setDeltaProvider(() -> 9999999f); Time.setDeltaProvider(() -> 9999999f);
d1.updateBuilding(); d1.update();
d2.updateBuilding(); d2.update();
assertEquals(Blocks.copperWallLarge, world.tile(0, 0).block()); assertEquals(Blocks.copperWallLarge, world.tile(0, 0).block());
assertEquals(Blocks.air, world.tile(2, 2).block()); assertEquals(Blocks.air, world.tile(2, 2).block());
@@ -357,26 +357,26 @@ public class ApplicationTests{
void buildingDestruction(){ void buildingDestruction(){
initBuilding(); initBuilding();
BuilderDrone d1 = (BuilderDrone)UnitTypes.phantom.create(Team.sharded); Builderc d1 = (Builderc)UnitTypes.phantom.create(Team.sharded);
BuilderDrone d2 = (BuilderDrone)UnitTypes.phantom.create(Team.sharded); Builderc d2 = (Builderc)UnitTypes.phantom.create(Team.sharded);
d1.set(10f, 20f); d1.set(10f, 20f);
d2.set(10f, 20f); d2.set(10f, 20f);
d1.addBuildRequest(new BuildRequest(0, 0, 0, Blocks.copperWallLarge)); d1.addBuild(new BuildRequest(0, 0, 0, Blocks.copperWallLarge));
d2.addBuildRequest(new BuildRequest(1, 1)); d2.addBuild(new BuildRequest(1, 1));
Time.setDeltaProvider(() -> 3f); Time.setDeltaProvider(() -> 3f);
d1.updateBuilding(); d1.update();
Time.setDeltaProvider(() -> 1f); Time.setDeltaProvider(() -> 1f);
d2.updateBuilding(); d2.update();
assertEquals(content.getByName(ContentType.block, "build2"), world.tile(0, 0).block()); assertEquals(content.getByName(ContentType.block, "build2"), world.tile(0, 0).block());
Time.setDeltaProvider(() -> 9999f); Time.setDeltaProvider(() -> 9999f);
d1.updateBuilding(); d1.update();
d2.updateBuilding(); d2.update();
assertEquals(Blocks.air, world.tile(0, 0).block()); assertEquals(Blocks.air, world.tile(0, 0).block());
assertEquals(Blocks.air, world.tile(2, 2).block()); assertEquals(Blocks.air, world.tile(2, 2).block());
@@ -414,8 +414,8 @@ public class ApplicationTests{
}catch(Throwable t){ }catch(Throwable t){
fail("Failed to update block '" + tile.block() + "'.", t); fail("Failed to update block '" + tile.block() + "'.", t);
} }
assertEquals(tile.block(), tile.entity.block); assertEquals(tile.block(), tile.entity.block());
assertEquals(tile.block().health, tile.entity.health); assertEquals(tile.block().health, tile.entity.health());
} }
} }
} }

View File

@@ -1,12 +1,9 @@
import arc.util.*; import arc.util.*;
import arc.util.io.*; import arc.util.io.*;
import mindustry.content.*;
import mindustry.game.*; import mindustry.game.*;
import mindustry.gen.*;
import mindustry.io.*; import mindustry.io.*;
import org.junit.jupiter.api.*; import org.junit.jupiter.api.*;
import java.io.*;
import java.nio.*; import java.nio.*;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
@@ -50,9 +47,9 @@ public class IOTests{
rules.attackMode = true; rules.attackMode = true;
rules.buildSpeedMultiplier = 99f; rules.buildSpeedMultiplier = 99f;
TypeIO.writeRules(buffer, rules); TypeIO.writeRules(new Writes(new ByteBufferOutput(buffer)), rules);
buffer.position(0); buffer.position(0);
Rules res = TypeIO.readRules(buffer); Rules res = TypeIO.readRules(new Reads(new ByteBufferInput(buffer)));
assertEquals(rules.buildSpeedMultiplier, res.buildSpeedMultiplier); assertEquals(rules.buildSpeedMultiplier, res.buildSpeedMultiplier);
assertEquals(rules.attackMode, res.attackMode); assertEquals(rules.attackMode, res.attackMode);

View File

@@ -37,8 +37,8 @@ public class DirectConsumerTests extends PowerTestFixture{
consumes.power(requestedPower); consumes.power(requestedPower);
consumes.items(new ItemStack(Items.silicon, 30), new ItemStack(Items.lead, 30)); consumes.items(new ItemStack(Items.silicon, 30), new ItemStack(Items.lead, 30));
}}); }});
consumertile.entity.items().add(Items.silicon, siliconAmount); consumerTile.entity.items().add(Items.silicon, siliconAmount);
consumertile.entity.items().add(Items.lead, leadAmount); consumerTile.entity.items().add(Items.lead, leadAmount);
Tile producerTile = createFakeTile(2, 0, createFakeProducerBlock(producedPower)); Tile producerTile = createFakeTile(2, 0, createFakeProducerBlock(producedPower));
producerTile.<PowerGenerator.GeneratorEntity>ent().productionEfficiency = 1f; producerTile.<PowerGenerator.GeneratorEntity>ent().productionEfficiency = 1f;
@@ -50,6 +50,6 @@ public class DirectConsumerTests extends PowerTestFixture{
consumerTile.entity.update(); consumerTile.entity.update();
graph.update(); graph.update();
assertEquals(expectedSatisfaction, consumertile.entity.power().status); assertEquals(expectedSatisfaction, consumerTile.entity.power().status);
} }
} }

View File

@@ -1,6 +1,7 @@
package power; package power;
import arc.*; import arc.*;
import arc.mock.*;
import arc.util.*; import arc.util.*;
import mindustry.*; import mindustry.*;
import mindustry.content.*; import mindustry.content.*;
@@ -14,7 +15,7 @@ import org.junit.jupiter.api.*;
import java.lang.reflect.*; import java.lang.reflect.*;
import static mindustry.Vars.content; import static mindustry.Vars.*;
/** /**
* This class provides objects commonly used by power related unit tests. * This class provides objects commonly used by power related unit tests.
@@ -26,8 +27,11 @@ public class PowerTestFixture{
@BeforeAll @BeforeAll
static void initializeDependencies(){ static void initializeDependencies(){
headless = true;
Core.graphics = new FakeGraphics(); Core.graphics = new FakeGraphics();
Core.files = new MockFiles();
Vars.state = new GameState(); Vars.state = new GameState();
Vars.tree = new FileTree();
Vars.content = new ContentLoader(){ Vars.content = new ContentLoader(){
@Override @Override
public void handleMappableContent(MappableContent content){ public void handleMappableContent(MappableContent content){
@@ -87,11 +91,11 @@ public class PowerTestFixture{
// 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.entity = block.newEntity().init(tile, false); tile.entity = block.newEntity().init(tile, false);
tile.entity.cons() = new ConsumeModule(tile.entity); tile.entity.cons(new ConsumeModule(tile.entity));
if(block.hasItems) tile.entity.items() = new ItemModule(); if(block.hasItems) tile.entity.items(new ItemModule());
if(block.hasLiquids) tile.entity.liquids() = new LiquidModule(); if(block.hasLiquids) tile.entity.liquids(new LiquidModule());
if(block.hasPower){ if(block.hasPower){
tile.entity.power() = new PowerModule(); tile.entity.power(new PowerModule());
tile.entity.power().graph = new PowerGraph(){ tile.entity.power().graph = new PowerGraph(){
//assume there's always something consuming power //assume there's always something consuming power
@Override @Override
@@ -104,7 +108,7 @@ public class PowerTestFixture{
// Assign incredibly high health so the block does not get destroyed on e.g. burning Blast Compound // Assign incredibly high health so the block does not get destroyed on e.g. burning Blast Compound
block.health = 100000; block.health = 100000;
tile.entity.health = 100000.0f; tile.entity.health(100000.0f);
return tile; return tile;
}catch(Exception ex){ }catch(Exception ex){

View File

@@ -66,7 +66,7 @@ public class PowerTests extends PowerTestFixture{
// Update and check for the expected power status of the consumer // Update and check for the expected power status of the consumer
powerGraph.update(); powerGraph.update();
assertEquals(expectedSatisfaction, directConsumertile.entity.power().status, Mathf.FLOAT_ROUNDING_ERROR, parameterDescription + ": Satisfaction of direct consumer did not match"); assertEquals(expectedSatisfaction, directConsumerTile.entity.power().status, Mathf.FLOAT_ROUNDING_ERROR, parameterDescription + ": Satisfaction of direct consumer did not match");
} }
/** /**
@@ -104,14 +104,14 @@ public class PowerTests extends PowerTestFixture{
} }
float maxCapacity = 100f; float maxCapacity = 100f;
Tile batteryTile = createFakeTile(0, 2, createFakeBattery(maxCapacity)); Tile batteryTile = createFakeTile(0, 2, createFakeBattery(maxCapacity));
batterytile.entity.power().status = initialBatteryCapacity / maxCapacity; batteryTile.entity.power().status = initialBatteryCapacity / maxCapacity;
powerGraph.add(batteryTile); powerGraph.add(batteryTile);
powerGraph.update(); powerGraph.update();
assertEquals(expectedBatteryCapacity / maxCapacity, batterytile.entity.power().status, Mathf.FLOAT_ROUNDING_ERROR, parameterDescription + ": Expected battery status did not match"); assertEquals(expectedBatteryCapacity / maxCapacity, batteryTile.entity.power().status, Mathf.FLOAT_ROUNDING_ERROR, parameterDescription + ": Expected battery status did not match");
if(directConsumerTile != null){ if(directConsumerTile != null){
assertEquals(expectedSatisfaction, directConsumertile.entity.power().status, Mathf.FLOAT_ROUNDING_ERROR, parameterDescription + ": Satisfaction of direct consumer did not match"); assertEquals(expectedSatisfaction, directConsumerTile.entity.power().status, Mathf.FLOAT_ROUNDING_ERROR, parameterDescription + ": Satisfaction of direct consumer did not match");
} }
} }
@@ -127,13 +127,13 @@ public class PowerTests extends PowerTestFixture{
powerGraph.add(consumerTile); powerGraph.add(consumerTile);
powerGraph.update(); powerGraph.update();
assertEquals(1.0f, consumertile.entity.power().status, Mathf.FLOAT_ROUNDING_ERROR); assertEquals(1.0f, consumerTile.entity.power().status, Mathf.FLOAT_ROUNDING_ERROR);
powerGraph.remove(producerTile); powerGraph.remove(producerTile);
powerGraph.add(consumerTile); powerGraph.add(consumerTile);
powerGraph.update(); powerGraph.update();
assertEquals(0.0f, consumertile.entity.power().status, Mathf.FLOAT_ROUNDING_ERROR); assertEquals(0.0f, consumerTile.entity.power().status, Mathf.FLOAT_ROUNDING_ERROR);
if(consumerTile.block().consumes.hasPower()){ if(consumerTile.block().consumes.hasPower()){
ConsumePower consumePower = consumerTile.block().consumes.getPower(); ConsumePower consumePower = consumerTile.block().consumes.getPower();
assertFalse(consumePower.valid(consumerTile.ent())); assertFalse(consumePower.valid(consumerTile.ent()));