mirror of
https://github.com/Anuken/Mindustry.git
synced 2026-10-01 18:50:27 +03:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -3413,7 +3413,7 @@ name.token.read = olvasás
|
||||
name.token.write = írás
|
||||
name.token.from = innen:
|
||||
name.token.char = karakter
|
||||
name.token.linknum = hivatkozás\#
|
||||
name.token.linknum = hivatkozás#
|
||||
name.token.draw = rajzolás
|
||||
name.token.clear = törlés
|
||||
name.token.apply = alkalmaz
|
||||
@@ -3472,7 +3472,7 @@ name.token.volume = hangerő
|
||||
name.token.pitch = hangmagasság
|
||||
name.token.pan = térhatás
|
||||
name.token.limit = korlát
|
||||
name.token.of-id- = azonosító alapján\#
|
||||
name.token.of-id- = azonosító alapján#
|
||||
name.token.replace = csere?
|
||||
name.token.for = ezért:
|
||||
name.token.success = siker
|
||||
|
||||
@@ -355,19 +355,25 @@ public class UnitTypes{
|
||||
|
||||
nova = new UnitType("nova"){{
|
||||
canBoost = true;
|
||||
boostMultiplier = 1.5f;
|
||||
boostMultiplier = 2f;
|
||||
speed = 0.55f;
|
||||
hitSize = 8f;
|
||||
health = 120f;
|
||||
health = 200f;
|
||||
buildSpeed = 0.3f;
|
||||
armor = 1f;
|
||||
|
||||
abilities.add(new RepairFieldAbility(10f, 60f * 4, 60f));
|
||||
abilities.add(new RepairFieldAbility(20f, 60f * 2, 100f){{
|
||||
sameTypeHealMult = 0.15f;
|
||||
maxTargets = 6;
|
||||
|
||||
smartHeal = true;
|
||||
smartDowntime = 60 * 4f;
|
||||
}});
|
||||
|
||||
weapons.add(new Weapon("heal-weapon"){{
|
||||
top = false;
|
||||
shootY = 2f;
|
||||
reload = 24f;
|
||||
reload = 30f;
|
||||
x = 4.5f;
|
||||
alternate = false;
|
||||
ejectEffect = Fx.none;
|
||||
@@ -377,6 +383,9 @@ public class UnitTypes{
|
||||
bullet = new LaserBoltBulletType(5.2f, 13){{
|
||||
lifetime = 30f;
|
||||
healPercent = 5f;
|
||||
pierce = true;
|
||||
pierceBuilding = true;
|
||||
pierceCap = 2;
|
||||
collidesTeam = true;
|
||||
backColor = Pal.heal;
|
||||
frontColor = Color.white;
|
||||
@@ -1370,7 +1379,11 @@ public class UnitTypes{
|
||||
mineSpeed = 3.5f;
|
||||
wreckSoundVolume = 0.9f;
|
||||
|
||||
abilities.add(new RepairFieldAbility(5f, 60f * 8, 50f));
|
||||
abilities.add(new RepairFieldAbility(){{
|
||||
amount = 5f;
|
||||
reload = 60f * 8f;
|
||||
range = 50f;
|
||||
}});
|
||||
|
||||
weapons.add(new Weapon("poly-weapon"){{
|
||||
top = false;
|
||||
|
||||
@@ -4,10 +4,12 @@ import arc.*;
|
||||
import arc.audio.*;
|
||||
import arc.math.*;
|
||||
import arc.scene.ui.layout.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.entities.*;
|
||||
import mindustry.gen.*;
|
||||
import java.util.*;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
@@ -20,11 +22,29 @@ public class RepairFieldAbility extends Ability{
|
||||
public boolean parentizeEffects = false;
|
||||
/** Multiplies healing to units of the same type by this amount. */
|
||||
public float sameTypeHealMult = 1f;
|
||||
/** Maximum number of units healed. */
|
||||
public int maxTargets = -1;
|
||||
|
||||
protected float timer;
|
||||
protected boolean wasHealed = false;
|
||||
/** If true, this ability will consider missing hp, number of targets, cooldowns...etc. */
|
||||
public boolean smartHeal = false;
|
||||
/** If a damaged unit health % is lower than this heal it as soon as possible. Values close to 1f will likely waste healing potential. */
|
||||
public float smartHealPercent = 0f;
|
||||
/** A multiplier on potential healing efficiency. High values -> efficient aoe healing. Low values -> efficient single target healing. */
|
||||
public float smartHealStrength = 1f;
|
||||
/** If all damaged units havent been hurt for at least this amount of time, force healing them, regardless of thresholds. */
|
||||
public float smartDowntime = 60f * 8f;
|
||||
/** How often to check for healing when at least 1 damaged unit is found. */
|
||||
public float smartInterval = 20f;
|
||||
/** Random initial reload multiplier to check for damaged units. Useful for desyncing healer timers once. */
|
||||
public float randDesync = -1f;
|
||||
|
||||
RepairFieldAbility(){}
|
||||
//a high capacity is needed to account for t1 spam in custom gamemodes, but set too high it becomes expensive
|
||||
protected static Seq<Unit> targets = new Seq<>(50);
|
||||
protected float healTimer, downTimer;
|
||||
protected float healthMissing, sumMaxHealth, sumTypeMult, healthChange;
|
||||
protected boolean hasHealed, healNow;
|
||||
|
||||
public RepairFieldAbility(){}
|
||||
|
||||
public RepairFieldAbility(float amount, float reload, float range){
|
||||
this.amount = amount;
|
||||
@@ -57,30 +77,80 @@ public class RepairFieldAbility extends Ability{
|
||||
t.row();
|
||||
t.add(abilityStat("sametypehealmultiplier", (sameTypeHealMult < 1f ? "[negstat]" : "") + Strings.autoFixed(sameTypeHealMult * 100f, 2)));
|
||||
}
|
||||
if(maxTargets > 0){
|
||||
t.row();
|
||||
t.add(abilityStat("maxtargets", maxTargets));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Unit unit){
|
||||
timer += Time.delta;
|
||||
healTimer += Time.delta;
|
||||
downTimer = smartHeal && healthChange >= healthMissing && healthMissing > 0f ? downTimer + Time.delta : 0f;
|
||||
|
||||
if(timer >= reload){
|
||||
wasHealed = false;
|
||||
if(healTimer >= reload){
|
||||
targets.clear();
|
||||
hasHealed = healNow = false;
|
||||
healthChange = healthMissing;
|
||||
healthMissing = sumMaxHealth = sumTypeMult = 0f;
|
||||
|
||||
boolean limitTargets = maxTargets >= 0;
|
||||
float healPercentMult = healPercent / 100f;
|
||||
|
||||
Units.nearby(unit.team, unit.x, unit.y, range, other -> {
|
||||
//check for 2 more targets just in case
|
||||
if(limitTargets && targets.size >= maxTargets + 2) return;
|
||||
|
||||
if(other.damaged()){
|
||||
healEffect.at(other, parentizeEffects);
|
||||
wasHealed = true;
|
||||
targets.add(other);
|
||||
if(smartHeal){
|
||||
float maxHealth = other.maxHealth();
|
||||
healthMissing += maxHealth - other.health();
|
||||
sumMaxHealth += maxHealth;
|
||||
sumTypeMult += unit.type == other.type ? sameTypeHealMult : 1f;
|
||||
if(other.healthf() < smartHealPercent) healNow = true;
|
||||
}
|
||||
}
|
||||
float healMult = unit.type == other.type ? sameTypeHealMult : 1f;
|
||||
other.heal((amount + healPercent / 100f * other.maxHealth()) * healMult);
|
||||
});
|
||||
int targetCount = targets.size;
|
||||
|
||||
if(wasHealed){
|
||||
activeEffect.at(unit, range);
|
||||
sound.at(unit, 1f + Mathf.range(0.1f), soundVolume);
|
||||
//mixed approach, care both about groups and single low hp units
|
||||
float ratio = amount + healPercentMult * sumMaxHealth * (sumTypeMult / targetCount);
|
||||
float requiredHeals = (healthMissing * 0.7f + healthMissing / (limitTargets ? maxTargets : targetCount) * 0.3f) / smartHealStrength / ratio;
|
||||
|
||||
if(requiredHeals >= 1f || !smartHeal || healNow || downTimer >= smartDowntime){
|
||||
|
||||
//sort closest if number of targets is limited
|
||||
if(limitTargets){
|
||||
boolean isSameType = sameTypeHealMult < 1f;
|
||||
targets.sort(u -> u.dst2(unit.x, unit.y) + (isSameType && u.type() == unit.type ? 6400f : 0f));
|
||||
}
|
||||
|
||||
int len = limitTargets ? Math.min(targetCount, maxTargets) : targetCount;
|
||||
for(int i = 0; i < len; i++){
|
||||
Unit other = targets.get(i);
|
||||
if(other.damaged()){
|
||||
float maxHealth = other.maxHealth();
|
||||
float healMult = unit.type == other.type ? sameTypeHealMult : 1f;
|
||||
other.heal((amount + healPercentMult * maxHealth) * healMult);
|
||||
healEffect.at(other, parentizeEffects);
|
||||
hasHealed = true;
|
||||
}
|
||||
}
|
||||
if(hasHealed){
|
||||
healTimer = 0f;
|
||||
activeEffect.at(unit, range);
|
||||
sound.at(unit, 1f + Mathf.range(0.1f), soundVolume);
|
||||
}
|
||||
|
||||
//increase how often this checks if there are damaged units but still below the healing threshold
|
||||
}else if(smartHeal && targetCount > 0){
|
||||
healTimer = reload >= (2f * smartInterval) ? reload - smartInterval : smartInterval;
|
||||
}else if(randDesync > 0){
|
||||
healTimer = Mathf.random(randDesync) * reload;
|
||||
}else{
|
||||
healTimer = 0;
|
||||
}
|
||||
|
||||
timer = 0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user