Power-based ammo / Refactoring / IP kicks / Fixes

This commit is contained in:
Anuken 2020-09-24 13:05:39 -04:00
parent db94acdb83
commit 0a07458186
28 changed files with 322 additions and 126 deletions

View File

@ -3,6 +3,8 @@ package mindustry.annotations.impl;
import arc.files.*;
import arc.scene.style.*;
import arc.struct.*;
import arc.util.*;
import arc.util.io.*;
import arc.util.serialization.*;
import com.squareup.javapoet.*;
import mindustry.annotations.Annotations.*;
@ -33,6 +35,17 @@ public class AssetsProcess extends BaseProcessor{
String resources = rootDirectory + "/core/assets-raw/sprites/ui";
Jval icons = Jval.read(Fi.get(rootDirectory + "/core/assets-raw/fontgen/config.json").readString());
ObjectMap<String, String> texIcons = new OrderedMap<>();
PropertiesUtils.load(texIcons, Fi.get(rootDirectory + "/core/assets/icons/icons.properties").reader());
texIcons.each((key, val) -> {
String[] split = val.split("\\|");
String name = Strings.kebabToCamel(split[1]).replace("Medium", "").replace("Icon", "");
if(SourceVersion.isKeyword(name) || name.equals("char")) name = name + "i";
ichtype.addField(FieldSpec.builder(char.class, name, Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL).initializer("(char)" + key).build());
});
ictype.addField(FieldSpec.builder(ParameterizedTypeName.get(ObjectMap.class, String.class, TextureRegionDrawable.class),
"icons", Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL).initializer("new ObjectMap<>()").build());

View File

@ -21,15 +21,8 @@
63723=ice|block-ice-medium
63722=ice-snow|block-ice-snow-medium
63721=cliffs|block-cliffs-medium
63720=rocks|block-rocks-medium
63719=sporerocks|block-sporerocks-medium
63718=rock|block-rock-medium
63717=snowrock|block-snowrock-medium
63716=icerocks|block-icerocks-medium
63715=snowrocks|block-snowrocks-medium
63714=dunerocks|block-dunerocks-medium
63713=sandrocks|block-sandrocks-medium
63712=saltrocks|block-saltrocks-medium
63711=spore-pine|block-spore-pine-medium
63710=snow-pine|block-snow-pine-medium
63709=pine|block-pine-medium
@ -38,7 +31,6 @@
63706=white-tree|block-white-tree-medium
63705=spore-cluster|block-spore-cluster-medium
63704=shale|block-shale-medium
63703=shalerocks|block-shalerocks-medium
63702=shale-boulder|block-shale-boulder-medium
63701=sand-boulder|block-sand-boulder-medium
63700=moss|block-moss-medium

View File

@ -6,6 +6,7 @@ import arc.math.*;
import arc.math.geom.*;
import arc.struct.EnumSet;
import arc.struct.*;
import arc.util.ArcAnnotate.*;
import mindustry.content.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
@ -165,6 +166,11 @@ public class BlockIndexer{
return flagMap[team.id][type.ordinal()];
}
@Nullable
public Tile findClosestFlag(float x, float y, Team team, BlockFlag flag){
return Geometry.findClosest(x, y, getAllied(team, flag));
}
public boolean eachBlock(Teamc team, float range, Boolf<Building> pred, Cons<Building> cons){
return eachBlock(team.team(), team.getX(), team.getY(), range, pred, cons);
}

View File

@ -265,7 +265,7 @@ public class Blocks implements ContentList{
variants = 3;
status = StatusEffects.muddy;
statusDuration = 30f;
attributes.set(Attribute.water, 2f);
attributes.set(Attribute.water, 1f);
cacheLayer = CacheLayer.mud;
albedo = 0.35f;
}};

View File

