Ammo resupply point implementation

This commit is contained in:
Anuken
2020-06-17 10:41:26 -04:00
parent de16c95dd6
commit 3c02234a3b
22 changed files with 959 additions and 838 deletions

View File

@@ -792,6 +792,7 @@ rules.buildspeedmultiplier = Build Speed Multiplier
rules.deconstructrefundmultiplier = Deconstruct Refund Multiplier rules.deconstructrefundmultiplier = Deconstruct Refund Multiplier
rules.waitForWaveToEnd = Waves Wait for Enemies rules.waitForWaveToEnd = Waves Wait for Enemies
rules.dropzoneradius = Drop Zone Radius:[lightgray] (tiles) rules.dropzoneradius = Drop Zone Radius:[lightgray] (tiles)
rules.unitammo = Units Require Ammo
rules.title.waves = Waves rules.title.waves = Waves
rules.title.resourcesbuilding = Resources & Building rules.title.resourcesbuilding = Resources & Building
rules.title.enemy = Enemies rules.title.enemy = Enemies

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 645 KiB

After

Width:  |  Height:  |  Size: 652 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 130 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 130 KiB

View File

@@ -79,7 +79,7 @@ public class Blocks implements ContentList{
//units //units
groundFactory, airFactory, navalFactory, groundFactory, airFactory, navalFactory,
additiveReconstructor, multiplicativeReconstructor, exponentialReconstructor, tetrativeReconstructor, additiveReconstructor, multiplicativeReconstructor, exponentialReconstructor, tetrativeReconstructor,
repairPoint, repairPoint, resupplyPoint,
//campaign //campaign
launchPad, launchPadLarge, coreSilo, dataProcessor, launchPad, launchPadLarge, coreSilo, dataProcessor,
@@ -1754,6 +1754,15 @@ public class Blocks implements ContentList{
powerUse = 1f; powerUse = 1f;
}}; }};
resupplyPoint = new ResupplyPoint("resupply-point"){{
requirements(Category.units, BuildVisibility.ammoOnly, ItemStack.with(Items.lead, 20, Items.copper, 15, Items.silicon, 15));
size = 2;
range = 80f;
consumes.item(Items.copper, 1);
}};
//endregion //endregion
//region sandbox //region sandbox

View File

@@ -98,6 +98,9 @@ public class Logic implements ApplicationListener{
SectorDamage.apply(state.rules.sector.getTurnsPassed()); SectorDamage.apply(state.rules.sector.getTurnsPassed());
state.rules.sector.setTurnsPassed(0); state.rules.sector.setTurnsPassed(0);
} }
//enable infinite ammo for wave team by default
state.rules.waveTeam.rules().infiniteAmmo = true;
}); });
//TODO dying takes up a turn (?) //TODO dying takes up a turn (?)

View File

@@ -97,7 +97,7 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc{
mount.targetRotation = angleTo(mount.aimX, mount.aimY); mount.targetRotation = angleTo(mount.aimX, mount.aimY);
} }
if(mount.shoot && (ammo > 0 || !state.rules.unitAmmo)){ if(mount.shoot && (ammo > 0 || !state.rules.unitAmmo || team().rules().infiniteAmmo)){
float rotation = this.rotation - 90; float rotation = this.rotation - 90;
//shoot if applicable //shoot if applicable
@@ -118,10 +118,10 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc{
if(mount.weapon.mirror) mount.side = !mount.side; if(mount.weapon.mirror) mount.side = !mount.side;
mount.reload = weapon.reload; mount.reload = weapon.reload;
}
ammo --; ammo --;
if(ammo < 0) ammo = 0; if(ammo < 0) ammo = 0;
}
} }
} }
} }

View File

@@ -105,6 +105,8 @@ public class Rules{
public boolean cheat; public boolean cheat;
/** If true, resources are not consumed when building. */ /** If true, resources are not consumed when building. */
public boolean infiniteResources; public boolean infiniteResources;
/** If true, this team has infinite unit ammo. */
public boolean infiniteAmmo;
} }
/** Copies this ruleset exactly. Not efficient at all, do not use often. */ /** Copies this ruleset exactly. Not efficient at all, do not use often. */

View File

