Implemented basic mech factories

This commit is contained in:
Anuken 2018-06-19 14:23:59 -04:00
parent 6cfd1a1ef6
commit 23f3f68767
32 changed files with 903 additions and 750 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 381 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 B

View File

Before

Width:  |  Height:  |  Size: 195 B

After

Width:  |  Height:  |  Size: 195 B

View File

Before

Width:  |  Height:  |  Size: 177 B

After

Width:  |  Height:  |  Size: 177 B

View File

Before

Width:  |  Height:  |  Size: 264 B

After

Width:  |  Height:  |  Size: 264 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

After

Width:  |  Height:  |  Size: 118 KiB

View File

@ -7,22 +7,46 @@ import io.anuke.mindustry.type.Mech;
import io.anuke.mindustry.type.Upgrade;
public class Mechs implements ContentList {
public static Mech standard, standardShip;
public static Mech alpha, delta, tau, omega, standardShip;
/**These are not new mechs, just re-assignments for convenience.*/
public static Mech starterDesktop, starterMobile;
@Override
public void load() {
standard = new Mech("standard-mech", false){{
drillPower = 1;
alpha = new Mech("alpha-mech", false){{
drillPower = 2;
speed = 1.1f;
maxSpeed = 1.1f;
}};
delta = new Mech("delta-mech", false){{
drillPower = -1;
speed = 1.5f;
maxSpeed = 1.5f;
}};
tau = new Mech("tau-mech", false){{
drillPower = 2;
speed = 1.1f;
maxSpeed = 1.1f;
}};
omega = new Mech("omega-mech", false){{
drillPower = 1;
speed = 1.0f;
maxSpeed = 1.0f;
}};
standardShip = new Mech("standard-ship", true){{
drillPower = 1;
speed = 0.4f;
maxSpeed = 3f;
}};
starterDesktop = alpha;
starterMobile = standardShip;
}
@Override

View File

@ -6,6 +6,7 @@ import io.anuke.mindustry.game.Content;
import io.anuke.mindustry.type.ContentList;
import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.type.Recipe;
import static io.anuke.mindustry.type.Category.*;
public class Recipes implements ContentList{
@ -126,11 +127,9 @@ public class Recipes implements ContentList{
new Recipe(units, UnitBlocks.overdriveProjector, new ItemStack(Items.iron, 1));
new Recipe(units, UnitBlocks.shieldProjector, new ItemStack(Items.iron, 1));
//new Recipe(units, UnitBlocks.vtolFactory, new ItemStack(Items.steel, 10));
//new Recipe(units, UnitBlocks.droneFactory, new ItemStack(Items.steel, 10));
//new Recipe(units, UnitBlocks.droneFactory, new ItemStack(Items.steel, 10));
//new Recipe(units, UnitBlocks.walkerFactory, new ItemStack(Items.steel, 10));
new Recipe(units, UpgradeBlocks.omegaFactory, new ItemStack(Items.iron, 1));
new Recipe(units, UpgradeBlocks.deltaFactory, new ItemStack(Items.iron, 1));
new Recipe(units, UpgradeBlocks.tauFactory, new ItemStack(Items.iron, 1));
new Recipe(units, DebugBlocks.itemSource, new ItemStack(Items.steel, 10)).setDebug();
new Recipe(units, DebugBlocks.itemVoid, new ItemStack(Items.steel, 10)).setDebug();

View File

@ -0,0 +1,27 @@
package io.anuke.mindustry.content.blocks;
import io.anuke.mindustry.content.Mechs;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.blocks.production.MechFactory;
public class UpgradeBlocks extends BlockList {
public static Block deltaFactory, tauFactory, omegaFactory;
@Override
public void load() {
deltaFactory = new MechFactory("delta-mech-factory"){{
mech = Mechs.delta;
size = 2;
}};
tauFactory = new MechFactory("tau-mech-factory"){{
mech = Mechs.tau;
size = 2;
}};
omegaFactory = new MechFactory("omega-mech-factory"){{
mech = Mechs.omega;
size = 3;
}};
}
}

View File

@ -82,6 +82,7 @@ public class ContentLoader {
new UnitBlocks(),
new PowerBlocks(),
new CraftingBlocks(),
new UpgradeBlocks(),
//recipes
new Recipes(),

View File

@ -195,7 +195,7 @@ public class Control extends Module{
Player player = new Player();
player.name = Settings.getString("name");
player.mech = mobile ? Mechs.standardShip : Mechs.standard;
player.mech = mobile ? Mechs.starterMobile : Mechs.starterDesktop;
player.color.set(Settings.getInt("color-" + index));
player.isLocal = true;
player.playerIndex = index;

View File

@ -137,7 +137,7 @@ public class NetServer extends Module{
player.usid = packet.usid;
player.name = packet.name;
player.uuid = uuid;
player.mech = packet.mobile ? Mechs.standardShip : Mechs.standard;
player.mech = packet.mobile ? Mechs.starterMobile : Mechs.starterDesktop;
player.dead = true;
player.setNet(player.x, player.y);
player.color.set(packet.color);

View File

@ -8,7 +8,6 @@ import com.badlogic.gdx.utils.Queue;
import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.content.Mechs;
import io.anuke.mindustry.entities.effect.ItemDrop;
import io.anuke.mindustry.entities.traits.BuilderTrait;
import io.anuke.mindustry.entities.traits.CarriableTrait;
@ -62,7 +61,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait {
public String uuid, usid;
public boolean isAdmin, isTransferring, isShooting;
public Color color = new Color();
public Mech mech = Mechs.standard;
public Mech mech;
public int clientid = -1;
public int playerIndex = 0;
@ -87,7 +86,18 @@ public class Player extends Unit implements BuilderTrait, CarryTrait {
//region unit and event overrides, utility methods
@Override
@Override
public int getItemCapacity() {
return mech.itemCapacity;
}
@Override
public int getAmmoCapacity() {
return mech.ammoCapacity;
}
@Override
public void interpolate() {
super.interpolate();
@ -122,7 +132,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait {
@Override
public float getBuildPower(Tile tile) {
return 1f;
return mech.buildPower;
}
@Override

View File

@ -35,7 +35,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
/**Maximum absolute value of a velocity vector component.*/
public static final float maxAbsVelocity = 127f/velocityPercision;
public UnitInventory inventory = new UnitInventory(100, 100);
public UnitInventory inventory = new UnitInventory(this);
public float rotation;
protected Interpolator interpolator = new Interpolator();
@ -259,6 +259,12 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
public void drawUnder(){}
public void drawOver(){}
public boolean isInfiniteAmmo(){
return false;
}
public abstract int getItemCapacity();
public abstract int getAmmoCapacity();
public abstract float getArmor();
public abstract boolean acceptsAmmo(Item item);
public abstract void addAmmo(Item item);

View File

@ -14,28 +14,21 @@ public class UnitInventory implements Saveable{
private Array<AmmoEntry> ammos = new Array<>();
private int totalAmmo;
private ItemStack item = new ItemStack(Items.stone, 0);
//TODO move these somewhere else so they're not variables?
private int capacity, ammoCapacity;
private boolean infiniteAmmo;
public UnitInventory(int capacity, int ammoCapacity) {
this.capacity = capacity;
this.ammoCapacity = ammoCapacity;
private final Unit unit;
public UnitInventory(Unit unit) {
this.unit = unit;
}
public boolean isFull(){
return item != null && item.amount >= capacity;
}
public void setInfiniteAmmo(boolean infinite){
infiniteAmmo = infinite;
return item != null && item.amount >= unit.getItemCapacity();
}
@Override
public void writeSave(DataOutput stream) throws IOException {
stream.writeShort(item.amount);
stream.writeByte(item.item.id);
stream.writeBoolean(infiniteAmmo);
stream.writeShort(totalAmmo);
stream.writeByte(ammos.size);
for(int i = 0; i < ammos.size; i ++){
@ -48,7 +41,6 @@ public class UnitInventory implements Saveable{
public void readSave(DataInput stream) throws IOException {
short iamount = stream.readShort();
byte iid = stream.readByte();
infiniteAmmo = stream.readBoolean();
this.totalAmmo = stream.readShort();
byte ammoa = stream.readByte();
for(int i = 0; i < ammoa; i ++){
@ -75,7 +67,7 @@ public class UnitInventory implements Saveable{
}
public void useAmmo(){
if(infiniteAmmo) return;
if(unit.isInfiniteAmmo()) return;
AmmoEntry entry = ammos.peek();
entry.amount --;
if(entry.amount == 0) ammos.pop();
@ -87,11 +79,11 @@ public class UnitInventory implements Saveable{
}
public int ammoCapacity(){
return ammoCapacity;
return unit.getAmmoCapacity();
}
public boolean canAcceptAmmo(AmmoType type){
return totalAmmo + type.quantityMultiplier <= ammoCapacity;
return totalAmmo + type.quantityMultiplier <= unit.getAmmoCapacity();
}
public void addAmmo(AmmoType type){
@ -115,7 +107,7 @@ public class UnitInventory implements Saveable{
}
public int capacity(){
return capacity;
return unit.getItemCapacity();
}
public boolean isEmpty(){
@ -124,18 +116,18 @@ public class UnitInventory implements Saveable{
public int itemCapacityUsed(Item type){
if(canAcceptItem(type)){
return !hasItem() ? capacity : (capacity - item.amount);
return !hasItem() ? unit.getItemCapacity() : (unit.getItemCapacity() - item.amount);
}else{
return capacity;
return unit.getItemCapacity();
}
}
public boolean canAcceptItem(Item type){
return !hasItem() || (item.item == type && capacity - item.amount > 0);
return !hasItem() || (item.item == type && unit.getItemCapacity() - item.amount > 0);
}
public boolean canAcceptItem(Item type, int amount){
return !hasItem() || (item.item == type && item.amount + amount <= capacity);
return !hasItem() || (item.item == type && item.amount + amount <= unit.getItemCapacity());
}
public void clear(){

View File

@ -76,7 +76,7 @@ public class Units {
boolean[] value = new boolean[1];
Units.getNearby(rect, unit -> {
if(value[0] || !pred.test(unit)) return;
if(value[0] || !pred.test(unit) || unit.isDead()) return;
if(!unit.isFlying()){
unit.getHitbox(hitrect);

View File

@ -53,7 +53,6 @@ public abstract class BaseUnit extends Unit{
/**Sets this to a 'wave' unit, which means it has slightly different AI and will not run out of ammo.*/
public void setWave(){
isWave = true;
inventory.setInfiniteAmmo(true);
}
public void rotate(float angle){
@ -115,6 +114,21 @@ public abstract class BaseUnit extends Unit{
return null;
}
@Override
public int getItemCapacity() {
return type.itemCapacity;
}
@Override
public int getAmmoCapacity() {
return type.ammoCapacity;
}
@Override
public boolean isInfiniteAmmo() {
return isWave;
}
@Override
public void interpolate() {
super.interpolate();

View File

@ -31,6 +31,8 @@ public class UnitType {
public float retreatPercent = 0.2f;
public float armor = 0f;
public float carryWeight = 1f;
public int ammoCapacity = 100;
public int itemCapacity = 100;
public ObjectMap<Item, AmmoType> ammo = new ObjectMap<>();
public UnitType(String name, UnitCreator creator){

View File

@ -6,14 +6,22 @@ import io.anuke.ucore.graphics.Draw;
public class Mech extends Upgrade {
public boolean flying;
public float speed = 1.1f;
public float maxSpeed = 1.1f;
public float mass = 1f;
public float armor = 1f;
public int drillPower = -1;
public float carryWeight = 1f;
public float armor = 1f;
public float buildPower = 1f;
public boolean canRepair = false;
public Weapon weapon = Weapons.blaster;
public int itemCapacity = 30;
public int ammoCapacity = 100;
public TextureRegion baseRegion, legRegion, region, iconRegion;
public Mech(String name, boolean flying){

View File

@ -3,6 +3,8 @@ package io.anuke.mindustry.type;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.game.Content;
import io.anuke.mindustry.game.UnlockableContent;
import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.function.Predicate;
import io.anuke.ucore.util.Bundles;
public abstract class Upgrade implements UnlockableContent{
@ -45,6 +47,14 @@ public abstract class Upgrade implements UnlockableContent{
return all();
}
public static <T extends Upgrade> void forEach(Consumer<T> type, Predicate<Upgrade> pred){
for(Upgrade u : upgrades){
if(pred.test(u)){
type.accept((T)u);
}
}
}
public static Array<Upgrade> all() {
return upgrades;
}

View File

@ -1,19 +1,18 @@
package io.anuke.mindustry.world.blocks.production;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.utils.Array;
import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.content.fx.Fx;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.gen.CallBlocks;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.graphics.Shaders;
import io.anuke.mindustry.net.In;
import io.anuke.mindustry.type.Mech;
import io.anuke.mindustry.type.Upgrade;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Effects;
@ -21,35 +20,49 @@ import io.anuke.ucore.core.Graphics;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.scene.style.TextureRegionDrawable;
import io.anuke.ucore.scene.ui.ButtonGroup;
import io.anuke.ucore.scene.ui.ImageButton;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.util.Mathf;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import static io.anuke.mindustry.Vars.tilesize;
public class MechFactory extends Block{
protected float powerUse = 0.1f;
protected Mech mech;
public MechFactory(String name){
super(name);
solid = true;
hasItems = true;
destructible = true;
configurable = true;
hasPower = true;
update = true;
consumesTap = true;
solidifes = true;
}
@Override
public boolean isSolidFor(Tile tile) {
MechFactoryEntity entity = tile.entity();
return !entity.open;
}
@Override
public void tapped(Tile tile, Player player) {
if(checkValidTap(tile, player)){
CallBlocks.onMechFactoryBegin(player, tile);
}
}
@Override
public void draw(Tile tile) {
MechFactoryEntity entity = tile.entity();
Draw.rect(name, tile.drawx(), tile.drawy());
Draw.rect(entity.open ? name + "-open" : name, tile.drawx(), tile.drawy());
if(entity.current != null) {
TextureRegion region = entity.current.region;
if(entity.player != null) {
TextureRegion region = mech.iconRegion;
Shaders.build.region = region;
Shaders.build.progress = entity.progress;
@ -77,136 +90,87 @@ public class MechFactory extends Block{
public void update(Tile tile) {
MechFactoryEntity entity = tile.entity();
if(entity.current != null){
entity.heat = Mathf.lerpDelta(entity.heat, 1f, 0.1f);
entity.time += Timers.delta();
entity.progress += 1f / Vars.respawnduration;
float used = Math.min(powerCapacity, Timers.delta() * powerUse);
if(entity.open){
if(!Units.anyEntities(tile)){
entity.open = false;
}else{
entity.heat = Mathf.lerpDelta(entity.heat, 0f, 0.1f);
}
}
if(entity.player != null){
if(entity.power.amount >= used || true) {
entity.heat = Mathf.lerpDelta(entity.heat, 1f, 0.1f);
entity.progress += 1f / Vars.respawnduration;
entity.power.amount -= used;
}else{
entity.heat = Mathf.lerpDelta(entity.heat, 0f, 0.05f);
}
entity.time += entity.heat;
if(entity.progress >= 1f){
CallBlocks.onMechFactoryDone(tile, entity.current);
CallBlocks.onMechFactoryDone(tile);
}
}else{
if(Units.anyEntities(tile, 4f, unit -> unit.getTeam() == entity.getTeam() && unit instanceof Player)){
entity.open = true;
}
entity.heat = Mathf.lerpDelta(entity.heat, 0f, 0.1f);
}
}
@Override
public void buildTable(Tile tile, Table table) {
MechFactoryEntity entity = tile.entity();
Table cont = new Table();
//no result to show, build weapon selection menu
if(entity.result == null) {
//show weapon to select and build
showSelect(tile, cont);
}else{
//show weapon to withdraw
showResult(tile, cont);
}
table.add(cont);
}
protected void showSelect(Tile tile, Table cont){
MechFactoryEntity entity = tile.entity();
Array<Upgrade> items = Upgrade.all();
ButtonGroup<ImageButton> group = new ButtonGroup<>();
group.setMinCheckCount(0);
int i = 0;
for (Upgrade upgrade : items) {
if (!(upgrade instanceof Mech)) continue;
Mech mech = (Mech) upgrade;
ImageButton button = cont.addImageButton("white", "toggle", 24, () -> CallBlocks.setMechFactory(null, tile, mech))
.size(38, 42).padBottom(-5.1f).group(group).get();
button.getStyle().imageUp = new TextureRegionDrawable(new TextureRegion(mech.region));
button.setChecked(entity.current == mech);
if (i++ % 4 == 3) {
cont.row();
}
}
cont.update(() -> {
//show result when done
if(entity.result != null){
cont.clear();
cont.update(null);
showResult(tile, cont);
}
});
}
protected void showResult(Tile tile, Table cont){
MechFactoryEntity entity = tile.entity();
Mech mech = entity.result;
ImageButton button = cont.addImageButton("white", "toggle", 24, () -> CallBlocks.pickupMechFactory(null, tile))
.size(38, 42).padBottom(-5.1f).get();
button.getStyle().imageUp = new TextureRegionDrawable(new TextureRegion(mech.region));
button.setChecked(entity.current == mech);
cont.update(() -> {
//show selection menu when result disappears
if(entity.result == null){
cont.clear();
cont.update(null);
showSelect(tile, cont);
}
});
}
@Override
public TileEntity getEntity() {
return new MechFactoryEntity();
}
@Remote(targets = Loc.both, called = Loc.server, in = In.blocks, forward = true)
public static void pickupMechFactory(Player player, Tile tile){
MechFactoryEntity entity = tile.entity();
public static void onMechFactoryBegin(Player player, Tile tile){
if(!checkValidTap(tile, player)) return;
if(entity.current != null){
player.mech = entity.current;
entity.current = null;
entity.progress = 0;
entity.result = null;
}
}
@Remote(targets = Loc.both, called = Loc.server, in = In.blocks, forward = true)
public static void setMechFactory(Player player, Tile tile, Mech weapon){
MechFactoryEntity entity = tile.entity();
entity.current = weapon;
entity.progress = 0f;
entity.heat = 0f;
entity.player = player;
player.rotation = 90f;
player.baseRotation = 90f;
player.set(entity.x, entity.y);
player.setDead(true);
player.setRespawning(true);
}
@Remote(called = Loc.server, in = In.blocks)
public static void onMechFactoryDone(Tile tile, Mech result){
public static void onMechFactoryDone(Tile tile){
MechFactoryEntity entity = tile.entity();
Effects.effect(Fx.spawn, entity);
entity.current = null;
entity.player.mech = ((MechFactory)tile.block()).mech;
entity.progress = 0;
entity.result = result;
entity.player.heal();
entity.player.setDead(false);
entity.player = null;
}
protected static boolean checkValidTap(Tile tile, Player player){
MechFactoryEntity entity = tile.entity();
return Math.abs(player.x - tile.drawx()) <= tile.block().size * tilesize / 2f &&
Math.abs(player.y - tile.drawy()) <= tile.block().size * tilesize / 2f && entity.player == null;
}
public class MechFactoryEntity extends TileEntity{
public Mech current;
public Mech result;
public Player player;
public float progress;
public float time;
public float heat;
public boolean open;
@Override
public void write(DataOutputStream stream) throws IOException {
stream.writeByte(current == null ? -1 : current.id);
stream.writeByte(result == null ? -1 : result.id);
stream.writeFloat(progress);
stream.writeFloat(time);
stream.writeFloat(heat);
@ -214,18 +178,9 @@ public class MechFactory extends Block{
@Override
public void read(DataInputStream stream) throws IOException {
byte id = stream.readByte(), rid = stream.readByte();
progress = stream.readFloat();
time = stream.readFloat();
heat = stream.readFloat();
if(id != -1){
current = Upgrade.getByID(id);
}
if(rid != -1){
result = Upgrade.getByID(rid);
}
}
}
}