AI tweaks / Control tweaks / Plastanium conveyor tweaks / Unit factories
@ -11,5 +11,6 @@ mindustry.entities.def.PuddleComp=7
|
||||
mindustry.entities.def.TileComp=8
|
||||
mindustry.type.Weather.WeatherComp=9
|
||||
phantom=10
|
||||
titan=13
|
||||
vanguard=11
|
||||
wraith=12
|
BIN
core/assets-raw/sprites/blocks/units/naval-factory-top.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
core/assets-raw/sprites/blocks/units/naval-factory.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
@ -230,3 +230,5 @@
|
||||
63514=block-launcher|block-block-launcher-medium
|
||||
63513=plastanium-conveyor|block-plastanium-conveyor-medium
|
||||
63512=crater|crater
|
||||
63511=naval-factory|block-naval-factory-medium
|
||||
63510=air-factory|block-air-factory-medium
|
||||
|
Before Width: | Height: | Size: 717 B After Width: | Height: | Size: 723 B |
Before Width: | Height: | Size: 708 KiB After Width: | Height: | Size: 714 KiB |
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 127 KiB |
Before Width: | Height: | Size: 226 KiB After Width: | Height: | Size: 222 KiB |
Before Width: | Height: | Size: 828 KiB After Width: | Height: | Size: 837 KiB |
@ -3,7 +3,6 @@ package mindustry.ai.types;
|
||||
import arc.math.*;
|
||||
import arc.math.geom.*;
|
||||
import arc.util.*;
|
||||
import mindustry.*;
|
||||
import mindustry.entities.*;
|
||||
import mindustry.entities.units.*;
|
||||
import mindustry.world.meta.*;
|
||||
@ -33,7 +32,7 @@ public class FlyingAI extends AIController{
|
||||
|
||||
boolean shoot = false;
|
||||
|
||||
if(target != null){
|
||||
if(target != null && unit.hasWeapons()){
|
||||
attack(80f);
|
||||
|
||||
shoot = unit.inRange(target);
|
||||
@ -42,9 +41,6 @@ public class FlyingAI extends AIController{
|
||||
Vec2 to = Predict.intercept(unit, target, unit.type().weapons.first().bullet.speed);
|
||||
unit.aim(to);
|
||||
}
|
||||
}else{
|
||||
target = unit.closestCore();
|
||||
moveTo(Vars.state.rules.dropZoneRadius + 120f);
|
||||
}
|
||||
|
||||
unit.controlWeapons(shoot, shoot);
|
||||
|
@ -77,7 +77,7 @@ public class Blocks implements ContentList{
|
||||
duo, scatter, scorch, hail, arc, wave, lancer, swarmer, salvo, fuse, ripple, cyclone, spectre, meltdown,
|
||||
|
||||
//units
|
||||
groundFactory, repairPoint,
|
||||
groundFactory, airFactory, navalFactory, repairPoint,
|
||||
|
||||
//misc experimental
|
||||
|
||||
@ -1669,14 +1669,40 @@ public class Blocks implements ContentList{
|
||||
//region units
|
||||
|
||||
//for testing only.
|
||||
|
||||
groundFactory = new UnitFactory("ground-factory"){{
|
||||
requirements(Category.units, ItemStack.with(Items.copper, 30, Items.lead, 70));
|
||||
plans = new UnitPlan[]{
|
||||
new UnitPlan(UnitTypes.dagger, 60f, ItemStack.with(Items.silicon, 10)),
|
||||
new UnitPlan(UnitTypes.wraith, 60f, ItemStack.with(Items.silicon, 10)),
|
||||
new UnitPlan(UnitTypes.dagger, 200f, ItemStack.with(Items.silicon, 10)),
|
||||
new UnitPlan(UnitTypes.titan, 400f, ItemStack.with(Items.silicon, 10)),
|
||||
};
|
||||
size = 3;
|
||||
consumes.power(1.2f);
|
||||
//TODO this is incorrect
|
||||
consumes.items(new ItemStack(Items.silicon, 10));
|
||||
}};
|
||||
|
||||
airFactory = new UnitFactory("air-factory"){{
|
||||
requirements(Category.units, ItemStack.with(Items.copper, 30, Items.lead, 70));
|
||||
plans = new UnitPlan[]{
|
||||
new UnitPlan(UnitTypes.wraith, 200f, ItemStack.with(Items.silicon, 10)),
|
||||
//new UnitPlan(UnitTypes.ghoul, 200f, ItemStack.with(Items.silicon, 10)),
|
||||
};
|
||||
size = 3;
|
||||
consumes.power(1.2f);
|
||||
//TODO
|
||||
consumes.items(new ItemStack(Items.silicon, 10));
|
||||
}};
|
||||
|
||||
navalFactory = new UnitFactory("naval-factory"){{
|
||||
requirements(Category.units, ItemStack.with(Items.copper, 30, Items.lead, 70));
|
||||
plans = new UnitPlan[]{
|
||||
new UnitPlan(UnitTypes.vanguard, 200f, ItemStack.with(Items.silicon, 10)),
|
||||
};
|
||||
size = 3;
|
||||
requiresWater = true;
|
||||
consumes.power(1.2f);
|
||||
//TODO
|
||||
consumes.items(new ItemStack(Items.silicon, 10));
|
||||
}};
|
||||
|
||||
|
@ -10,8 +10,10 @@ public class UnitTypes implements ContentList{
|
||||
//TODO reimplement - DO NOT USE
|
||||
public static UnitType
|
||||
ghoul, revenant, lich,
|
||||
crawler, titan, fortress, eruptor, chaosArray, eradicator;
|
||||
crawler, fortress, eruptor, chaosArray, eradicator;
|
||||
|
||||
//TODO this is awful
|
||||
public static @EntityDef({Unitc.class, Legsc.class}) UnitType titan;
|
||||
public static @EntityDef({Unitc.class, Legsc.class}) UnitType dagger;
|
||||
public static @EntityDef({Unitc.class, WaterMovec.class}) UnitType vanguard;
|
||||
public static @EntityDef({Unitc.class, Minerc.class}) UnitType draug;
|
||||
@ -42,10 +44,32 @@ public class UnitTypes implements ContentList{
|
||||
}});
|
||||
}};
|
||||
|
||||
titan = new UnitType("titan"){{
|
||||
speed = 0.4f;
|
||||
drag = 0.3f;
|
||||
mass = 3.5f;
|
||||
hitsize = 9f;
|
||||
range = 10f;
|
||||
health = 460;
|
||||
|
||||
immunities.add(StatusEffects.burning);
|
||||
|
||||
weapons.add(new Weapon("flamethrower"){{
|
||||
shootSound = Sounds.flame;
|
||||
shootY = 2f;
|
||||
reload = 14f;
|
||||
alternate = true;
|
||||
recoil = 1f;
|
||||
ejectEffect = Fx.none;
|
||||
bullet = Bullets.basicFlame;
|
||||
}});
|
||||
|
||||
}};
|
||||
|
||||
wraith = new UnitType("wraith"){{
|
||||
speed = 3f;
|
||||
accel = 0.08f;
|
||||
drag = 0f;
|
||||
drag = 0.01f;
|
||||
mass = 1.5f;
|
||||
flying = true;
|
||||
health = 75;
|
||||
@ -137,8 +161,8 @@ public class UnitTypes implements ContentList{
|
||||
flying = true;
|
||||
drag = 0.05f;
|
||||
mass = 2f;
|
||||
speed = 4f;
|
||||
rotateSpeed = 12f;
|
||||
speed = 3f;
|
||||
rotateSpeed = 15f;
|
||||
accel = 0.3f;
|
||||
range = 70f;
|
||||
itemCapacity = 70;
|
||||
|
@ -38,6 +38,10 @@ abstract class UnitComp implements Healthc, Velc, Statusc, Teamc, Itemsc, Hitbox
|
||||
lookAt(x, y);
|
||||
}
|
||||
|
||||
public boolean hasWeapons(){
|
||||
return type.hasWeapons();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float clipSize(){
|
||||
return type.region.getWidth() * 2f;
|
||||
|
@ -529,6 +529,7 @@ public class DesktopInput extends InputHandler{
|
||||
|
||||
protected void updateMovement(Unitc unit){
|
||||
boolean omni = !(unit instanceof WaterMovec);
|
||||
boolean legs = unit.isGrounded();
|
||||
float speed = unit.type().speed;
|
||||
float xa = Core.input.axis(Binding.move_x);
|
||||
float ya = Core.input.axis(Binding.move_y);
|
||||
@ -540,14 +541,16 @@ public class DesktopInput extends InputHandler{
|
||||
if(aimCursor){
|
||||
unit.lookAt(mouseAngle);
|
||||
}else{
|
||||
if(!unit.vel().isZero(0.01f)) unit.lookAt(unit.vel().angle());
|
||||
if(!unit.vel().isZero(0.01f)){
|
||||
unit.lookAt(unit.vel().angle());
|
||||
}
|
||||
}
|
||||
|
||||
if(omni){
|
||||
unit.moveAt(movement);
|
||||
}else{
|
||||
unit.moveAt(Tmp.v2.trns(unit.rotation(), movement.len()));
|
||||
if(!movement.isZero()){
|
||||
if(!movement.isZero() && legs){
|
||||
unit.vel().rotateTo(movement.angle(), unit.type().rotateSpeed * Time.delta());
|
||||
}
|
||||
}
|
||||
|
@ -71,6 +71,8 @@ public class Block extends UnlockableContent{
|
||||
public boolean breakable;
|
||||
/** whether to add this block to brokenblocks */
|
||||
public boolean rebuildable = true;
|
||||
/** whether this water can only be placed on water */
|
||||
public boolean requiresWater = false;
|
||||
/** whether this floor can be placed on. */
|
||||
public boolean placeableOn = true;
|
||||
/** whether this block has insulating properties. */
|
||||
|
@ -106,9 +106,13 @@ public class Build{
|
||||
for(int dx = 0; dx < type.size; dx++){
|
||||
for(int dy = 0; dy < type.size; dy++){
|
||||
Tile other = world.tile(x + dx + offsetx, y + dy + offsety);
|
||||
if(other == null || (other.block() != Blocks.air && !other.block().alwaysReplace) ||
|
||||
!other.floor().placeableOn ||
|
||||
(other.floor().isDeep() && !type.floating)){
|
||||
if(
|
||||
other == null ||
|
||||
(other.block() != Blocks.air && !other.block().alwaysReplace) ||
|
||||
!other.floor().placeableOn ||
|
||||
(other.floor().isDeep() && !type.floating && !type.requiresWater) ||
|
||||
(type.requiresWater && tile.floor().liquidDrop != Liquids.water)
|
||||
){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -116,12 +120,13 @@ public class Build{
|
||||
return true;
|
||||
}else{
|
||||
return tile.interactable(team)
|
||||
&& contactsGround(tile.x, tile.y, type)
|
||||
&& (!tile.floor().isDeep() || type.floating)
|
||||
&& tile.floor().placeableOn
|
||||
&& (((type.canReplace(tile.block()) || (tile.block instanceof BuildBlock && tile.<BuildEntity>ent().cblock == type))
|
||||
&& !(type == tile.block() && rotation == tile.rotation() && type.rotate)) || tile.block().alwaysReplace || tile.block() == Blocks.air)
|
||||
&& tile.block().isMultiblock() == type.isMultiblock() && type.canPlaceOn(tile);
|
||||
&& contactsGround(tile.x, tile.y, type)
|
||||
&& (!tile.floor().isDeep() || type.floating || type.requiresWater)
|
||||
&& tile.floor().placeableOn
|
||||
&& (!type.requiresWater || tile.floor().liquidDrop == Liquids.water)
|
||||
&& (((type.canReplace(tile.block()) || (tile.block instanceof BuildBlock && tile.<BuildEntity>ent().cblock == type))
|
||||
&& !(type == tile.block() && rotation == tile.rotation() && type.rotate)) || tile.block().alwaysReplace || tile.block() == Blocks.air)
|
||||
&& tile.block().isMultiblock() == type.isMultiblock() && type.canPlaceOn(tile);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@ public class OverdriveProjector extends Block{
|
||||
float realBoost = (speedBoost + phaseHeat * speedBoostPhase) * efficiency();
|
||||
|
||||
charge = 0f;
|
||||
indexer.eachBlock(this, realRange, other -> other.timeScale() < realBoost, other -> other.applyBoost(realBoost, reload + 1f));
|
||||
indexer.eachBlock(this, realRange, other -> true, other -> other.applyBoost(realBoost, reload + 1f));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ public class StackConveyor extends Block implements Autotiler{
|
||||
update = true;
|
||||
group = BlockGroup.transportation;
|
||||
hasItems = true;
|
||||
itemCapacity = 8;
|
||||
itemCapacity = 10;
|
||||
conveyorPlacement = true;
|
||||
|
||||
idleSound = Sounds.conveyor;
|
||||
@ -166,7 +166,7 @@ public class StackConveyor extends Block implements Autotiler{
|
||||
@Override
|
||||
public void updateTile(){
|
||||
// reel in crater
|
||||
if(cooldown > 0f) cooldown = Mathf.clamp(cooldown - speed, 0f, recharge);
|
||||
if(cooldown > 0f) cooldown = Mathf.clamp(cooldown - speed * edelta(), 0f, recharge);
|
||||
|
||||
if(link == -1){
|
||||
return;
|
||||
@ -207,11 +207,6 @@ public class StackConveyor extends Block implements Autotiler{
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaximumAccepted(Item item){
|
||||
return Mathf.round(super.getMaximumAccepted(item) * timeScale); // increased item capacity while boosted
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldIdleSound(){
|
||||
return false; // has no moving parts;
|
||||
|
@ -23,7 +23,7 @@ import mindustry.world.meta.*;
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
public class UnitFactory extends Block{
|
||||
public float launchVelocity = 0f;
|
||||
public float launchVelocity = 5f;
|
||||
public TextureRegion topRegion;
|
||||
public int[] capacities;
|
||||
|
||||
@ -123,9 +123,11 @@ public class UnitFactory extends Block{
|
||||
if(!net.client() && currentPlan != -1){
|
||||
UnitPlan plan = plans[currentPlan];
|
||||
Unitc unit = plan.unit.create(team);
|
||||
unit.set(x + Mathf.range(4), y + Mathf.range(4));
|
||||
unit.set(x, y );
|
||||
unit.add();
|
||||
unit.vel().y = launchVelocity;
|
||||
unit.rotation(90);
|
||||
unit.vel().y = launchVelocity + Mathf.range(1f);
|
||||
unit.vel().x = Mathf.range(1f);
|
||||
Events.fire(new UnitCreateEvent(unit));
|
||||
}
|
||||
}
|
||||
|
65
core/src/mindustry/world/consumers/ConsumeItemDynamic.java
Normal file
@ -0,0 +1,65 @@
|
||||
package mindustry.world.consumers;
|
||||
|
||||
import arc.func.*;
|
||||
import arc.scene.ui.layout.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.ArcAnnotate.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.ui.*;
|
||||
import mindustry.world.meta.*;
|
||||
|
||||
//TODO
|
||||
public class ConsumeItemDynamic extends Consume{
|
||||
public final @NonNull Func<Tilec, ItemStack[]> items;
|
||||
|
||||
public ConsumeItemDynamic(Func<Tilec, ItemStack[]> items){
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyItemFilter(Bits filter){
|
||||
//this must be done dynamically
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConsumeType type(){
|
||||
return ConsumeType.item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(Tilec tile, Table table){
|
||||
for(ItemStack stack : items.get(tile)){
|
||||
table.add(new ReqImage(new ItemImage(stack.item.icon(Cicon.medium), stack.amount),
|
||||
() -> tile.items() != null && tile.items().has(stack.item, stack.amount))).size(8 * 4).padRight(5);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIcon(){
|
||||
return "icon-item";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Tilec entity){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trigger(Tilec entity){
|
||||
for(ItemStack stack : items.get(entity)){
|
||||
entity.items().remove(stack);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean valid(Tilec entity){
|
||||
return entity.items() != null && entity.items().has(items.get(entity));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void display(BlockStats stats){
|
||||
//TODO
|
||||
//stats.add(booster ? BlockStat.booster : BlockStat.input, new ItemListValue(items));
|
||||
}
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
org.gradle.daemon=true
|
||||
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
||||
archash=e8817285d699b8d4336229ded2b0079581c502bd
|
||||
archash=f3c9d742fecd62da79f37eb84c8351a9e0b16758
|
||||
|