@@ -52,7 +52,7 @@ public class UnitType extends UnlockableContent{
public boolean flipBackLegs = true; public boolean flipBackLegs = true;
public int itemCapacity = 30; public int itemCapacity = 30;
public int ammoCapacity = 100; public int ammoCapacity = 220;
public int drillTier = -1; public int drillTier = -1;
public float buildSpeed = 1f, mineSpeed = 1f; public float buildSpeed = 1f, mineSpeed = 1f;

View File

@@ -155,6 +155,7 @@ public class CustomRulesDialog extends BaseDialog{
main.row(); main.row();
title("$rules.title.unit"); title("$rules.title.unit");
check("$rules.unitammo", b -> rules.unitAmmo = b, () -> rules.unitAmmo);
number("$rules.unithealthmultiplier", f -> rules.unitHealthMultiplier = f, () -> rules.unitHealthMultiplier); number("$rules.unithealthmultiplier", f -> rules.unitHealthMultiplier = f, () -> rules.unitHealthMultiplier);
number("$rules.unitdamagemultiplier", f -> rules.unitDamageMultiplier = f, () -> rules.unitDamageMultiplier); number("$rules.unitdamagemultiplier", f -> rules.unitDamageMultiplier = f, () -> rules.unitDamageMultiplier);
number("$rules.unitbuildspeedmultiplier", f -> rules.unitBuildSpeedMultiplier = f, () -> rules.unitBuildSpeedMultiplier); number("$rules.unitbuildspeedmultiplier", f -> rules.unitBuildSpeedMultiplier = f, () -> rules.unitBuildSpeedMultiplier);

View File

@@ -163,10 +163,17 @@ public interface Autotiler{
/** @return whether this tile is looking at the other tile, or the other tile is looking at this one. /** @return whether this tile is looking at the other tile, or the other tile is looking at this one.
* If the other tile does not rotate, it is always considered to be facing this one. */ * If the other tile does not rotate, it is always considered to be facing this one. */
default boolean lookingAt(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock){ default boolean lookingAtEither(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock){
return (Point2.equals(tile.x + Geometry.d4(rotation).x, tile.y + Geometry.d4(rotation).y, otherx, othery) return (Point2.equals(tile.x + Geometry.d4(rotation).x, tile.y + Geometry.d4(rotation).y, otherx, othery)
|| (!otherblock.rotatedOutput(otherx, othery) || Point2.equals(otherx + Geometry.d4(otherrot).x, othery + Geometry.d4(otherrot).y, tile.x, tile.y))); || (!otherblock.rotatedOutput(otherx, othery) || Point2.equals(otherx + Geometry.d4(otherrot).x, othery + Geometry.d4(otherrot).y, tile.x, tile.y)));
} }
/** @return whether this tile is looking at the other tile. */
default boolean lookingAt(Tile tile, int rotation, int otherx, int othery, Block otherblock){
Tile facing = Edges.getFacingEdge(otherblock, otherx, othery, tile);
return facing != null &&
Point2.equals(tile.x + Geometry.d4(rotation).x, tile.y + Geometry.d4(rotation).y, facing.x, facing.y);
}
boolean blends(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock); boolean blends(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock);
} }

View File

@@ -67,7 +67,8 @@ public class Conveyor extends Block implements Autotiler{
@Override @Override
public boolean blends(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock){ public boolean blends(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock){
return otherblock.outputsItems() && lookingAt(tile, rotation, otherx, othery, otherrot, otherblock); return (otherblock.outputsItems() || lookingAt(tile, rotation, otherx, othery, otherblock))
&& lookingAtEither(tile, rotation, otherx, othery, otherrot, otherblock);
} }
@Override @Override

View File

@@ -55,7 +55,7 @@ public class StackConveyor extends Block implements Autotiler{
if(tile.entity instanceof StackConveyorEntity){ if(tile.entity instanceof StackConveyorEntity){
int state = ((StackConveyorEntity)tile.entity).state; int state = ((StackConveyorEntity)tile.entity).state;
if(state == stateLoad){ //standard conveyor mode if(state == stateLoad){ //standard conveyor mode
return otherblock.outputsItems() && lookingAt(tile, rotation, otherx, othery, otherrot, otherblock); return otherblock.outputsItems() && lookingAtEither(tile, rotation, otherx, othery, otherrot, otherblock);
}else if(state == stateUnload){ //router mode }else if(state == stateUnload){ //router mode
return (otherblock.hasItems || otherblock.outputsItems() || otherblock.acceptsItems) && return (otherblock.hasItems || otherblock.outputsItems() || otherblock.acceptsItems) &&
(notLookingAt(tile, rotation, otherx, othery, otherrot, otherblock) || (notLookingAt(tile, rotation, otherx, othery, otherrot, otherblock) ||

View File

@@ -64,7 +64,7 @@ public class Conduit extends LiquidBlock implements Autotiler{
@Override @Override
public boolean blends(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock){ public boolean blends(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock){
return otherblock.hasLiquids && otherblock.outputsLiquid && lookingAt(tile, rotation, otherx, othery, otherrot, otherblock); return otherblock.hasLiquids && otherblock.outputsLiquid && lookingAtEither(tile, rotation, otherx, othery, otherrot, otherblock);
} }
@Override @Override

View File

@@ -43,14 +43,14 @@ public class LiquidConverter extends GenericCrafter{
ConsumeLiquidBase cl = consumes.get(ConsumeType.liquid); ConsumeLiquidBase cl = consumes.get(ConsumeType.liquid);
if(cons.valid()){ if(cons.valid()){
float use = Math.min(cl.amount * delta(), liquidCapacity - liquids.get(outputLiquid.liquid)) * efficiency(); float use = Math.min(cl.amount * edelta(), liquidCapacity - liquids.get(outputLiquid.liquid));
useContent(outputLiquid.liquid); useContent(outputLiquid.liquid);
progress += use / cl.amount / craftTime; progress += use / cl.amount;
liquids.add(outputLiquid.liquid, use); liquids.add(outputLiquid.liquid, use);
if(progress >= 1f){ if(progress >= craftTime){
consume(); consume();
progress = 0f; progress %= craftTime;
} }
} }

View File

@@ -17,6 +17,7 @@ import mindustry.type.*;
import mindustry.ui.*; import mindustry.ui.*;
import mindustry.world.*; import mindustry.world.*;
import mindustry.world.blocks.*; import mindustry.world.blocks.*;
import mindustry.world.blocks.units.*;
import mindustry.world.meta.*; import mindustry.world.meta.*;
import mindustry.world.modules.*; import mindustry.world.modules.*;
@@ -25,6 +26,13 @@ import static mindustry.Vars.*;
public class CoreBlock extends StorageBlock{ public class CoreBlock extends StorageBlock{
public UnitType unitType = UnitTypes.alpha; public UnitType unitType = UnitTypes.alpha;
public final int timerResupply = timers++;
public int ammoAmount = 5;
public float resupplyRate = 10f;
public float resupplyRange = 60f;
public Item resupplyItem = Items.copper;
public CoreBlock(String name){ public CoreBlock(String name){
super(name); super(name);
@@ -101,6 +109,15 @@ public class CoreBlock extends StorageBlock{
Call.onPlayerSpawn(tile, player); Call.onPlayerSpawn(tile, player);
} }
@Override
public void updateTile(){
//resupply nearby units
if(items.has(resupplyItem) && timer(timerResupply, resupplyRate) && ResupplyPoint.resupply(this, resupplyRange, ammoAmount, resupplyItem.color)){
items.remove(resupplyItem, 1);
}
}
@Override @Override
public void drawLight(){ public void drawLight(){
Drawf.light(team, x, y, 30f * size, Pal.accent, 0.5f + Mathf.absin(20f, 0.1f)); Drawf.light(team, x, y, 30f * size, Pal.accent, 0.5f + Mathf.absin(20f, 0.1f));

View File

@@ -0,0 +1,65 @@
package mindustry.world.blocks.units;
import arc.graphics.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.world.*;
import static mindustry.Vars.*;
public class ResupplyPoint extends Block{
public final int timerResupply = timers++;
public int ammoAmount = 10;
public float resupplyRate = 5f;
public float range = 60f;
public Color ammoColor = Items.copper.color;
public ResupplyPoint(String name){
super(name);
solid = update = true;
hasItems = true;
}
@Override
public boolean outputsItems(){
return false;
}
@Override
public void drawPlace(int x, int y, int rotation, boolean valid){
Drawf.dashCircle(x * tilesize + offset(), y * tilesize + offset(), range, Pal.placing);
}
public class ResupplyPointEntity extends TileEntity{
@Override
public void drawSelect(){
Drawf.dashCircle(x, y, range, team.color);
}
@Override
public void updateTile(){
if(consValid() && timer(timerResupply, resupplyRate / timeScale) && resupply(this, range, ammoAmount, ammoColor)){
consume();
}
}
}
/** Tries to resupply nearby units.
* @return whether resupplying was successful. If unit ammo is disabled, always returns false. */
public static boolean resupply(TileEntity tile, float range, int ammoAmount, Color ammoColor){
if(!state.rules.unitAmmo) return false;
Unitc unit = Units.closest(tile.team, tile.x, tile.y, range, u -> u.ammo() <= u.type().ammoCapacity - ammoAmount);
if(unit != null){
Fx.itemTransfer.at(tile.x, tile.y, ammoAmount / 2f, ammoColor, unit);
unit.ammo(Math.min(unit.ammo() + ammoAmount, unit.type().ammoCapacity));
return true;
}
return false;
}
}

View File

@@ -9,7 +9,8 @@ public enum BuildVisibility{
debugOnly(() -> false), debugOnly(() -> false),
sandboxOnly(() -> Vars.state.rules.infiniteResources), sandboxOnly(() -> Vars.state.rules.infiniteResources),
campaignOnly(() -> Vars.state.isCampaign()), campaignOnly(() -> Vars.state.isCampaign()),
lightingOnly(() -> Vars.state.rules.lighting); lightingOnly(() -> Vars.state.rules.lighting),
ammoOnly(() -> Vars.state.rules.unitAmmo);
private final Boolp visible; private final Boolp visible;

View File

@@ -1,3 +1,3 @@
org.gradle.daemon=true org.gradle.daemon=true
org.gradle.jvmargs=-Xms256m -Xmx1024m org.gradle.jvmargs=-Xms256m -Xmx1024m
archash=06c938d6dced0d9bf9f8ec98d4767b38f633f8fa archash=f76b0c94953c07ef2ac40858b3b615a34911bdf7