Improvements of status effects in database
Before Width: | Height: | Size: 276 B |
Before Width: | Height: | Size: 343 B |
Before Width: | Height: | Size: 329 B |
Before Width: | Height: | Size: 304 B |
Before Width: | Height: | Size: 286 B |
Before Width: | Height: | Size: 387 B |
Before Width: | Height: | Size: 387 B |
Before Width: | Height: | Size: 322 B |
Before Width: | Height: | Size: 283 B |
@ -628,11 +628,10 @@ status.melting.name = Melting
|
||||
status.sapped.name = Sapped
|
||||
status.spore-slowed.name = Spore Slowed
|
||||
status.tarred.name = Tarred
|
||||
status.overdrive.name = Overdrive
|
||||
status.overclock.name = Overclock
|
||||
status.shocked.name = Shocked
|
||||
status.blasted.name = Blasted
|
||||
status.disarmed.name = Disarmed
|
||||
status.unmoving = Unmoving
|
||||
|
||||
settings.language = Language
|
||||
settings.data = Game Data
|
||||
|
@ -315,3 +315,22 @@
|
||||
63418=legacy-unit-factory-ground|block-legacy-unit-factory-ground-medium
|
||||
63417=interplanetary-accelerator|block-interplanetary-accelerator-medium
|
||||
63416=basalt-boulder|block-basalt-boulder-medium
|
||||
63415=none|status-none-icon
|
||||
63414=burning|status-burning-icon
|
||||
63413=freezing|status-freezing-icon
|
||||
63412=unmoving|status-unmoving-icon
|
||||
63411=slow|status-slow-icon
|
||||
63410=wet|status-wet-icon
|
||||
63409=muddy|status-muddy-icon
|
||||
63408=melting|status-melting-icon
|
||||
63407=sapped|status-sapped-icon
|
||||
63406=spore-slowed|status-spore-slowed-icon
|
||||
63405=tarred|status-tarred-icon
|
||||
63404=overdrive|status-overdrive-icon
|
||||
63403=overclock|status-overclock-icon
|
||||
63402=shielded|status-shielded-icon
|
||||
63401=boss|status-boss-icon
|
||||
63400=shocked|status-shocked-icon
|
||||
63399=blasted|status-blasted-icon
|
||||
63398=corroded|status-corroded-icon
|
||||
63397=disarmed|status-disarmed-icon
|
||||
|
@ -12,7 +12,7 @@ import mindustry.graphics.*;
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
public class StatusEffects implements ContentList{
|
||||
public static StatusEffect none, burning, freezing, unmoving, slow, wet, muddy, melting, sapped, tarred, overdrive, overclock, shielded, shocked, blasted, corroded, boss, sporeSlowed, disarmed;
|
||||
public static StatusEffect none, burning, freezing, unmoving, slow, wet, muddy, melting, sapped, tarred, overdrive, overclock, shielded, shocked, blasted, boss, sporeSlowed, disarmed;
|
||||
|
||||
@Override
|
||||
public void load(){
|
||||
@ -20,14 +20,15 @@ public class StatusEffects implements ContentList{
|
||||
none = new StatusEffect("none");
|
||||
|
||||
burning = new StatusEffect("burning"){{
|
||||
color = Pal.lightFlame;
|
||||
color = Color.valueOf("ffc455");
|
||||
damage = 0.12f; //over 8 seconds, this would be ~60 damage
|
||||
effect = Fx.burning;
|
||||
transitionDamage = 8f;
|
||||
|
||||
init(() -> {
|
||||
opposite(wet, freezing);
|
||||
affinity(tarred, ((unit, time, newTime, result) -> {
|
||||
unit.damagePierce(8f);
|
||||
unit.damagePierce(transitionDamage);
|
||||
Fx.burning.at(unit.x + Mathf.range(unit.bounds() / 2f), unit.y + Mathf.range(unit.bounds() / 2f));
|
||||
result.set(burning, Math.min(time + newTime, 300f));
|
||||
}));
|
||||
@ -39,12 +40,13 @@ public class StatusEffects implements ContentList{
|
||||
speedMultiplier = 0.6f;
|
||||
healthMultiplier = 0.8f;
|
||||
effect = Fx.freezing;
|
||||
transitionDamage = 18f;
|
||||
|
||||
init(() -> {
|
||||
opposite(melting, burning);
|
||||
|
||||
affinity(blasted, ((unit, time, newTime, result) -> {
|
||||
unit.damagePierce(18f);
|
||||
unit.damagePierce(transitionDamage);
|
||||
result.set(freezing, time);
|
||||
}));
|
||||
});
|
||||
@ -65,10 +67,11 @@ public class StatusEffects implements ContentList{
|
||||
speedMultiplier = 0.94f;
|
||||
effect = Fx.wet;
|
||||
effectChance = 0.09f;
|
||||
transitionDamage = 14;
|
||||
|
||||
init(() -> {
|
||||
affinity(shocked, ((unit, time, newTime, result) -> {
|
||||
unit.damagePierce(14f);
|
||||
unit.damagePierce(transitionDamage);
|
||||
if(unit.team == state.rules.waveTeam){
|
||||
Events.fire(Trigger.shock);
|
||||
}
|
||||
@ -169,11 +172,6 @@ public class StatusEffects implements ContentList{
|
||||
reactive = true;
|
||||
}};
|
||||
|
||||
corroded = new StatusEffect("corroded"){{
|
||||
color = Pal.plastanium;
|
||||
damage = 0.1f;
|
||||
}};
|
||||
|
||||
disarmed = new StatusEffect("disarmed"){{
|
||||
color = Color.valueOf("e9ead3");
|
||||
disarm = true;
|
||||
|
@ -139,7 +139,9 @@ public class Control implements ApplicationListener, Loadable{
|
||||
}));
|
||||
|
||||
Events.on(UnlockEvent.class, e -> {
|
||||
ui.hudfrag.showUnlock(e.content);
|
||||
if(e.content.showUnlock()){
|
||||
ui.hudfrag.showUnlock(e.content);
|
||||
}
|
||||
|
||||
checkAutoUnlocks();
|
||||
|
||||
|
@ -95,6 +95,10 @@ public abstract class UnlockableContent extends MappableContent{
|
||||
return cicons[icon.ordinal()];
|
||||
}
|
||||
|
||||
public Cicon prefDatabaseIcon(){
|
||||
return Cicon.xlarge;
|
||||
}
|
||||
|
||||
/** Iterates through any implicit dependencies of this content.
|
||||
* For blocks, this would be the items required to build it. */
|
||||
public void getDependencies(Cons<UnlockableContent> cons){
|
||||
@ -115,6 +119,11 @@ public abstract class UnlockableContent extends MappableContent{
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @return whether to show a notification toast when this is unlocked */
|
||||
public boolean showUnlock(){
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Makes this piece of content unlocked; if it already unlocked, nothing happens. */
|
||||
public void unlock(){
|
||||
if(!unlocked && !alwaysUnlocked){
|
||||
|
@ -33,6 +33,11 @@ abstract class StatusComp implements Posc, Flyingc{
|
||||
void apply(StatusEffect effect, float duration){
|
||||
if(effect == StatusEffects.none || effect == null || isImmune(effect)) return; //don't apply empty or immune effects
|
||||
|
||||
//unlock status effects regardless of whether they were applied to friendly units
|
||||
if(state.isCampaign()){
|
||||
effect.unlock();
|
||||
}
|
||||
|
||||
if(statuses.size > 0){
|
||||
//check for opposite effects
|
||||
for(int i = 0; i < statuses.size; i ++){
|
||||
|
@ -208,9 +208,7 @@ public class JsonIO{
|
||||
static class CustomJson extends Json{
|
||||
private Object baseObject;
|
||||
|
||||
{
|
||||
apply(this);
|
||||
}
|
||||
{ apply(this); }
|
||||
|
||||
@Override
|
||||
public <T> T fromJson(Class<T> type, String json){
|
||||
|
@ -1,7 +1,6 @@
|
||||
package mindustry.type;
|
||||
|
||||
import arc.graphics.*;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.math.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
@ -10,8 +9,8 @@ import mindustry.ctype.*;
|
||||
import mindustry.entities.*;
|
||||
import mindustry.entities.units.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.world.meta.*;
|
||||
import mindustry.ui.*;
|
||||
import mindustry.world.meta.*;
|
||||
|
||||
public class StatusEffect extends UnlockableContent{
|
||||
/** Damage dealt by the unit with the effect. */
|
||||
@ -24,6 +23,8 @@ public class StatusEffect extends UnlockableContent{
|
||||
public float reloadMultiplier = 1f;
|
||||
/** Unit build speed multiplier. */
|
||||
public float buildSpeedMultiplier = 1f;
|
||||
/** Damage dealt upon transition to an affinity. */
|
||||
public float transitionDamage = 0f;
|
||||
/** Unit weapon(s) disabled. */
|
||||
public boolean disarm = false;
|
||||
/** Damage per frame. */
|
||||
@ -66,37 +67,39 @@ public class StatusEffect extends UnlockableContent{
|
||||
|
||||
@Override
|
||||
public void setStats(){
|
||||
if(damageMultiplier != 1){
|
||||
stats.addPercent(Stat.damageMultiplier, damageMultiplier);
|
||||
if(damageMultiplier != 1) stats.addPercent(Stat.damageMultiplier, damageMultiplier);
|
||||
if(healthMultiplier != 1) stats.addPercent(Stat.healthMultiplier, healthMultiplier);
|
||||
if(speedMultiplier != 1) stats.addPercent(Stat.speedMultiplier, speedMultiplier);
|
||||
if(reloadMultiplier != 1) stats.addPercent(Stat.reloadMultiplier, reloadMultiplier);
|
||||
if(buildSpeedMultiplier != 1) stats.addPercent(Stat.buildSpeedMultiplier, buildSpeedMultiplier);
|
||||
if(damage > 0) stats.add(Stat.damage, damage * 60f, StatUnit.perSecond);
|
||||
|
||||
var afseq = affinities.asArray().sort();
|
||||
var opseq = opposites.asArray().sort();
|
||||
|
||||
for(int i = 0; i < afseq.size; i++){
|
||||
var e = afseq.get(i);
|
||||
stats.add(Stat.affinities, e.emoji() + "" + e.toString());
|
||||
}
|
||||
|
||||
if(afseq.any() && transitionDamage != 0){
|
||||
stats.add(Stat.affinities, "/ [accent]" + (int)transitionDamage + " " + Stat.damage.localized());
|
||||
}
|
||||
|
||||
if(healthMultiplier != 1){
|
||||
stats.addPercent(Stat.healthMultiplier, healthMultiplier);
|
||||
for(int i = 0; i < opseq.size; i++){
|
||||
var e = opseq.get(i);
|
||||
stats.add(Stat.opposites, e.emoji() + "" + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
if(speedMultiplier != 1){
|
||||
stats.addPercent(Stat.speedMultiplier, speedMultiplier);
|
||||
}
|
||||
@Override
|
||||
public Cicon prefDatabaseIcon(){
|
||||
return Cicon.large;
|
||||
}
|
||||
|
||||
if(reloadMultiplier != 1){
|
||||
stats.addPercent(Stat.reloadMultiplier, reloadMultiplier);
|
||||
}
|
||||
|
||||
if(buildSpeedMultiplier != 1){
|
||||
stats.addPercent(Stat.buildSpeedMultiplier, buildSpeedMultiplier);
|
||||
}
|
||||
|
||||
if(damage > 0){
|
||||
stats.add(Stat.damage, damage * 60f, StatUnit.perSecond);
|
||||
}
|
||||
|
||||
for(StatusEffect e : affinities){
|
||||
stats.add(Stat.affinities, e.toString(), StatUnit.none);
|
||||
}
|
||||
|
||||
for(StatusEffect e : opposites){
|
||||
stats.add(Stat.opposites, e.toString(), StatUnit.none);
|
||||
}
|
||||
@Override
|
||||
public boolean showUnlock(){
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Runs every tick on the affected unit while time is greater than 0. */
|
||||
|
@ -6,7 +6,6 @@ import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.ctype.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.ui.*;
|
||||
import mindustry.world.meta.*;
|
||||
|
||||
public class ContentInfoDialog extends BaseDialog{
|
||||
@ -27,9 +26,9 @@ public class ContentInfoDialog extends BaseDialog{
|
||||
content.checkStats();
|
||||
|
||||
table.table(title1 -> {
|
||||
int size = 8 * 6;
|
||||
var size = content.prefDatabaseIcon();
|
||||
|
||||
title1.image(content.icon(Cicon.xlarge)).size(size).scaling(Scaling.fit);
|
||||
title1.image(content.icon(size)).size(size.size).scaling(Scaling.fit);
|
||||
title1.add("[accent]" + content.localizedName).padLeft(5);
|
||||
});
|
||||
|
||||
|
@ -44,8 +44,7 @@ public class MessageBlock extends Block{
|
||||
for(int i = 0; i < text.length(); i++){
|
||||
char c = text.charAt(i);
|
||||
if(c == '\n'){
|
||||
count ++;
|
||||
if(count <= maxNewlines){
|
||||
if(count++ <= maxNewlines){
|
||||
tile.message.append('\n');
|
||||
}
|
||||
}else{
|
||||
|
@ -376,8 +376,24 @@ public class Generators{
|
||||
});
|
||||
|
||||
ImagePacker.generate("item-icons", () -> {
|
||||
for(UnlockableContent item : Seq.<UnlockableContent>withArrays(content.items(), content.liquids())){
|
||||
for(UnlockableContent item : Seq.<UnlockableContent>withArrays(content.items(), content.liquids(), content.statusEffects())){
|
||||
if(item instanceof StatusEffect && !ImagePacker.has(item.getContentType().name() + "-" + item.name)){
|
||||
continue;
|
||||
}
|
||||
|
||||
Image base = ImagePacker.get(item.getContentType().name() + "-" + item.name);
|
||||
//tint status effect icon color
|
||||
if(item instanceof StatusEffect){
|
||||
StatusEffect stat = (StatusEffect)item;
|
||||
Image tint = base;
|
||||
base.each((x, y) -> tint.draw(x, y, tint.getColor(x, y).mul(stat.color)));
|
||||
|
||||
//outline the image
|
||||
Image container = new Image(38, 38);
|
||||
container.draw(base, 3, 3);
|
||||
base = container.outline(3, Pal.gray);
|
||||
}
|
||||
|
||||
for(Cicon icon : Cicon.scaled){
|
||||
//if(icon.size == base.width) continue;
|
||||
Image image = new Image(icon.size, icon.size);
|
||||
|
@ -106,7 +106,7 @@ public class ImagePacker{
|
||||
ObjectMap<String, String> content2id = new ObjectMap<>();
|
||||
map.each((key, val) -> content2id.put(val.split("\\|")[0], key));
|
||||
|
||||
Seq<UnlockableContent> cont = Seq.withArrays(Vars.content.blocks(), Vars.content.items(), Vars.content.liquids(), Vars.content.units());
|
||||
Seq<UnlockableContent> cont = Seq.withArrays(Vars.content.blocks(), Vars.content.items(), Vars.content.liquids(), Vars.content.units(), Vars.content.statusEffects());
|
||||
cont.removeAll(u -> u instanceof ConstructBlock || u == Blocks.air);
|
||||
|
||||
int minid = 0xF8FF;
|
||||
|