1
0
mirror of https://github.com/Anuken/Mindustry.git synced 2024-11-13 07:15:28 +03:00

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.waitForWaveToEnd = Waves Wait for Enemies
rules.dropzoneradius = Drop Zone Radius:[lightgray] (tiles)
rules.unitammo = Units Require Ammo
rules.title.waves = Waves
rules.title.resourcesbuilding = Resources & Building
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
groundFactory, airFactory, navalFactory,
additiveReconstructor, multiplicativeReconstructor, exponentialReconstructor, tetrativeReconstructor,
repairPoint,
repairPoint, resupplyPoint,
//campaign
launchPad, launchPadLarge, coreSilo, dataProcessor,
@ -1754,6 +1754,15 @@ public class Blocks implements ContentList{
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
//region sandbox

View File

@ -98,6 +98,9 @@ public class Logic implements ApplicationListener{
SectorDamage.apply(state.rules.sector.getTurnsPassed());
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 (?)

View File

@ -97,7 +97,7 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc{
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;
//shoot if applicable
@ -118,10 +118,10 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc{
if(mount.weapon.mirror) mount.side = !mount.side;
mount.reload = weapon.reload;
}
ammo --;
if(ammo < 0) ammo = 0;
ammo --;
if(ammo < 0) ammo = 0;
}
}
}
}

View File

@ -105,6 +105,8 @@ public class Rules{
public boolean cheat;
/** If true, resources are not consumed when building. */
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. */

View File

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

View File

@ -155,6 +155,7 @@ public class CustomRulesDialog extends BaseDialog{
main.row();
title("$rules.title.unit");
check("$rules.unitammo", b -> rules.unitAmmo = b, () -> rules.unitAmmo);
number("$rules.unithealthmultiplier", f -> rules.unitHealthMultiplier = f, () -> rules.unitHealthMultiplier);
number("$rules.unitdamagemultiplier", f -> rules.unitDamageMultiplier = f, () -> rules.unitDamageMultiplier);
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.
* 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)
|| (!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);
}

View File

@ -67,7 +67,8 @@ public class Conveyor extends Block implements Autotiler{
@Override
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

View File

@ -55,7 +55,7 @@ public class StackConveyor extends Block implements Autotiler{
if(tile.entity instanceof StackConveyorEntity){
int state = ((StackConveyorEntity)tile.entity).state;
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
return (otherblock.hasItems || otherblock.outputsItems() || otherblock.acceptsItems) &&
(notLookingAt(tile, rotation, otherx, othery, otherrot, otherblock) ||

View File

@ -64,7 +64,7 @@ public class Conduit extends LiquidBlock implements Autotiler{
@Override
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

View File

@ -43,14 +43,14 @@ public class LiquidConverter extends GenericCrafter{
ConsumeLiquidBase cl = consumes.get(ConsumeType.liquid);
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);
progress += use / cl.amount / craftTime;
progress += use / cl.amount;
liquids.add(outputLiquid.liquid, use);
if(progress >= 1f){
if(progress >= craftTime){
consume();
progress = 0f;
progress %= craftTime;
}
}

View File

@ -17,6 +17,7 @@ import mindustry.type.*;
import mindustry.ui.*;
import mindustry.world.*;
import mindustry.world.blocks.*;
import mindustry.world.blocks.units.*;
import mindustry.world.meta.*;
import mindustry.world.modules.*;
@ -25,6 +26,13 @@ import static mindustry.Vars.*;
public class CoreBlock extends StorageBlock{
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){
super(name);
@ -101,6 +109,15 @@ public class CoreBlock extends StorageBlock{
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
public void drawLight(){
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),
sandboxOnly(() -> Vars.state.rules.infiniteResources),
campaignOnly(() -> Vars.state.isCampaign()),
lightingOnly(() -> Vars.state.rules.lighting);
lightingOnly(() -> Vars.state.rules.lighting),
ammoOnly(() -> Vars.state.rules.unitAmmo);
private final Boolp visible;

View File

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