@ -378,7 +378,11 @@ public class TechTree implements ContentList{
node(nova, () -> {
node(pulsar, () -> {
node(quasar, () -> {
node(vela, () -> {
node(corvus, () -> {
});
});
});
});
});

View File

@ -69,7 +69,7 @@ public class UnitTypes implements ContentList{
dagger = new UnitType("dagger"){{
speed = 0.5f;
hitsize = 8f;
hitSize = 8f;
health = 140;
weapons.add(new Weapon("large-weapon"){{
reload = 14f;
@ -83,7 +83,7 @@ public class UnitTypes implements ContentList{
mace = new UnitType("mace"){{
speed = 0.4f;
hitsize = 9f;
hitSize = 9f;
health = 500;
armor = 4f;
@ -114,7 +114,7 @@ public class UnitTypes implements ContentList{
fortress = new UnitType("fortress"){{
speed = 0.38f;
hitsize = 13f;
hitSize = 13f;
rotateSpeed = 3f;
targetAir = false;
health = 790;
@ -147,7 +147,7 @@ public class UnitTypes implements ContentList{
scepter = new UnitType("scepter"){{
speed = 0.35f;
hitsize = 20f;
hitSize = 20f;
rotateSpeed = 2.1f;
health = 9000;
armor = 11f;
@ -207,7 +207,7 @@ public class UnitTypes implements ContentList{
reign = new UnitType("reign"){{
speed = 0.35f;
hitsize = 26f;
hitSize = 26f;
rotateSpeed = 1.65f;
health = 24000;
armor = 14f;
@ -269,13 +269,14 @@ public class UnitTypes implements ContentList{
canBoost = true;
boostMultiplier = 1.5f;
speed = 0.55f;
hitsize = 8f;
hitSize = 8f;
health = 110f;
buildSpeed = 0.8f;
armor = 1f;
commandLimit = 8;
abilities.add(new HealFieldAbility(10f, 60f * 4, 60f));
ammoType = AmmoTypes.power;
weapons.add(new Weapon("heal-weapon"){{
top = false;
@ -295,7 +296,7 @@ public class UnitTypes implements ContentList{
canBoost = true;
boostMultiplier = 1.5f;
speed = 0.65f;
hitsize = 10f;
hitSize = 10f;
health = 320f;
buildSpeed = 0.9f;
armor = 4f;
@ -305,6 +306,7 @@ public class UnitTypes implements ContentList{
commandLimit = 15;
abilities.add(new ShieldFieldAbility(20f, 40f, 60f * 5, 60f));
ammoType = AmmoTypes.power;
weapons.add(new Weapon("heal-shotgun-weapon"){{
top = false;
@ -335,7 +337,7 @@ public class UnitTypes implements ContentList{
quasar = new UnitType("quasar"){{
mineTier = 1;
hitsize = 12f;
hitSize = 12f;
boostMultiplier = 2f;
itemCapacity = 80;
health = 650f;
@ -346,9 +348,10 @@ public class UnitTypes implements ContentList{
commandLimit = 18;
mechFrontSway = 0.55f;
ammoType = AmmoTypes.power;
speed = 0.4f;
hitsize = 10f;
hitSize = 10f;
mineTier = 2;
mineSpeed = 7f;
@ -377,7 +380,7 @@ public class UnitTypes implements ContentList{
}};
vela = new UnitType("vela"){{
hitsize = 23f;
hitSize = 23f;
rotateSpeed = 1.6f;
canDrown = false;
@ -385,6 +388,7 @@ public class UnitTypes implements ContentList{
mechStepParticles = true;
mechStepShake = 0.15f;
ammoType = AmmoTypes.powerHigh;
speed = 0.35f;
boostMultiplier = 2.1f;
@ -439,7 +443,7 @@ public class UnitTypes implements ContentList{
corvus = new UnitType("corvus"){{
mineTier = 1;
hitsize = 29f;
hitSize = 29f;
itemCapacity = 80;
health = 19000f;
buildSpeed = 1.7f;
@ -457,6 +461,7 @@ public class UnitTypes implements ContentList{
hovering = true;
visualElevation = 0.2f;
allowLegStep = true;
ammoType = AmmoTypes.powerHigh;
speed = 0.3f;
@ -513,7 +518,7 @@ public class UnitTypes implements ContentList{
defaultController = SuicideAI::new;
speed = 0.85f;
hitsize = 8f;
hitSize = 8f;
health = 180;
mechSideSway = 0.25f;
range = 40f;
@ -541,7 +546,7 @@ public class UnitTypes implements ContentList{
itemCapacity = 80;
speed = 0.5f;
drag = 0.4f;
hitsize = 10f;
hitSize = 10f;
rotateSpeed = 3f;
targetAir = false;
health = 600;
@ -581,7 +586,7 @@ public class UnitTypes implements ContentList{
spiroct = new UnitType("spiroct"){{
speed = 0.4f;
drag = 0.4f;
hitsize = 12f;
hitSize = 12f;
rotateSpeed = 3f;
health = 760;
immunities = ObjectSet.with(StatusEffects.burning, StatusEffects.melting);
@ -592,6 +597,7 @@ public class UnitTypes implements ContentList{
legBaseOffset = 2f;
hovering = true;
armor = 5f;
ammoType = AmmoTypes.power;
buildSpeed = 0.75f;
@ -646,7 +652,7 @@ public class UnitTypes implements ContentList{
arkyid = new UnitType("arkyid"){{
drag = 0.1f;
speed = 0.5f;
hitsize = 21f;
hitSize = 21f;
health = 8000;
armor = 6f;
@ -663,6 +669,7 @@ public class UnitTypes implements ContentList{
legLengthScl = 0.96f;
rippleScale = 2f;
legSpeed = 0.2f;
ammoType = AmmoTypes.power;
legSplashDamage = 32;
legSplashRange = 30;
@ -744,7 +751,7 @@ public class UnitTypes implements ContentList{
toxopid = new UnitType("toxopid"){{
drag = 0.1f;
speed = 0.5f;
hitsize = 21f;
hitSize = 21f;
health = 22000;
armor = 13f;
@ -761,6 +768,7 @@ public class UnitTypes implements ContentList{
legLengthScl = 0.93f;
rippleScale = 3f;
legSpeed = 0.19f;
ammoType = AmmoTypes.powerHigh;
legSplashDamage = 80;
legSplashRange = 60;
@ -888,7 +896,7 @@ public class UnitTypes implements ContentList{
accel = 0.08f;
drag = 0.016f;
flying = true;
hitsize = 9f;
hitSize = 9f;
targetAir = false;
engineOffset = 7.8f;
range = 140f;
@ -925,7 +933,7 @@ public class UnitTypes implements ContentList{
drag = 0.016f;
flying = true;
range = 140f;
hitsize = 18f;
hitSize = 18f;
lowAltitude = true;
armor = 5f;
@ -973,7 +981,7 @@ public class UnitTypes implements ContentList{
armor = 9f;
engineOffset = 21;
engineSize = 5.3f;
hitsize = 56f;
hitSize = 56f;
BulletType missiles = new MissileBulletType(2.7f, 10){{
width = 8f;
@ -1045,7 +1053,7 @@ public class UnitTypes implements ContentList{
health = 20000;
engineOffset = 38;
engineSize = 7.3f;
hitsize = 58f;
hitSize = 58f;
destructibleWreck = false;
armor = 13f;
@ -1128,6 +1136,8 @@ public class UnitTypes implements ContentList{
range = 50f;
isCounted = false;
ammoType = AmmoTypes.powerLow;
mineTier = 1;
mineSpeed = 2.5f;
}};
@ -1145,10 +1155,12 @@ public class UnitTypes implements ContentList{
health = 400;
buildSpeed = 0.5f;
engineOffset = 6.5f;
hitsize = 8f;
hitSize = 8f;
lowAltitude = true;
isCounted = false;
ammoType = AmmoTypes.power;
mineTier = 2;
mineSpeed = 3.5f;
@ -1197,11 +1209,13 @@ public class UnitTypes implements ContentList{
flying = true;
engineOffset = 10.5f;
rotateShooting = false;
hitsize = 15f;
hitSize = 15f;
engineSize = 3f;
payloadCapacity = (2 * 2) * tilePayload;
buildSpeed = 2.5f;
ammoType = AmmoTypes.power;
weapons.add(
new Weapon("heal-weapon-mount"){{
reload = 25f;
@ -1231,12 +1245,14 @@ public class UnitTypes implements ContentList{
engineOffset = 12f;
engineSize = 6f;
rotateShooting = false;
hitsize = 32f;
hitSize = 32f;
payloadCapacity = (3 * 3) * tilePayload;
buildSpeed = 2.5f;
range = 140f;
targetAir = false;
ammoType = AmmoTypes.powerHigh;
weapons.add(
new Weapon(){{
x = y = 0f;
@ -1291,7 +1307,7 @@ public class UnitTypes implements ContentList{
engineOffset = 46f;
engineSize = 7.8f;
rotateShooting = false;
hitsize = 60f;
hitSize = 60f;
payloadCapacity = (5.3f * 5.3f) * tilePayload;
buildSpeed = 4f;
drawShields = false;
@ -1306,7 +1322,7 @@ public class UnitTypes implements ContentList{
risso = new UnitType("risso"){{
speed = 1.1f;
drag = 0.13f;
hitsize = 9f;
hitSize = 9f;
health = 280;
accel = 0.4f;
rotateSpeed = 3.3f;
@ -1357,7 +1373,7 @@ public class UnitTypes implements ContentList{
health = 600;
speed = 0.9f;
drag = 0.15f;
hitsize = 11f;
hitSize = 11f;
armor = 4f;
accel = 0.3f;
rotateSpeed = 2.6f;
@ -1400,7 +1416,7 @@ public class UnitTypes implements ContentList{
accel = 0.2f;
rotateSpeed = 1.8f;
drag = 0.17f;
hitsize = 16f;
hitSize = 16f;
armor = 7f;
rotateShooting = false;
@ -1493,7 +1509,7 @@ public class UnitTypes implements ContentList{
speed = 0.73f;
drag = 0.17f;
hitsize = 39f;
hitSize = 39f;
accel = 0.2f;
rotateSpeed = 1.3f;
rotateShooting = false;
@ -1576,7 +1592,7 @@ public class UnitTypes implements ContentList{
health = 22000;
speed = 0.62f;
drag = 0.18f;
hitsize = 50f;
hitSize = 50f;
armor = 16f;
accel = 0.19f;
rotateSpeed = 0.9f;
@ -1639,7 +1655,7 @@ public class UnitTypes implements ContentList{
itemCapacity = 30;
health = 120f;
engineOffset = 6f;
hitsize = 8f;
hitSize = 8f;
weapons.add(new Weapon("small-basic-weapon"){{
reload = 17f;
@ -1673,7 +1689,7 @@ public class UnitTypes implements ContentList{
itemCapacity = 50;
health = 150f;
engineOffset = 6f;
hitsize = 9f;
hitSize = 9f;
rotateShooting = false;
lowAltitude = true;
@ -1713,7 +1729,7 @@ public class UnitTypes implements ContentList{
itemCapacity = 70;
health = 190f;
engineOffset = 6f;
hitsize = 10f;
hitSize = 10f;
weapons.add(new Weapon("small-mount-weapon"){{
top = false;
@ -1743,7 +1759,7 @@ public class UnitTypes implements ContentList{
block = new UnitType("block"){
{
speed = 0f;
hitsize = 0f;
hitSize = 0f;
health = 1;
rotateSpeed = 360f;
itemCapacity = 0;

View File

@ -33,6 +33,7 @@ public class ContentLoader{
new StatusEffects(),
new Liquids(),
new Bullets(),
new AmmoTypes(),
new UnitTypes(),
new Blocks(),
new Loadouts(),

View File

@ -131,7 +131,7 @@ public class NetServer implements ApplicationListener{
return;
}
if(Time.millis() < info.lastKicked){
if(Time.millis() < admins.getKickTime(uuid, con.address)){
con.kick(KickReason.recentKick);
return;
}

View File

@ -15,7 +15,8 @@ public enum ContentType{
loadout_UNUSED,
typeid_UNUSED,
error,
planet;
planet,
ammo;
public static final ContentType[] all = values();
}

View File

@ -1,13 +1,23 @@
package mindustry.entities.comp;
import arc.graphics.*;
import arc.math.*;
import arc.math.geom.*;
import arc.util.*;
import mindustry.annotations.Annotations.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.*;
import static mindustry.Vars.*;
@Component
abstract class MechComp implements Posc, Flyingc, Hitboxc, Unitc, Mechc, ElevationMovec{
@Import float x, y, hitSize;
@Import UnitType type;
@SyncField(false) @SyncLocal float baseRotation;
transient float walkTime, walkExtension;
transient private boolean walked;
@ -21,6 +31,49 @@ abstract class MechComp implements Posc, Flyingc, Hitboxc, Unitc, Mechc, Elevati
walkTime += len;
walked = false;
}
//update mech effects
float extend = walkExtend(false);
float base = walkExtend(true);
float extendScl = base % 1f;
float lastExtend = walkExtension;
if(extendScl < lastExtend && base % 2f > 1f){
int side = -Mathf.sign(extend);
float width = hitSize / 2f * side, length = type.mechStride * 1.35f;
float cx = x + Angles.trnsx(baseRotation, length, width),
cy = y + Angles.trnsy(baseRotation, length, width);
if(type.mechStepShake > 0){
Effect.shake(type.mechStepShake, type.mechStepShake, cx, cy);
}
if(type.mechStepParticles){
Tile tile = world.tileWorld(cx, cy);
if(tile != null){
Color color = tile.floor().mapColor;
Fx.unitLand.at(cx, cy, hitSize/8f, color);
}
}
}
walkExtension = extendScl;
}
public float walkExtend(boolean scaled){
//now ranges from -maxExtension to maxExtension*3
float raw = walkTime % (type.mechStride * 4);
if(scaled) return raw / type.mechStride;
if(raw > type.mechStride*3) raw = raw - type.mechStride * 4;
else if(raw > type.mechStride*2) raw = type.mechStride * 2 - raw;
else if(raw > type.mechStride) raw = type.mechStride * 2 - raw;
return raw;
}
@Override

View File

@ -92,7 +92,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
@Replace
public float clipSize(){
return unit.isNull() ? 20 : unit.type().hitsize * 2f;
return unit.isNull() ? 20 : unit.type().hitSize * 2f;
}
@Override

View File

@ -30,9 +30,8 @@ import static mindustry.Vars.*;
@Component(base = true)
abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, Itemsc, Rotc, Unitc, Weaponsc, Drawc, Boundedc, Syncc, Shieldc, Displayable, Senseable{
@Import boolean hovering;
@Import float x, y, rotation, elevation, maxHealth, drag, armor, hitSize, health;
@Import boolean dead;
@Import boolean hovering, dead;
@Import float x, y, rotation, elevation, maxHealth, drag, armor, hitSize, health, ammo;
@Import Team team;
@Import int id;
@ -41,6 +40,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
boolean spawnedByCore;
transient Seq<Ability> abilities = new Seq<>(0);
private transient float resupplyTime = Mathf.random(10f);
public void moveAt(Vec2 vector){
moveAt(vector, type.accel);
@ -191,7 +191,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
this.maxHealth = type.health;
this.drag = type.drag;
this.armor = type.armor;
this.hitSize = type.hitsize;
this.hitSize = type.hitSize;
this.hovering = type.hovering;
if(controller == null) controller(type.createController());
@ -245,6 +245,16 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
type.update(self());
if(state.rules.unitAmmo && ammo < type.ammoCapacity - 0.0001f){
resupplyTime += Time.delta;
//resupply only at a fixed interval to prevent lag
if(resupplyTime > 10f){
type.ammoType.resupply(self());
resupplyTime = 0f;
}
}
if(abilities.size > 0){
for(Ability a : abilities){
a.update(self());
@ -366,7 +376,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
if(!headless){
for(int i = 0; i < type.wreckRegions.length; i++){
if(type.wreckRegions[i].found()){
float range = type.hitsize/4f;
float range = type.hitSize /4f;
Tmp.v1.rnd(range);
Effect.decal(type.wreckRegions[i], x + Tmp.v1.x, y + Tmp.v1.y, rotation - 90);
}

View File

@ -228,7 +228,7 @@ public class FloorRenderer implements Disposable{
int chunksx = Mathf.ceil((float)(world.width()) / chunksize),
chunksy = Mathf.ceil((float)(world.height()) / chunksize);
cache = new Chunk[chunksx][chunksy];
cbatch = new MultiCacheBatch(chunksize * chunksize * 7);
cbatch = new MultiCacheBatch(chunksize * chunksize * 8);
Time.mark();

View File

@ -113,7 +113,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
Payloadc pay = (Payloadc)unit;
if(target.isAI() && target.isGrounded() && pay.canPickup(target)
&& target.within(unit, unit.type().hitsize * 2f + target.type().hitsize * 2f)){
&& target.within(unit, unit.type().hitSize * 2f + target.type().hitSize * 2f)){
Call.pickedUnitPayload(player, target);
}
}
@ -395,7 +395,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
if(!(unit instanceof Payloadc)) return;
Payloadc pay = (Payloadc)unit;
Unit target = Units.closest(player.team(), pay.x(), pay.y(), unit.type().hitsize * 2.5f, u -> u.isAI() && u.isGrounded() && pay.canPickup(u) && u.within(unit, u.hitSize + unit.hitSize * 1.2f));
Unit target = Units.closest(player.team(), pay.x(), pay.y(), unit.type().hitSize * 2.5f, u -> u.isAI() && u.isGrounded() && pay.canPickup(u) && u.within(unit, u.hitSize + unit.hitSize * 1.2f));
if(target != null){
Call.requestUnitPayload(player, target);
}else{

View File

@ -24,6 +24,7 @@ public class Administration{
public Seq<ChatFilter> chatFilters = new Seq<>();
public Seq<ActionFilter> actionFilters = new Seq<>();
public Seq<String> subnetBans = new Seq<>();
public ObjectMap<String, Long> kickedIPs = new ObjectMap<>();
/** All player info. Maps UUIDs to info. This persists throughout restarts. Do not access directly. */
private ObjectMap<String, PlayerInfo> playerInfo = new ObjectMap<>();
@ -86,6 +87,20 @@ public class Administration{
});
}
/** @return time at which a player would be pardoned for a kick (0 means they were never kicked) */
public long getKickTime(String uuid, String ip){
return Math.max(getInfo(uuid).lastKicked, kickedIPs.get(ip, 0L));
}
/** Sets up kick duration for a player. */
public void handleKicked(String uuid, String ip, long duration){
kickedIPs.put(ip, Math.max(kickedIPs.get(ip, 0L), Time.millis() + duration));
PlayerInfo info = getInfo(uuid);
info.timesKicked++;
info.lastKicked = Math.max(Time.millis() + duration, info.lastKicked);
}
public Seq<String> getSubnetBans(){
return subnetBans;
}

View File

@ -65,9 +65,7 @@ public abstract class NetConnection{
Log.info("Kicking connection @; Reason: @", address, reason.replace("\n", " "));
PlayerInfo info = netServer.admins.getInfo(uuid);
info.timesKicked++;
info.lastKicked = Math.max(Time.millis() + kickDuration, info.lastKicked);
netServer.admins.handleKicked(uuid, address, kickDuration);
Call.kick(this, reason);

View File

@ -0,0 +1,28 @@
package mindustry.type;
import arc.graphics.*;
import mindustry.ctype.*;
import mindustry.gen.*;
import mindustry.graphics.*;
/** Type of ammo that a unit uses. */
public class AmmoType extends Content{
public String icon = Iconc.itemCopper + "";
public Color color = Pal.ammo;
public Color barColor = Pal.ammo;
public AmmoType(char icon, Color color){
this.icon = icon + "";
this.color = color;
}
public AmmoType(){
}
public void resupply(Unit unit){}
@Override
public ContentType getContentType(){
return ContentType.ammo;
}
}

View File

@ -0,0 +1,86 @@
package mindustry.type;
import arc.util.ArcAnnotate.*;
import mindustry.*;
import mindustry.content.*;
import mindustry.ctype.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.world.*;
import mindustry.world.meta.*;
public class AmmoTypes implements ContentList{
public static AmmoType
powerLow,
power,
powerHigh,
copper,
thorium;
@Override
public void load(){
powerLow = new PowerAmmoType(500);
power = new PowerAmmoType(1000);
powerHigh = new PowerAmmoType(2000);
copper = new ItemAmmoType(Items.copper);
thorium = new ItemAmmoType(Items.thorium);
}
public static class PowerAmmoType extends AmmoType{
public float totalPower = 1000;
public PowerAmmoType(){
super(Iconc.power, Pal.powerLight);
barColor = color;
}
public PowerAmmoType(float totalPower){
this();
this.totalPower = totalPower;
}
@Override
public void resupply(Unit unit){
float range = unit.hitSize + 60f;
Tile closest = Vars.indexer.findClosestFlag(unit.x, unit.y, unit.team, BlockFlag.powerResupply);
if(closest != null && closest.build != null && unit.within(closest.build, range) && closest.build.power != null){
Building build = closest.build;
if(build.block.consumes.hasPower() && build.block.consumes.getPower().buffered){
float amount = closest.build.power.status * build.block.consumes.getPower().capacity;
float powerPerAmmo = totalPower / unit.type().ammoCapacity;
float ammoRequired = unit.type().ammoCapacity - unit.ammo;
float powerRequired = ammoRequired * powerPerAmmo;
float powerTaken = Math.min(amount, powerRequired);
if(powerTaken > 1){
closest.build.power.status -= powerTaken / build.block.consumes.getPower().capacity;
unit.ammo += powerTaken / powerPerAmmo;
Fx.itemTransfer.at(build.x, build.y, Math.max(powerTaken / 100f, 1f), Pal.power, unit);
}
}
}
}
}
public static class ItemAmmoType extends AmmoType{
public @NonNull Item item;
public ItemAmmoType(Item item){
this.item = item;
this.color = item.color;
}
public ItemAmmoType(){
}
@Override
public void load(){
if(item != null){
icon = item.emoji();
}
}
}
}

View File

@ -56,7 +56,7 @@ public class StatusEffect extends MappableContent{
}
if(effect != Fx.none && Mathf.chanceDelta(effectChance)){
Tmp.v1.rnd(unit.type().hitsize/2f);
Tmp.v1.rnd(unit.type().hitSize /2f);
effect.at(unit.x + Tmp.v1.x, unit.y + Tmp.v1.y);
}
}

View File

@ -72,7 +72,8 @@ public class UnitType extends UnlockableContent{
public Color mechLegColor = Pal.darkMetal;
public int itemCapacity = -1;
public int ammoCapacity = 220;
public int ammoCapacity = -1;
public AmmoType ammoType = AmmoTypes.copper;
public int mineTier = -1;
public float buildSpeed = 1f, mineSpeed = 1f;
@ -80,7 +81,7 @@ public class UnitType extends UnlockableContent{
public boolean canDrown = true;
public float engineOffset = 5f, engineSize = 2.5f;
public float strafePenalty = 0.5f;
public float hitsize = 6f;
public float hitSize = 6f;
public float itemOffsetY = 3f;
public float lightRadius = 60f, lightOpacity = 0.6f;
public Color lightColor = Pal.powerLight;
@ -136,41 +137,6 @@ public class UnitType extends UnlockableContent{
public void update(Unit unit){
if(unit instanceof Mechc && !unit.isFlying()){
updateMechEffects(unit);
}
}
public void updateMechEffects(Unit unit){
Mechc mech = (Mechc)unit;
float extend = walkExtend((Mechc)unit, false);
float base = walkExtend((Mechc)unit, true);
float extendScl = base % 1f;
float lastExtend = mech.walkExtension();
if(extendScl < lastExtend && base % 2f > 1f){
int side = -Mathf.sign(extend);
float width = hitsize / 2f * side, length = mechStride * 1.35f;
float cx = unit.x + Angles.trnsx(mech.baseRotation(), length, width),
cy = unit.y + Angles.trnsy(mech.baseRotation(), length, width);
if(mechStepShake > 0){
Effect.shake(mechStepShake, mechStepShake, cx, cy);
}
if(mechStepParticles){
Tile tile = world.tileWorld(cx, cy);
if(tile != null){
Color color = tile.floor().mapColor;
Fx.unitLand.at(cx, cy, hitsize/8f, color);
}
}
}
mech.walkExtension(extendScl);
}
public void landed(Unit unit){}
@ -184,13 +150,13 @@ public class UnitType extends UnlockableContent{
table.row();
table.table(bars -> {
bars.defaults().growX().height(18f).pad(4);
bars.defaults().growX().height(20f).pad(4);
bars.add(new Bar("blocks.health", Pal.health, unit::healthf).blink(Color.white));
bars.row();
if(state.rules.unitAmmo){
bars.add(new Bar("blocks.ammo", Pal.ammo, () -> unit.ammo / ammoCapacity));
bars.add(new Bar(ammoType.icon + " " + Core.bundle.get("blocks.ammo"), ammoType.barColor, () -> unit.ammo / ammoCapacity));
bars.row();
}
}).growX();
@ -237,24 +203,24 @@ public class UnitType extends UnlockableContent{
singleTarget = weapons.size <= 1;
if(itemCapacity < 0){
itemCapacity = Math.max(Mathf.round(hitsize * 7, 20), 20);
itemCapacity = Math.max(Mathf.round(hitSize * 7, 20), 20);
}
//set up default range
if(range < 0){
range = Float.MAX_VALUE;
for(Weapon weapon : weapons){
range = Math.min(range, weapon.bullet.range() + hitsize/2f);
range = Math.min(range, weapon.bullet.range() + hitSize /2f);
}
}
if(mechStride < 0){
mechStride = 4f + (hitsize-8f)/2.1f;
mechStride = 4f + (hitSize -8f)/2.1f;
}
if(mechStepShake < 0){
mechStepShake = Mathf.round((hitsize - 11f) / 9f);
mechStepParticles = hitsize > 15f;
mechStepShake = Mathf.round((hitSize - 11f) / 9f);
mechStepParticles = hitSize > 15f;
}
canHeal = weapons.contains(w -> w.bullet instanceof HealBulletType);
@ -281,6 +247,15 @@ public class UnitType extends UnlockableContent{
}
}
this.weapons = mapped;
//dynamically create ammo capacity based on firing rate
if(ammoCapacity < 0){
float shotsPerSecond = weapons.sumf(w -> 60f / w.reload);
//duration of continuous fire without reload
float targetSeconds = 30;
ammoCapacity = Math.max(1, (int)(shotsPerSecond * targetSeconds));
}
}
@CallSuper
@ -342,7 +317,7 @@ public class UnitType extends UnlockableContent{
public void draw(Unit unit){
Mechc mech = unit instanceof Mechc ? (Mechc)unit : null;
float z = unit.elevation > 0.5f ? (lowAltitude ? Layer.flyingUnitLow : Layer.flyingUnit) : groundLayer + Mathf.clamp(hitsize/4000f, 0, 0.01f);
float z = unit.elevation > 0.5f ? (lowAltitude ? Layer.flyingUnitLow : Layer.flyingUnit) : groundLayer + Mathf.clamp(hitSize /4000f, 0, 0.01f);
if(unit.controller().isBeingControlled(player.unit())){
drawControl(unit);
@ -359,10 +334,10 @@ public class UnitType extends UnlockableContent{
drawMech(mech);
//side
legOffset.trns(mech.baseRotation(), 0f, Mathf.lerp(Mathf.sin(walkExtend(mech, true), 2f/Mathf.PI, 1) * mechSideSway, 0f, unit.elevation));
legOffset.trns(mech.baseRotation(), 0f, Mathf.lerp(Mathf.sin(mech.walkExtend(true), 2f/Mathf.PI, 1) * mechSideSway, 0f, unit.elevation));
//front
legOffset.add(Tmp.v1.trns(mech.baseRotation() + 90, 0f, Mathf.lerp(Mathf.sin(walkExtend(mech, true), 1f/Mathf.PI, 1) * mechFrontSway, 0f, unit.elevation)));
legOffset.add(Tmp.v1.trns(mech.baseRotation() + 90, 0f, Mathf.lerp(Mathf.sin(mech.walkExtend(true), 1f/Mathf.PI, 1) * mechFrontSway, 0f, unit.elevation)));
unit.trns(legOffset.x, legOffset.y);
}
@ -656,8 +631,8 @@ public class UnitType extends UnlockableContent{
float e = unit.elevation;
float sin = Mathf.lerp(Mathf.sin(walkExtend(mech, true), 2f / Mathf.PI, 1f), 0f, e);
float extension = Mathf.lerp(walkExtend(mech, false), 0, e);
float sin = Mathf.lerp(Mathf.sin(mech.walkExtend(true), 2f / Mathf.PI, 1f), 0f, e);
float extension = Mathf.lerp(mech.walkExtend(false), 0, e);
float boostTrns = e * 2f;
Floor floor = unit.isFlying() ? Blocks.air.asFloor() : unit.floorOn();
@ -690,20 +665,6 @@ public class UnitType extends UnlockableContent{
Draw.mixcol();
}
public float walkExtend(Mechc mech, boolean scaled){
//now ranges from -maxExtension to maxExtension*3
float raw = mech.walkTime() % (mechStride * 4);
if(scaled) return raw / mechStride;
if(raw > mechStride*3) raw = raw - mechStride * 4;
else if(raw > mechStride*2) raw = mechStride * 2 - raw;
else if(raw > mechStride) raw = mechStride * 2 - raw;
return raw;
}
public void applyColor(Unit unit){
Draw.color();
Draw.mixcol(Color.white, unit.hitTime);

View File

@ -21,7 +21,7 @@ public class Bar extends Element{
public Bar(String name, Color color, Floatp fraction){
this.fraction = fraction;
this.name = Core.bundle.get(name);
this.name = Core.bundle.get(name, name);
this.blinkColor.set(color);
lastValue = value = fraction.get();
setColor(color);

View File

@ -130,7 +130,7 @@ public class ContentDisplay{
public static void displayUnit(Table table, UnitType unit){
table.table(title -> {
title.image(unit.icon(Cicon.xlarge));
title.image(unit.icon(Cicon.xlarge)).size(8 * 6).scaling(Scaling.fit);
title.add("[accent]" + unit.localizedName).padLeft(5);
});

View File

@ -30,6 +30,7 @@ public class JoinDialog extends BaseDialog{
Table global = new Table();
Table hosts = new Table();
int totalHosts;
int refreshes;
public JoinDialog(){
super("@joingame");
@ -95,6 +96,8 @@ public class JoinDialog extends BaseDialog{
}
void refreshAll(){
refreshes ++;
refreshLocal();
refreshRemote();
refreshGlobal();
@ -327,12 +330,15 @@ public class JoinDialog extends BaseDialog{
}
void refreshGlobal(){
int cur = refreshes;
global.clear();
global.background(null);
for(String host : defaultServers){
String resaddress = host.contains(":") ? host.split(":")[0] : host;
int resport = host.contains(":") ? Strings.parseInt(host.split(":")[1]) : port;
net.pingHost(resaddress, resport, res -> {
if(refreshes != cur) return;
res.port = resport;
addGlobalHost(res);
}, e -> {});

View File

@ -93,7 +93,7 @@ public class SettingsMenuDialog extends SettingsDialog{
ObjectMap<String, Object> map = new ObjectMap<>();
for(String value : Core.settings.keys()){
if(value.contains("usid") || value.contains("uuid")){
map.put(value, Core.settings.getString(value));
map.put(value, Core.settings.get(value, null));
}
}
Core.settings.clear();

View File

@ -741,7 +741,7 @@ public class HudFragment extends Fragment{
t.add(new SideBar(() -> player.unit().healthf(), () -> true, true)).width(bw).growY().padRight(pad);
t.image(() -> player.icon()).scaling(Scaling.bounded).grow().maxWidth(54f);
t.add(new SideBar(() -> player.dead() ? 0f : player.displayAmmo() ? player.unit().ammof() : player.unit().healthf(), () -> !player.displayAmmo(), false)).width(bw).growY().padLeft(pad).update(b -> {
b.color.set(player.displayAmmo() ? Pal.ammo : Pal.health);
b.color.set(player.displayAmmo() ? player.dead() ? Pal.ammo : player.unit().type().ammoType.color : Pal.health);
});
t.getChildren().get(1).toFront();

View File

@ -2,8 +2,10 @@ package mindustry.world.blocks.power;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.struct.*;
import mindustry.annotations.Annotations.*;
import mindustry.gen.*;
import mindustry.world.meta.*;
import static mindustry.Vars.tilesize;
@ -17,6 +19,7 @@ public class Battery extends PowerDistributor{
super(name);
outputsPower = true;
consumesPower = true;
flags = EnumSet.of(BlockFlag.powerResupply);
}
public class BatteryBuild extends Building{

View File

@ -5,6 +5,7 @@ import mindustry.content.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.type.AmmoTypes.*;
import mindustry.world.*;
import static mindustry.Vars.*;
@ -53,10 +54,10 @@ public class ResupplyPoint extends Block{
public static boolean resupply(Building tile, float range, int ammoAmount, Color ammoColor){
if(!state.rules.unitAmmo) return false;
Unit unit = Units.closest(tile.team, tile.x, tile.y, range, u -> u.ammo() <= u.type().ammoCapacity - ammoAmount);
Unit unit = Units.closest(tile.team, tile.x, tile.y, range, u -> u.type().ammoType instanceof ItemAmmoType && 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));
unit.ammo = Math.min(unit.ammo + ammoAmount, unit.type().ammoCapacity);
return true;
}

View File

@ -12,6 +12,8 @@ public enum BlockFlag{
repair,
/** Rally point. */
rally,
/** Block that stored power for resupply. */
powerResupply,
/** Any block that boosts unit capacity. */
unitModifier;